aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.tree-ssa110
-rw-r--r--boehm-gc/.cvsignore1
-rw-r--r--boehm-gc/configure.ac489
-rwxr-xr-xboehm-gc/install-sh34
-rw-r--r--boehm-gc/libtool.m43398
-rwxr-xr-xboehm-gc/mkinstalldirs81
-rw-r--r--compile136
-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
-rw-r--r--contrib/tree-ssa.doxy1113
-rwxr-xr-xdepcomp472
-rw-r--r--fastjar/configure.ac102
-rw-r--r--fastjar/shift.c166
-rw-r--r--fastjar/shift.h29
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/ChangeLog.1016352
-rw-r--r--gcc/ChangeLog.1121016
-rw-r--r--gcc/ChangeLog.tree-ssa19338
-rw-r--r--gcc/ada/5xcrtl.ads159
-rw-r--r--gcc/ada/ChangeLog.tree-ssa29
-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-direct.adb926
-rw-r--r--gcc/ada/a-direct.ads415
-rw-r--r--gcc/ada/a-dirval-mingw.adb146
-rw-r--r--gcc/ada/a-dirval-vms.adb175
-rw-r--r--gcc/ada/a-dirval.adb90
-rw-r--r--gcc/ada/a-dirval.ads47
-rw-r--r--gcc/ada/a-elchha.adb165
-rw-r--r--gcc/ada/a-elchha.ads46
-rw-r--r--gcc/ada/a-excpol-abort.adb58
-rw-r--r--gcc/ada/a-excpol-interix.adb66
-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.adb572
-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/g-eacodu-vms.adb73
-rw-r--r--gcc/ada/g-expect-vms.adb1184
-rw-r--r--gcc/ada/g-sestin.ads50
-rw-r--r--gcc/ada/g-signal.adb71
-rw-r--r--gcc/ada/g-signal.ads55
-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/gnat_ugn.texi27811
-rw-r--r--gcc/ada/gprmake.adb36
-rw-r--r--gcc/ada/i-cpp-vms.adb346
-rw-r--r--gcc/ada/i-cstrea-vms.adb255
-rw-r--r--gcc/ada/interfac-vms.ads194
-rw-r--r--gcc/ada/makegpr.adb4074
-rw-r--r--gcc/ada/makegpr.ads35
-rw-r--r--gcc/ada/makeutl.adb509
-rw-r--r--gcc/ada/makeutl.ads117
-rw-r--r--gcc/ada/mlib-tgt-aix.adb378
-rw-r--r--gcc/ada/mlib-tgt-hpux.adb356
-rw-r--r--gcc/ada/mlib-tgt-irix.adb351
-rw-r--r--gcc/ada/mlib-tgt-linux.adb353
-rw-r--r--gcc/ada/mlib-tgt-mingw.adb285
-rw-r--r--gcc/ada/mlib-tgt-solaris.adb350
-rw-r--r--gcc/ada/mlib-tgt-tru64.adb367
-rw-r--r--gcc/ada/mlib-tgt-vms-alpha.adb694
-rw-r--r--gcc/ada/mlib-tgt-vms-ia64.adb727
-rw-r--r--gcc/ada/mlib-tgt-vxworks.adb304
-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-vms_64.ads592
-rw-r--r--gcc/ada/s-crtl.ads159
-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-interr-dummy.adb307
-rw-r--r--gcc/ada/s-interr-sigaction.adb683
-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.ads647
-rw-r--r--gcc/ada/s-osinte-fsu.adb366
-rw-r--r--gcc/ada/s-osinte-hpux-dce.adb530
-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.ads528
-rw-r--r--gcc/ada/s-osinte-linux-fsu.ads599
-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-mingw.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-proinf-irix-athread.adb221
-rw-r--r--gcc/ada/s-proinf-irix-athread.ads96
-rw-r--r--gcc/ada/s-restri.adb148
-rw-r--r--gcc/ada/s-restri.ads69
-rw-r--r--gcc/ada/s-stchop-vxworks.adb234
-rw-r--r--gcc/ada/s-stchop.adb251
-rw-r--r--gcc/ada/s-stchop.ads68
-rw-r--r--gcc/ada/s-taprop-dummy.adb439
-rw-r--r--gcc/ada/s-taprop-hpux-dce.adb1050
-rw-r--r--gcc/ada/s-taprop-irix-athread.adb952
-rw-r--r--gcc/ada/s-taprop-irix.adb1133
-rw-r--r--gcc/ada/s-taprop-linux.adb1084
-rw-r--r--gcc/ada/s-taprop-lynxos.adb1184
-rw-r--r--gcc/ada/s-taprop-mingw.adb1091
-rw-r--r--gcc/ada/s-taprop-os2.adb1152
-rw-r--r--gcc/ada/s-taprop-posix.adb1203
-rw-r--r--gcc/ada/s-taprop-solaris.adb1813
-rw-r--r--gcc/ada/s-taprop-tru64.adb1130
-rw-r--r--gcc/ada/s-taprop-vms.adb1000
-rw-r--r--gcc/ada/s-taprop-vxworks.adb1137
-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-alpha.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/symbols-vms-alpha.adb774
-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-ia64.ads150
-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-vms_64.ads255
-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/xgnatugn.adb1380
-rw-r--r--gcc/alias.h31
-rw-r--r--gcc/c-gimplify.c542
-rw-r--r--gcc/cfgexpand.c451
-rw-r--r--gcc/config/alpha/alpha.c34
-rw-r--r--gcc/config/alpha/alpha.md30
-rw-r--r--gcc/config/arm/arm-cores.def92
-rw-r--r--gcc/config/arm/arm-generic.md152
-rw-r--r--gcc/config/arm/arm1026ejs.md241
-rw-r--r--gcc/config/arm/arm1136jfs.md377
-rw-r--r--gcc/config/arm/arm926ejs.md188
-rw-r--r--gcc/config/arm/vfp.md781
-rw-r--r--gcc/config/darwin7.h29
-rw-r--r--gcc/config/frv/libgcc-frv.ver55
-rw-r--r--gcc/config/frv/linux.h74
-rw-r--r--gcc/config/frv/t-linux12
-rw-r--r--gcc/config/h8300/genmova.sh163
-rw-r--r--gcc/config/h8300/mova.md841
-rw-r--r--gcc/config/h8300/t-rtems7
-rw-r--r--gcc/config/host-linux.c141
-rw-r--r--gcc/config/host-solaris.c79
-rw-r--r--gcc/config/i386/host-mingw32.c148
-rw-r--r--gcc/config/i386/i386.c81
-rw-r--r--gcc/config/i386/i386.md44
-rw-r--r--gcc/config/i386/kfreebsd-gnu.h26
-rw-r--r--gcc/config/i386/knetbsd-gnu.h (renamed from gcc/config/i386/xm-sun.h)17
-rw-r--r--gcc/config/i386/scodbx.h84
-rw-r--r--gcc/config/i386/xm-dgux.h4
-rw-r--r--gcc/config/i386/xm-sysv3.h3
-rw-r--r--gcc/config/kfreebsd-gnu.h36
-rw-r--r--gcc/config/knetbsd-gnu.h36
-rw-r--r--gcc/config/m32r/linux.h104
-rw-r--r--gcc/config/m32r/little.h34
-rw-r--r--gcc/config/m32r/t-linux42
-rw-r--r--gcc/config/m32r/xm-linux.h26
-rw-r--r--gcc/config/m32r/xm-m32r.h43
-rw-r--r--gcc/config/m68k/t-slibgcc-elf-ver3
-rw-r--r--gcc/config/memcmp.c16
-rw-r--r--gcc/config/memcpy.c12
-rw-r--r--gcc/config/memmove.c20
-rw-r--r--gcc/config/memset.c11
-rw-r--r--gcc/config/mips/3000.md78
-rw-r--r--gcc/config/mips/4130.md136
-rw-r--r--gcc/config/mips/iris5gld.h75
-rw-r--r--gcc/config/mips/irix-crti.asm33
-rw-r--r--gcc/config/mips/irix-crtn.asm27
-rw-r--r--gcc/config/mips/sb1.md504
-rw-r--r--gcc/config/mips/t-irix-gld9
-rw-r--r--gcc/config/mips/vr4120-div.S75
-rw-r--r--gcc/config/pa/t-slibgcc-elf-ver3
-rw-r--r--gcc/config/rs6000/darwin-fallback.c432
-rw-r--r--gcc/config/rs6000/darwin-fpsave.asm100
-rw-r--r--gcc/config/rs6000/darwin-ldouble.c205
-rw-r--r--gcc/config/rs6000/darwin-vecsave.asm164
-rw-r--r--gcc/config/rs6000/darwin-world.asm264
-rw-r--r--gcc/config/rs6000/libgcc-ppc64.ver7
-rw-r--r--gcc/config/rs6000/power5.md299
-rw-r--r--gcc/config/rs6000/t-rtems86
-rw-r--r--gcc/config/sh/libgcc-std.ver218
-rw-r--r--gcc/config/sh/t-1e1
-rw-r--r--gcc/config/sh/t-linux641
-rw-r--r--gcc/config/sh/t-mlib-sh11
-rw-r--r--gcc/config/sh/t-mlib-sh21
-rw-r--r--gcc/config/sh/t-mlib-sh2e1
-rw-r--r--gcc/config/sh/t-mlib-sh31
-rw-r--r--gcc/config/sh/t-mlib-sh3e1
-rw-r--r--gcc/config/sh/t-mlib-sh41
-rw-r--r--gcc/config/sh/t-mlib-sh4-nofpu1
-rw-r--r--gcc/config/sh/t-mlib-sh4-single1
-rw-r--r--gcc/config/sh/t-mlib-sh4-single-only1
-rw-r--r--gcc/config/sh/t-mlib-sh5-32media1
-rw-r--r--gcc/config/sh/t-mlib-sh5-32media-nofpu1
-rw-r--r--gcc/config/sh/t-mlib-sh5-64media1
-rw-r--r--gcc/config/sh/t-mlib-sh5-64media-nofpu1
-rw-r--r--gcc/config/sh/t-mlib-sh5-compact1
-rw-r--r--gcc/config/sh/t-mlib-sh5-compact-nofpu1
-rw-r--r--gcc/config/t-slibgcc-darwin30
-rw-r--r--gcc/config/vax/t-memfuncs3
-rw-r--r--gcc/config/x-linux4
-rw-r--r--gcc/config/x-solaris4
-rw-r--r--gcc/configure.ac3257
-rw-r--r--gcc/cp/ChangeLog.322648
-rw-r--r--gcc/cp/ChangeLog.tree-ssa566
-rw-r--r--gcc/cp/cp-gimplify.c295
-rw-r--r--gcc/ddg.c1046
-rw-r--r--gcc/ddg.h187
-rw-r--r--gcc/doc/cfg.texi615
-rw-r--r--gcc/doc/tree-ssa.texi1205
-rw-r--r--gcc/domwalk.c265
-rw-r--r--gcc/domwalk.h112
-rw-r--r--gcc/emit-rtl.h48
-rw-r--r--gcc/fixinc/tests/base/locale.h20
-rw-r--r--gcc/fixinc/tests/base/mach-o/dyld.h17
-rw-r--r--gcc/fixinc/tests/base/standards.h14
-rw-r--r--gcc/fixinc/tests/base/wchar.h15
-rw-r--r--gcc/fortran/.cvsignore1
-rw-r--r--gcc/fortran/CONTRIB33
-rw-r--r--gcc/fortran/ChangeLog3930
-rw-r--r--gcc/fortran/Make-lang.in298
-rw-r--r--gcc/fortran/NEWS7
-rw-r--r--gcc/fortran/README18
-rw-r--r--gcc/fortran/TODO56
-rw-r--r--gcc/fortran/arith.c2861
-rw-r--r--gcc/fortran/arith.h90
-rw-r--r--gcc/fortran/array.c1975
-rw-r--r--gcc/fortran/bbt.c201
-rw-r--r--gcc/fortran/check.c2037
-rw-r--r--gcc/fortran/config-lang.in22
-rw-r--r--gcc/fortran/convert.c124
-rw-r--r--gcc/fortran/data.c541
-rw-r--r--gcc/fortran/decl.c2884
-rw-r--r--gcc/fortran/dependency.c679
-rw-r--r--gcc/fortran/dependency.h30
-rw-r--r--gcc/fortran/dump-parse-tree.c1500
-rw-r--r--gcc/fortran/error.c757
-rw-r--r--gcc/fortran/expr.c1916
-rw-r--r--gcc/fortran/f95-lang.c839
-rw-r--r--gcc/fortran/gfortran.h1699
-rw-r--r--gcc/fortran/gfortran.texi739
-rw-r--r--gcc/fortran/gfortranspec.c549
-rw-r--r--gcc/fortran/interface.c1865
-rw-r--r--gcc/fortran/intrinsic.c2726
-rw-r--r--gcc/fortran/intrinsic.h329
-rw-r--r--gcc/fortran/invoke.texi662
-rw-r--r--gcc/fortran/io.c2459
-rw-r--r--gcc/fortran/iresolve.c1489
-rw-r--r--gcc/fortran/lang-specs.h35
-rw-r--r--gcc/fortran/lang.opt156
-rw-r--r--gcc/fortran/match.c3426
-rw-r--r--gcc/fortran/match.h169
-rw-r--r--gcc/fortran/matchexp.c881
-rw-r--r--gcc/fortran/mathbuiltins.def14
-rw-r--r--gcc/fortran/misc.c327
-rw-r--r--gcc/fortran/module.c3525
-rw-r--r--gcc/fortran/options.c327
-rw-r--r--gcc/fortran/parse.c2615
-rw-r--r--gcc/fortran/parse.h65
-rw-r--r--gcc/fortran/primary.c2219
-rw-r--r--gcc/fortran/resolve.c4493
-rw-r--r--gcc/fortran/scanner.c1132
-rw-r--r--gcc/fortran/simplify.c4008
-rw-r--r--gcc/fortran/st.c186
-rw-r--r--gcc/fortran/symbol.c2420
-rw-r--r--gcc/fortran/trans-array.c4165
-rw-r--r--gcc/fortran/trans-array.h117
-rw-r--r--gcc/fortran/trans-common.c848
-rw-r--r--gcc/fortran/trans-const.c377
-rw-r--r--gcc/fortran/trans-const.h61
-rw-r--r--gcc/fortran/trans-decl.c2216
-rw-r--r--gcc/fortran/trans-expr.c1925
-rw-r--r--gcc/fortran/trans-intrinsic.c3067
-rw-r--r--gcc/fortran/trans-io.c1223
-rw-r--r--gcc/fortran/trans-stmt.c3144
-rw-r--r--gcc/fortran/trans-stmt.h65
-rw-r--r--gcc/fortran/trans-types.c1499
-rw-r--r--gcc/fortran/trans-types.h143
-rw-r--r--gcc/fortran/trans.c693
-rw-r--r--gcc/fortran/trans.h559
-rw-r--r--gcc/gimple-low.c544
-rw-r--r--gcc/gimplify.c4272
-rw-r--r--gcc/java/ChangeLog.tree-ssa360
-rw-r--r--gcc/java/java-gimplify.c282
-rw-r--r--gcc/libada-mk.in34
-rw-r--r--gcc/libgcc-darwin.ver218
-rw-r--r--gcc/loop-doloop.c560
-rw-r--r--gcc/loop-invariant.c933
-rw-r--r--gcc/loop-iv.c2584
-rw-r--r--gcc/modulo-sched.c2136
-rw-r--r--gcc/opt-functions.awk76
-rw-r--r--gcc/opt-gather.awk54
-rw-r--r--gcc/optc-gen.awk144
-rw-r--r--gcc/opth-gen.awk128
-rw-r--r--gcc/passes.c2021
-rw-r--r--gcc/po/ca.po23026
-rw-r--r--gcc/reload1.c16
-rw-r--r--gcc/rtl-profile.c424
-rw-r--r--gcc/rtlhooks-def.h46
-rw-r--r--gcc/rtlhooks.c103
-rw-r--r--gcc/statistics.h34
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog.tree-ssa1204
-rw-r--r--gcc/testsuite/ada/acats/norun.lst2
-rwxr-xr-xgcc/testsuite/ada/acats/run_acats45
-rwxr-xr-xgcc/testsuite/ada/acats/run_all.sh199
-rw-r--r--gcc/testsuite/ada/acats/support/impbit.adb6
-rw-r--r--gcc/testsuite/ada/acats/support/impdefc.a153
-rw-r--r--gcc/testsuite/ada/acats/support/macro.dfs6
-rw-r--r--gcc/testsuite/g++.dg/abi/covariant2.C32
-rw-r--r--gcc/testsuite/g++.dg/abi/covariant3.C85
-rw-r--r--gcc/testsuite/g++.dg/abi/macro0.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/macro1.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/macro2.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle18-1.C23
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle18-2.C23
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle19-1.C13
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle19-2.C13
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle20-1.C19
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle20-2.C16
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle21.C13
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle22.C9
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle23.C9
-rw-r--r--gcc/testsuite/g++.dg/abi/structret1.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb42.C19
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031023-1.c66
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031023-2.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031023-3.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031023-4.c2
-rw-r--r--gcc/tree-alias-ander.c933
-rw-r--r--gcc/tree-alias-ander.h29
-rw-r--r--gcc/tree-alias-common.c1270
-rw-r--r--gcc/tree-alias-common.h123
-rw-r--r--gcc/tree-alias-type.c37
-rw-r--r--gcc/tree-alias-type.h68
-rw-r--r--gcc/tree-browser.c1045
-rw-r--r--gcc/tree-browser.def98
-rw-r--r--gcc/tree-cfg.c4899
-rw-r--r--gcc/tree-chrec.c1019
-rw-r--r--gcc/tree-chrec.h206
-rw-r--r--gcc/tree-complex.c561
-rw-r--r--gcc/tree-dfa.c1200
-rw-r--r--gcc/tree-eh.c1844
-rw-r--r--gcc/tree-flow-inline.h688
-rw-r--r--gcc/tree-flow.h634
-rw-r--r--gcc/tree-gimple.c524
-rw-r--r--gcc/tree-gimple.h128
-rw-r--r--gcc/tree-into-ssa.c1912
-rw-r--r--gcc/tree-iterator.c367
-rw-r--r--gcc/tree-iterator.h123
-rw-r--r--gcc/tree-mudflap.c1294
-rw-r--r--gcc/tree-mudflap.h37
-rw-r--r--gcc/tree-nested.c1419
-rw-r--r--gcc/tree-nomudflap.c127
-rw-r--r--gcc/tree-nrv.c218
-rw-r--r--gcc/tree-outof-ssa.c2223
-rw-r--r--gcc/tree-pass.h139
-rw-r--r--gcc/tree-phinodes.c528
-rw-r--r--gcc/tree-pretty-print.c2279
-rw-r--r--gcc/tree-profile.c188
-rw-r--r--gcc/tree-sra.c2023
-rw-r--r--gcc/tree-ssa-alias.c2158
-rw-r--r--gcc/tree-ssa-ccp.c2556
-rw-r--r--gcc/tree-ssa-copy.c257
-rw-r--r--gcc/tree-ssa-copyrename.c395
-rw-r--r--gcc/tree-ssa-dce.c934
-rw-r--r--gcc/tree-ssa-dom.c3696
-rw-r--r--gcc/tree-ssa-dse.c445
-rw-r--r--gcc/tree-ssa-forwprop.c526
-rw-r--r--gcc/tree-ssa-live.c1900
-rw-r--r--gcc/tree-ssa-live.h750
-rw-r--r--gcc/tree-ssa-loop-ch.c349
-rw-r--r--gcc/tree-ssa-loop.c143
-rw-r--r--gcc/tree-ssa-operands.c1488
-rw-r--r--gcc/tree-ssa-operands.h169
-rw-r--r--gcc/tree-ssa-phiopt.c677
-rw-r--r--gcc/tree-ssa-pre.c2066
-rw-r--r--gcc/tree-ssa.c1165
-rw-r--r--gcc/tree-ssanames.c219
-rw-r--r--gcc/tree-tailcall.c942
-rw-r--r--gcc/tree-vn.c302
-rw-r--r--gcc/unwind-dw2.h88
-rw-r--r--gcc/var-tracking.c2767
-rw-r--r--gcc/vec.c90
-rw-r--r--gcc/vec.h600
-rw-r--r--gcc/xcoff.h17
-rw-r--r--libjava/ChangeLog11
-rw-r--r--libjava/java/util/jar/JarInputStream.java1
-rw-r--r--libjava/java/util/zip/DeflaterOutputStream.java30
545 files changed, 375662 insertions, 3967 deletions
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/boehm-gc/.cvsignore b/boehm-gc/.cvsignore
new file mode 100644
index 00000000000..d89921897ae
--- /dev/null
+++ b/boehm-gc/.cvsignore
@@ -0,0 +1 @@
+autom4te.cache
diff --git a/boehm-gc/configure.ac b/boehm-gc/configure.ac
new file mode 100644
index 00000000000..a99cb901a90
--- /dev/null
+++ b/boehm-gc/configure.ac
@@ -0,0 +1,489 @@
+# Copyright (c) 1999, 2000, 2001, 2002, 2003 by Red Hat, Inc. All rights reserved.
+# Copyright 2004 Nathanael Nerode
+#
+# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+#
+# Permission is hereby granted to use or copy this program
+# for any purpose, provided the above notices are retained on all copies.
+# Permission to modify the code and to distribute modified code is granted,
+# provided the above notices are retained, and a notice that the code was
+# modified is included with the above copyright notice.
+#
+# Original author: Tom Tromey
+# Modified by Nathanael Nerode
+
+dnl Process this file with autoconf to produce configure.
+
+AC_PREREQ(2.59)
+AC_INIT(gcj_mlc.c)
+
+# 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
+# exported.
+ORIGINAL_LD_FOR_MULTILIBS=$LD
+
+AM_ENABLE_MULTILIB(, ..)
+
+AC_CANONICAL_SYSTEM
+
+# Get the 'noncanonical' system names.
+_GCC_TOPLEV_NONCANONICAL_BUILD
+_GCC_TOPLEV_NONCANONICAL_HOST
+_GCC_TOPLEV_NONCANONICAL_TARGET
+
+# This works around an automake problem.
+mkinstalldirs="`cd $ac_aux_dir && ${PWDCMD-pwd}`/mkinstalldirs"
+AC_SUBST(mkinstalldirs)
+
+AM_INIT_AUTOMAKE(gc, 6.1a1, no-define)
+
+# The autoconf 2.5x version of the no-executables hack.
+sinclude(../config/no-executables.m4)
+GCC_NO_EXECUTABLES
+
+# Yak. We must force CC and CXX to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS and CXXFLAGS ourselves.
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+AC_PROG_CXX
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AM_PROG_CC_C_O
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+
+# Newer automakes demand CCAS and CCASFLAGS.
+: ${CCAS='$(CC)'}
+: ${CCASFLAGS='$(CFLAGS)'}
+AC_SUBST(CCAS)
+AC_SUBST(CCASFLAGS)
+
+AC_CHECK_TOOL(AS, as)
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+AC_PROG_INSTALL
+
+AM_MAINTAINER_MODE
+
+. [$]{srcdir}/configure.host
+
+case [$]{gc_basedir} in
+/* | [A-Za-z]:[/\\]*) gc_flagbasedir=[$]{gc_basedir} ;;
+*) gc_flagbasedir='[$](top_builddir)/'[$]{gc_basedir} ;;
+esac
+
+gc_cflags="[$]{gc_cflags} -I"'[$](top_builddir)'"/./targ-include -I[$]{gc_flagbasedir}/libc/include"
+case "${host}" in
+ *-*-cygwin32*)
+ gc_cflags="[$]{gc_cflags} -I[$]{gc_flagbasedir}/../winsup/include"
+ ;;
+esac
+
+dnl gc_cflags="[$]{gc_cflags} -fno-builtin"
+
+GC_CFLAGS=${gc_cflags}
+AC_SUBST(GC_CFLAGS)
+
+AM_PROG_LIBTOOL
+
+dnl We use these options to decide which functions to include.
+AC_ARG_WITH(target-subdir,
+[ --with-target-subdir=SUBDIR
+ configuring with a cross compiler])
+AC_ARG_WITH(cross-host,
+[ --with-cross-host=HOST configuring with a cross compiler])
+
+AC_MSG_CHECKING([for thread model used by GCC])
+THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
+if test -z "$THREADS"; then
+ THREADS=no
+fi
+AC_MSG_RESULT([$THREADS])
+
+AC_ARG_ENABLE(parallel-mark,
+[ --enable-parallel-mark parallelize marking and free list construction],
+ [case "$THREADS" in
+ no | none | single)
+ AC_MSG_ERROR([Parallel mark requires --enable-threads=x spec])
+ ;;
+ esac]
+)
+
+AM_CPPFLAGS="-I`cd $srcdir && ${PWDCMD-pwd}`/include"
+THREADLIBS=
+case "$THREADS" in
+ no | none | single)
+ THREADS=none
+ ;;
+ posix | pthreads)
+ THREADS=posix
+ THREADLIBS=-lpthread
+ case "$host" in
+ x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux*)
+ AC_DEFINE(GC_LINUX_THREADS)
+ AC_DEFINE(_REENTRANT)
+ if test "${enable_parallel_mark}" = yes; then
+ AC_DEFINE(PARALLEL_MARK)
+ fi
+ AC_DEFINE(THREAD_LOCAL_ALLOC)
+ ;;
+ *-*-linux*)
+ AC_DEFINE(GC_LINUX_THREADS)
+ AC_DEFINE(_REENTRANT)
+ ;;
+ *-*-aix*)
+ AC_DEFINE(GC_AIX_THREADS)
+ AC_DEFINE(_REENTRANT)
+ ;;
+ *-*-hpux*)
+ AC_MSG_WARN("Only HP/UX 11 threads are supported.")
+ AC_DEFINE(GC_HPUX_THREADS)
+ AC_DEFINE(_POSIX_C_SOURCE,199506L)
+ if test "${enable_parallel_mark}" = yes; then
+ AC_DEFINE(PARALLEL_MARK)
+ fi
+ AC_DEFINE(THREAD_LOCAL_ALLOC)
+ THREADLIBS="-lpthread -lrt"
+ ;;
+ *-*-freebsd*)
+ AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.")
+ AC_DEFINE(GC_FREEBSD_THREADS)
+ AM_CPPFLAGS="$AM_CPPFLAGS -pthread"
+ THREADLIBS=-pthread
+ ;;
+ *-*-solaris*)
+ AC_DEFINE(GC_SOLARIS_THREADS)
+ AC_DEFINE(GC_SOLARIS_PTHREADS)
+ ;;
+ *-*-irix*)
+ AC_DEFINE(GC_IRIX_THREADS)
+ ;;
+ *-*-cygwin*)
+ AC_DEFINE(GC_WIN32_THREADS)
+ ;;
+ *-*-darwin*)
+ AC_DEFINE(GC_DARWIN_THREADS)
+ AC_DEFINE(THREAD_LOCAL_ALLOC)
+ if test "${enable_parallel_mark}" = yes; then
+ AC_DEFINE(PARALLEL_MARK)
+ fi
+ ;;
+ *-*-osf*)
+ AC_DEFINE(GC_OSF1_THREADS)
+ if test "${enable_parallel_mark}" = yes; then
+ AC_DEFINE(PARALLEL_MARK)
+ AC_DEFINE(THREAD_LOCAL_ALLOC)
+ # May want to enable it in other cases, too.
+ # Measurements havent yet been done.
+ fi
+ AM_CPPFLAGS="$AM_CPPFLAGS -pthread"
+ THREADLIBS="-lpthread -lrt"
+ ;;
+ esac
+ ;;
+ win32)
+ AC_DEFINE(GC_WIN32_THREADS)
+ dnl Old wine getenv may not return NULL for missing entry.
+ dnl Define EMPTY_GETENV_RESULTS here to work around the bug.
+ ;;
+ dgux386)
+ THREADS=dgux386
+AC_MSG_RESULT($THREADLIBS)
+ # Use pthread GCC switch
+ THREADLIBS=-pthread
+ if test "${enable_parallel_mark}" = yes; then
+ AC_DEFINE(PARALLEL_MARK)
+ fi
+ AC_DEFINE(THREAD_LOCAL_ALLOC)
+ AC_DEFINE(GC_DGUX386_THREADS)
+ AC_DEFINE(DGUX_THREADS)
+ # Enable _POSIX4A_DRAFT10_SOURCE with flag -pthread
+ AM_CPPFLAGS="-pthread $AM_CPPFLAGS"
+ ;;
+ aix)
+ THREADS=posix
+ THREADLIBS=-lpthread
+ AC_DEFINE(GC_AIX_THREADS)
+ AC_DEFINE(_REENTRANT)
+ ;;
+ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
+ AC_MSG_ERROR(thread package $THREADS not yet supported)
+ ;;
+ *)
+ AC_MSG_ERROR($THREADS is an unknown thread package)
+ ;;
+esac
+AC_SUBST(THREADLIBS)
+
+case "$host" in
+ powerpc-*-darwin*)
+ powerpc_darwin=true
+ ;;
+esac
+AM_CONDITIONAL(POWERPC_DARWIN,test x$powerpc_darwin = xtrue)
+
+# We never want libdl on darwin. It is a fake libdl that just ends up making
+# dyld calls anyway
+case "$host" in
+ *-*-darwin*) ;;
+ *)
+ AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
+ ;;
+esac
+
+AC_SUBST(EXTRA_TEST_LIBS)
+
+target_all=libgcjgc.la
+AC_SUBST(target_all)
+AC_SUBST(target_noncanonical)
+
+dnl If the target is an eCos system, use the appropriate eCos
+dnl I/O routines.
+dnl FIXME: this should not be a local option but a global target
+dnl system; at present there is no eCos target.
+TARGET_ECOS="no"
+AC_ARG_WITH(ecos,
+[ --with-ecos enable runtime eCos target support],
+TARGET_ECOS="$with_ecos"
+)
+
+addobjs=
+addlibs=
+addincludes=
+addtests=
+case "$TARGET_ECOS" in
+ no)
+ ;;
+ *)
+ AC_DEFINE(ECOS)
+ AM_CPPFLAGS="${AM_CPPFLAGS} -I${TARGET_ECOS}/include"
+ addobjs="$addobjs ecos.lo"
+ ;;
+esac
+
+if test "${enable_cplusplus}" = yes; then
+ addincludes="$addincludes include/gc_cpp.h include/gc_allocator.h"
+ addtests="$addtests test_cpp"
+fi
+
+AM_CONDITIONAL(CPLUSPLUS, test "${enable_cplusplus}" = yes)
+
+AC_SUBST(CXX)
+
+AC_SUBST(AM_CPPFLAGS)
+
+# Configuration of shared libraries
+#
+AC_MSG_CHECKING(whether to build shared libraries)
+AC_ENABLE_SHARED
+
+case "$host" in
+ alpha-*-openbsd*)
+ enable_shared=no
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ ;;
+esac
+
+# Configuration of machine-dependent code
+#
+# We don't set NO_EXECUTE_PERMISSION by default because gcj (and
+# anything else that creates trampolines in gc-allocated memory)
+# always needs exec permission. The exceptions to this are IA-64 and
+# some variations of Power PC, where trampolines don't contain
+# executable code.
+#
+AC_MSG_CHECKING(which machine-dependent code should be used)
+machdep=
+case "$host" in
+ alpha*-*-openbsd*)
+ machdep="alpha_mach_dep.lo"
+ if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
+ AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled)
+ fi
+ ;;
+ alpha*-*-linux*)
+ machdep="alpha_mach_dep.lo"
+ ;;
+ i?86-*-solaris2.[[89]] | i?86-*-solaris2.1?)
+ AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED)
+ ;;
+ mipstx39-*-elf*)
+ machdep="mips_ultrix_mach_dep.lo"
+ AC_DEFINE(STACKBASE, __stackbase)
+ AC_DEFINE(DATASTART_IS_ETEXT)
+ ;;
+ mips-dec-ultrix*)
+ machdep="mips_ultrix_mach-dep.lo"
+ ;;
+ mips-nec-sysv*|mips-unknown-sysv*)
+ ;;
+ mips*-*-linux*)
+ ;;
+ mips-*-*)
+ machdep="mips_sgi_mach_dep.lo"
+ ;;
+ sparc-*-netbsd*)
+ machdep="sparc_netbsd_mach_dep.lo"
+ ;;
+ sparc-sun-solaris2.3)
+ machdep="sparc_mach_dep.lo"
+ AC_DEFINE(SUNOS53_SHARED_LIB)
+ ;;
+ sparc-sun-solaris2.*)
+ machdep="sparc_mach_dep.lo"
+ ;;
+ ia64-*-*)
+ AC_DEFINE(NO_EXECUTE_PERMISSION)
+ machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
+ ;;
+esac
+if test x"$machdep" = x; then
+AC_MSG_RESULT($machdep)
+ machdep="mach_dep.lo"
+fi
+addobjs="$addobjs $machdep"
+AC_SUBST(addobjs)
+AC_SUBST(addincludes)
+AC_SUBST(addlibs)
+AC_SUBST(addtests)
+
+AC_PROG_LIBTOOL
+
+#
+# Check for AViiON Machines running DGUX
+#
+AC_MSG_CHECKING(if host is AViiON running DGUX)
+ac_is_dgux=no
+AC_CHECK_HEADER(sys/dg_sys_info.h,
+[ac_is_dgux=yes;])
+
+AC_MSG_RESULT($ac_is_dgux)
+ ## :GOTCHA: we do not check anything but sys/dg_sys_info.h
+if test $ac_is_dgux = yes; then
+ if test "$enable_full_debug" = "yes"; then
+ CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+ CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+ else
+ CFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+ CXXFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+ fi
+ AC_SUBST(CFLAGS)
+ AC_SUBST(CXXFLAGS)
+fi
+
+dnl We use these options to decide which functions to include.
+AC_ARG_WITH(target-subdir,
+[ --with-target-subdir=SUBDIR
+ configuring with a cross compiler])
+AC_ARG_WITH(cross-host,
+[ --with-cross-host=HOST configuring with a cross compiler])
+
+dnl As of 4.13a2, the collector will not properly work on Solaris when
+dnl built with gcc and -O. So we remove -O in the appropriate case.
+dnl
+AC_MSG_CHECKING(whether Solaris gcc optimization fix is necessary)
+case "$host" in
+ sparc-sun-solaris2*|*aix*)
+ if test "$GCC" = yes; then
+ AC_MSG_RESULT(yes)
+ new_CFLAGS=
+ for i in $CFLAGS; do
+ case "$i" in
+ -O*)
+ ;;
+ *)
+ new_CFLAGS="$new_CFLAGS $i"
+ ;;
+ esac
+ done
+ CFLAGS="$new_CFLAGS"
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ *) AC_MSG_RESULT(no) ;;
+esac
+
+dnl We need to override the top-level CFLAGS. This is how we do it.
+MY_CFLAGS="$CFLAGS"
+AC_SUBST(MY_CFLAGS)
+
+dnl Include defines that have become de facto standard.
+dnl ALL_INTERIOR_POINTERS can be overridden in startup code.
+AC_DEFINE(SILENT)
+AC_DEFINE(NO_SIGNALS)
+AC_DEFINE(ALL_INTERIOR_POINTERS)
+
+dnl By default, make the library as general as possible.
+AC_DEFINE(JAVA_FINALIZATION)
+AC_DEFINE(GC_GCJ_SUPPORT)
+AC_DEFINE(ATOMIC_UNCOLLECTABLE)
+
+dnl This is something of a hack. When cross-compiling we turn off
+dnl some functionality. These is only correct when targetting an
+dnl embedded system. FIXME.
+if test -n "${with_cross_host}"; then
+ AC_DEFINE(NO_SIGSET)
+ AC_DEFINE(NO_DEBUGGING)
+fi
+
+AC_ARG_ENABLE(full-debug,
+[ --enable-full-debug include full support for pointer backtracing etc.],
+[ if test "$enable_full_debug" = "yes"; then
+ AC_MSG_WARN("Must define GC_DEBUG and use debug alloc. in clients.")
+ AC_DEFINE(KEEP_BACK_PTRS)
+ AC_DEFINE(DBG_HDRS_ALL)
+ case $host in
+ ia64-*-linux* )
+ AC_DEFINE(MAKE_BACK_GRAPH)
+ ;;
+ x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
+ AC_DEFINE(MAKE_BACK_GRAPH)
+ AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
+ AC_DEFINE(SAVE_CALL_COUNT, 8)
+ ;;
+ i[3456]86-*-dgux*)
+ AC_DEFINE(MAKE_BACK_GRAPH)
+ ;;
+ esac ]
+ fi)
+
+if test -n "$with_cross_host" &&
+ test x"$with_cross_host" != x"no"; then
+ 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`
+case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+esac
+AC_SUBST(toolexecdir)
+AC_SUBST(toolexeclibdir)
+
+if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+else
+ multilib_arg=
+fi
+
+AC_CONFIG_COMMANDS(boehm-cflags, [
+dnl Put all the -I and -D options in a file.
+echo "$AM_CPPFLAGS $DEFS" > boehm-cflags], [
+DEFS="$DEFS"
+AM_CPPFLAGS="$AM_CPPFLAGS"])
+AC_CONFIG_FILES(Makefile include/Makefile)
+AC_OUTPUT
diff --git a/boehm-gc/install-sh b/boehm-gc/install-sh
index 398a88e1421..e9de23842dc 100755
--- a/boehm-gc/install-sh
+++ b/boehm-gc/install-sh
@@ -109,7 +109,7 @@ then
echo "install: no input file specified"
exit 1
else
- :
+ true
fi
if [ x"$dir_arg" != x ]; then
@@ -120,7 +120,7 @@ if [ x"$dir_arg" != x ]; then
instcmd=:
chmodcmd=""
else
- instcmd=$mkdirprog
+ instcmd=mkdir
fi
else
@@ -130,7 +130,7 @@ else
if [ -f $src -o -d $src ]
then
- :
+ true
else
echo "install: $src does not exist"
exit 1
@@ -141,7 +141,7 @@ else
echo "install: no destination specified"
exit 1
else
- :
+ true
fi
# If destination is a directory, append the input filename; if your system
@@ -151,7 +151,7 @@ else
then
dst="$dst"/`basename $src`
else
- :
+ true
fi
fi
@@ -163,8 +163,8 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
-defaultIFS='
- '
+defaultIFS='
+'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
@@ -183,7 +183,7 @@ while [ $# -ne 0 ] ; do
then
$mkdirprog "${pathcomp}"
else
- :
+ true
fi
pathcomp="${pathcomp}/"
@@ -194,10 +194,10 @@ if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
@@ -216,7 +216,7 @@ else
then
dstfile=`basename $dst`
else
- :
+ true
fi
# Make a temp file name in the proper directory.
@@ -235,10 +235,10 @@ else
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
diff --git a/boehm-gc/libtool.m4 b/boehm-gc/libtool.m4
index 066bf6a5ce6..c857149a9d6 100644
--- a/boehm-gc/libtool.m4
+++ b/boehm-gc/libtool.m4
@@ -1,6 +1,5 @@
-# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
-## Copyright 1996, 1997, 1998, 1999, 2000, 2001
-## Free Software Foundation, Inc.
+## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*-
+## Copyright (C) 1996-1999 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
@@ -22,68 +21,85 @@
## 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],
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| 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/ltmain.sh"
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
AC_SUBST(LIBTOOL)dnl
-# Prevent multiple expansion
-define([AC_PROG_LIBTOOL], [])
+# 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_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_RANLIB])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
-AC_REQUIRE([AC_OBJEXT])dnl
-AC_REQUIRE([AC_EXEEXT])dnl
dnl
-_LT_AC_PROG_ECHO_BACKSLASH
-# 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
- ;;
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
esac
-AC_CHECK_TOOL(RANLIB, ranlib, :)
-AC_CHECK_TOOL(STRIP, strip, :)
-
-ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+# Check for any special flags to pass to ltconfig.
+#
+# the following will cause an existing older ltconfig to fail, so
+# we ignore this at the expense of the cache file... Checking this
+# will just take longer ... bummer!
+#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 "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_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],
-enable_win32_dll=yes, enable_win32_dll=no)
-
+[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 && enable_libtool_lock=yes
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
-case $host in
+case "$lt_target" 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
+ case "`/usr/bin/file conftest.o`" in
*32-bit*)
LD="${LD-ld} -32"
;;
@@ -103,10 +119,7 @@ case $host in
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])
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
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"
@@ -114,2889 +127,33 @@ case $host in
;;
ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
-[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+[*-*-cygwin* | *-*-mingw*)
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
-
-_LT_AC_LTCONFIG_HACK
-
])
-
-# AC_LIBTOOL_HEADER_ASSERT
-# ------------------------
-AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT],
-[AC_CACHE_CHECK([whether $CC supports assert without backlinking],
- [lt_cv_func_assert_works],
- [case $host in
- *-*-solaris*)
- if test "$GCC" = yes && test "$with_gnu_ld" != yes; then
- case `$CC --version 2>/dev/null` in
- [[12]].*) lt_cv_func_assert_works=no ;;
- *) lt_cv_func_assert_works=yes ;;
- esac
- fi
- ;;
- esac])
-
-if test "x$lt_cv_func_assert_works" = xyes; then
- AC_CHECK_HEADERS(assert.h)
-fi
-])# AC_LIBTOOL_HEADER_ASSERT
-
-# _LT_AC_CHECK_DLFCN
-# --------------------
-AC_DEFUN([_LT_AC_CHECK_DLFCN],
-[AC_CHECK_HEADERS(dlfcn.h)
-])# _LT_AC_CHECK_DLFCN
-
-# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-# ---------------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
-[AC_REQUIRE([AC_CANONICAL_HOST])
-AC_REQUIRE([AC_PROG_NM])
-AC_REQUIRE([AC_OBJEXT])
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output])
-AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl
-
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[[BCDEGRST]]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
-
-# Transform the above into a raw symbol and a C symbol.
-symxfrm='\1 \2\3 \3'
-
-# Transform an extracted symbol line into a proper C declaration
-lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[[BCDT]]'
- ;;
-cygwin* | mingw* | pw32*)
- symcode='[[ABCDGISTW]]'
- ;;
-hpux*) # Its linker distinguishes data from code symbols
- lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- ;;
-irix*)
- symcode='[[BCDEGRST]]'
- ;;
-solaris* | sysv5*)
- symcode='[[BDT]]'
- ;;
-sysv4)
- symcode='[[DFNSTU]]'
- ;;
-esac
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $host_os in
-mingw*)
- opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
- symcode='[[ABCDGISTW]]'
-fi
-
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Write the raw and C identifiers.
-lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
-
- # Check to see that the pipe works correctly.
- pipe_works=no
- rm -f conftest*
- cat > conftest.$ac_ext <<EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-EOF
-
- if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if egrep ' nm_test_var$' "$nlist" >/dev/null; then
- if egrep ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
- # Now generate the symbol file.
- eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
-
- cat <<EOF >> conftest.$ac_ext
-#if defined (__STDC__) && __STDC__
-# define lt_ptr void *
-#else
-# define lt_ptr char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr address;
-}
-lt_preloaded_symbols[[]] =
-{
-EOF
- sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
- cat <<\EOF >> conftest.$ac_ext
- {0, (lt_ptr) 0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- save_LIBS="$LIBS"
- save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$no_builtin_flag"
- if AC_TRY_EVAL(ac_link) && test -s conftest; then
- pipe_works=yes
- fi
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&AC_FD_CC
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&AC_FD_CC
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC
- fi
- else
- echo "$progname: failed program was:" >&AC_FD_CC
- cat conftest.$ac_ext >&5
- fi
- rm -f conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-])
-global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- global_symbol_to_cdecl=
- global_symbol_to_c_name_address=
-else
- global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
- global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
-fi
-if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
-then
- AC_MSG_RESULT(failed)
-else
- AC_MSG_RESULT(ok)
-fi
-]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-
-# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
-# ---------------------------------
-AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR],
-[# Find the correct PATH separator. Usually this is `:', but
-# DJGPP uses `;' like DOS.
-if test "X${PATH_SEPARATOR+set}" != Xset; then
- UNAME=${UNAME-`uname 2>/dev/null`}
- case X$UNAME in
- *-DOS) lt_cv_sys_path_separator=';' ;;
- *) lt_cv_sys_path_separator=':' ;;
- esac
- PATH_SEPARATOR=$lt_cv_sys_path_separator
-fi
-])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
-
-# _LT_AC_PROG_ECHO_BACKSLASH
-# --------------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
-AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
-[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
- [AC_DIVERT_PUSH(NOTICE)])
-_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
-
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
- ;;
-esac
-
-echo=${ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X[$]1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
- # Yippee, $echo works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-$*
-EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
-
-if test -z "$ECHO"; then
-if test "X${echo_test_string+set}" != Xset; then
-# find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string="`eval $cmd`") 2>/dev/null &&
- echo_test_string="`eval $cmd`" &&
- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
- then
- break
- fi
- done
-fi
-
-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
-else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$dir/echo"
- break
- fi
- done
- IFS="$save_ifs"
-
- if test "X$echo" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- echo='print -r'
- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
- else
- # Try using printf.
- echo='printf %s\n'
- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- echo="$CONFIG_SHELL [$]0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$CONFIG_SHELL [$]0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "[$]0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
- else
- # Oops. We lost completely, so just stick with echo.
- echo=echo
- fi
- fi
- fi
- fi
-fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-ECHO=$echo
-if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
- ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
-
-AC_SUBST(ECHO)
-AC_DIVERT_POP
-])# _LT_AC_PROG_ECHO_BACKSLASH
-
-# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
-# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ------------------------------------------------------------------
-AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
-[if test "$cross_compiling" = yes; then :
- [$4]
-else
- AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-[#line __oline__ "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
-
- exit (status);
-}]
-EOF
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) $1 ;;
- x$lt_dlneed_uscore) $2 ;;
- x$lt_unknown|x*) $3 ;;
- esac
- else :
- # compilation failed
- $3
- fi
-fi
-rm -fr conftest*
-])# _LT_AC_TRY_DLOPEN_SELF
-
-# AC_LIBTOOL_DLOPEN_SELF
-# -------------------
-AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
-[if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- cygwin* | mingw* | pw32*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- *)
- AC_CHECK_FUNC([shl_load],
- [lt_cv_dlopen="shl_load"],
- [AC_CHECK_LIB([dld], [shl_load],
- [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
- [AC_CHECK_FUNC([dlopen],
- [lt_cv_dlopen="dlopen"],
- [AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
- [AC_CHECK_LIB([svld], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
- [AC_CHECK_LIB([dld], [dld_link],
- [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
- ])
- ])
- ])
- ])
- ])
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- AC_CACHE_CHECK([whether a program can dlopen itself],
- lt_cv_dlopen_self, [dnl
- _LT_AC_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
- lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
- ])
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- LDFLAGS="$LDFLAGS $link_static_flag"
- AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
- lt_cv_dlopen_self_static, [dnl
- _LT_AC_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
- lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
- ])
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-])# AC_LIBTOOL_DLOPEN_SELF
-
-AC_DEFUN([_LT_AC_LTCONFIG_HACK],
-[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e s/^X//'
-sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Constants:
-rm="rm -f"
-
-# Global variables:
-default_ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except M$VC,
-# which needs '.lib').
-libext=a
-ltmain="$ac_aux_dir/ltmain.sh"
-ofile="$default_ofile"
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-need_locks="$enable_libtool_lock"
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-test -z "$AS" && AS=as
-test -z "$CC" && CC=cc
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-test -z "$LD" && LD=ld
-test -z "$LN_S" && LN_S="ln -s"
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-test -z "$NM" && NM=nm
-test -z "$OBJDUMP" && OBJDUMP=objdump
-test -z "$RANLIB" && RANLIB=:
-test -z "$STRIP" && STRIP=:
-test -z "$ac_objext" && ac_objext=o
-
-if test x"$host" != x"$build"; then
- ac_tool_prefix=${host_alias}-
-else
- ac_tool_prefix=
-fi
-
-# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
-case $host_os in
-linux-gnu*) ;;
-linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
esac
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
- ;;
- *)
- old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-# Allow CC to be a program name with arguments.
-set dummy $CC
-compiler="[$]2"
-
-## FIXME: this should be a separate macro
-##
-AC_MSG_CHECKING([for objdir])
-rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- objdir=_libs
-fi
-rmdir .libs 2>/dev/null
-AC_MSG_RESULT($objdir)
-##
-## END FIXME
-
-
-## FIXME: this should be a separate macro
-##
-AC_ARG_WITH(pic,
-[ --with-pic try to use only PIC/non-PIC objects [default=use both]],
-pic_mode="$withval", pic_mode=default)
-test -z "$pic_mode" && pic_mode=default
-
-# We assume here that the value for lt_cv_prog_cc_pic will not be cached
-# in isolation, and that seeing it set (from the cache) indicates that
-# the associated values are set (in the cache) correctly too.
-AC_MSG_CHECKING([for $compiler option to produce PIC])
-AC_CACHE_VAL(lt_cv_prog_cc_pic,
-[ lt_cv_prog_cc_pic=
- lt_cv_prog_cc_shlib=
- lt_cv_prog_cc_wl=
- lt_cv_prog_cc_static=
- lt_cv_prog_cc_no_builtin=
- lt_cv_prog_cc_can_build_shared=$can_build_shared
-
- if test "$GCC" = yes; then
- lt_cv_prog_cc_wl='-Wl,'
- lt_cv_prog_cc_static='-static'
-
- case $host_os in
- aix*)
- # Below there is a dirty hack to force normal static linking with -ldl
- # The problem is because libdl dynamically linked with both libc and
- # libC (AIX C++ library), which obviously doesn't included in libraries
- # list by gcc. This cause undefined symbols with -static flags.
- # This hack allows C programs to be linked with "-static -ldl", but
- # not sure about C++ programs.
- lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
- ;;
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
- ;;
- beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_cv_prog_cc_pic='-fno-common'
- ;;
- cygwin* | mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_cv_prog_cc_pic='-DDLL_EXPORT'
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_cv_prog_cc_pic=-Kconform_pic
- fi
- ;;
- *)
- lt_cv_prog_cc_pic='-fPIC'
- ;;
- esac
- else
- # PORTME Check for PIC flags for the system compiler.
- case $host_os in
- aix3* | aix4* | aix5*)
- lt_cv_prog_cc_wl='-Wl,'
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_cv_prog_cc_static='-Bstatic'
- else
- lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
-
- hpux9* | hpux10* | hpux11*)
- # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
- lt_cv_prog_cc_wl='-Wl,'
- lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
- lt_cv_prog_cc_pic='+Z'
- ;;
-
- irix5* | irix6*)
- lt_cv_prog_cc_wl='-Wl,'
- lt_cv_prog_cc_static='-non_shared'
- # PIC (with -KPIC) is the default.
- ;;
-
- cygwin* | mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_cv_prog_cc_pic='-DDLL_EXPORT'
- ;;
-
- newsos6)
- lt_cv_prog_cc_pic='-KPIC'
- lt_cv_prog_cc_static='-Bstatic'
- ;;
-
- osf3* | osf4* | osf5*)
- # All OSF/1 code is PIC.
- lt_cv_prog_cc_wl='-Wl,'
- lt_cv_prog_cc_static='-non_shared'
- ;;
-
- sco3.2v5*)
- lt_cv_prog_cc_pic='-Kpic'
- lt_cv_prog_cc_static='-dn'
- lt_cv_prog_cc_shlib='-belf'
- ;;
-
- solaris*)
- lt_cv_prog_cc_pic='-KPIC'
- lt_cv_prog_cc_static='-Bstatic'
- lt_cv_prog_cc_wl='-Wl,'
- ;;
-
- sunos4*)
- lt_cv_prog_cc_pic='-PIC'
- lt_cv_prog_cc_static='-Bstatic'
- lt_cv_prog_cc_wl='-Qoption ld '
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- lt_cv_prog_cc_pic='-KPIC'
- lt_cv_prog_cc_static='-Bstatic'
- if test "x$host_vendor" = xsni; then
- lt_cv_prog_cc_wl='-LD'
- else
- lt_cv_prog_cc_wl='-Wl,'
- fi
- ;;
-
- uts4*)
- lt_cv_prog_cc_pic='-pic'
- lt_cv_prog_cc_static='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_cv_prog_cc_pic='-Kconform_pic'
- lt_cv_prog_cc_static='-Bstatic'
- fi
- ;;
-
- *)
- lt_cv_prog_cc_can_build_shared=no
- ;;
- esac
- fi
-])
-if test -z "$lt_cv_prog_cc_pic"; then
- AC_MSG_RESULT([none])
-else
- AC_MSG_RESULT([$lt_cv_prog_cc_pic])
-
- # Check to make sure the pic_flag actually works.
- AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works])
- AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
- AC_TRY_COMPILE([], [], [dnl
- case $host_os in
- hpux9* | hpux10* | hpux11*)
- # On HP-UX, both CC and GCC only warn that PIC is supported... then
- # they create non-PIC objects. So, if there were any warnings, we
- # assume that PIC is not supported.
- if test -s conftest.err; then
- lt_cv_prog_cc_pic_works=no
- else
- lt_cv_prog_cc_pic_works=yes
- fi
- ;;
- *)
- lt_cv_prog_cc_pic_works=yes
- ;;
- esac
- ], [dnl
- lt_cv_prog_cc_pic_works=no
- ])
- CFLAGS="$save_CFLAGS"
- ])
-
- if test "X$lt_cv_prog_cc_pic_works" = Xno; then
- lt_cv_prog_cc_pic=
- lt_cv_prog_cc_can_build_shared=no
- else
- lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
- fi
-
- AC_MSG_RESULT([$lt_cv_prog_cc_pic_works])
-fi
-##
-## END FIXME
-
-# Check for any special shared library compilation flags.
-if test -n "$lt_cv_prog_cc_shlib"; then
- AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries])
- if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then :
- else
- AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure])
- lt_cv_prog_cc_can_build_shared=no
- fi
-fi
-
-## FIXME: this should be a separate macro
-##
-AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works])
-AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl
- lt_cv_prog_cc_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
- AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes])
- LDFLAGS="$save_LDFLAGS"
])
-# Belt *and* braces to stop my trousers falling down:
-test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
-AC_MSG_RESULT([$lt_cv_prog_cc_static_works])
-
-pic_flag="$lt_cv_prog_cc_pic"
-special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
-wl="$lt_cv_prog_cc_wl"
-link_static_flag="$lt_cv_prog_cc_static"
-no_builtin_flag="$lt_cv_prog_cc_no_builtin"
-can_build_shared="$lt_cv_prog_cc_can_build_shared"
-##
-## END FIXME
-
-
-## FIXME: this should be a separate macro
-##
-# Check to see if options -o and -c are simultaneously supported by compiler
-AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext])
-AC_CACHE_VAL([lt_cv_compiler_c_o], [
-$rm -r conftest 2>/dev/null
-mkdir conftest
-cd conftest
-echo "int some_variable = 0;" > conftest.$ac_ext
-mkdir out
-# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
-# that will create temporary files in the current directory regardless of
-# the output directory. Thus, making CWD read-only will cause this test
-# to fail, enabling locking or at least warning the user not to do parallel
-# builds.
-chmod -w .
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
-compiler_c_o=no
-if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s out/conftest.err; then
- lt_cv_compiler_c_o=no
- else
- lt_cv_compiler_c_o=yes
- fi
-else
- # Append any errors to the config.log.
- cat out/conftest.err 1>&AC_FD_CC
- lt_cv_compiler_c_o=no
-fi
-CFLAGS="$save_CFLAGS"
-chmod u+w .
-$rm conftest* out/*
-rmdir out
-cd ..
-rmdir conftest
-$rm -r conftest 2>/dev/null
-])
-compiler_c_o=$lt_cv_compiler_c_o
-AC_MSG_RESULT([$compiler_c_o])
-
-if test x"$compiler_c_o" = x"yes"; then
- # Check to see if we can write to a .lo
- AC_MSG_CHECKING([if $compiler supports -c -o file.lo])
- AC_CACHE_VAL([lt_cv_compiler_o_lo], [
- lt_cv_compiler_o_lo=no
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -c -o conftest.lo"
- save_objext="$ac_objext"
- ac_objext=lo
- AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- lt_cv_compiler_o_lo=no
- else
- lt_cv_compiler_o_lo=yes
- fi
- ])
- ac_objext="$save_objext"
- CFLAGS="$save_CFLAGS"
- ])
- compiler_o_lo=$lt_cv_compiler_o_lo
- AC_MSG_RESULT([$compiler_o_lo])
-else
- compiler_o_lo=no
-fi
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-# Check to see if we can do hard links to lock some files if needed
-hard_links="nottested"
-if test "$compiler_c_o" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- AC_MSG_CHECKING([if we can lock with hard links])
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- AC_MSG_RESULT([$hard_links])
- if test "$hard_links" = no; then
- AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe])
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-if test "$GCC" = yes; then
- # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
- AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions])
- echo "int some_variable = 0;" > conftest.$ac_ext
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
- compiler_rtti_exceptions=no
- AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- compiler_rtti_exceptions=no
- else
- compiler_rtti_exceptions=yes
- fi
- ])
- CFLAGS="$save_CFLAGS"
- AC_MSG_RESULT([$compiler_rtti_exceptions])
-
- if test "$compiler_rtti_exceptions" = "yes"; then
- no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
- else
- no_builtin_flag=' -fno-builtin'
- fi
-fi
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-# See if the linker supports building shared libraries.
-AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries])
-
-allow_undefined_flag=
-no_undefined_flag=
-need_lib_prefix=unknown
-need_version=unknown
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-archive_cmds=
-archive_expsym_cmds=
-old_archive_from_new_cmds=
-old_archive_from_expsyms_cmds=
-export_dynamic_flag_spec=
-whole_archive_flag_spec=
-thread_safe_flag_spec=
-hardcode_into_libs=no
-hardcode_libdir_flag_spec=
-hardcode_libdir_separator=
-hardcode_direct=no
-hardcode_minus_L=no
-hardcode_shlibpath_var=unsupported
-runpath_var=
-link_all_deplibs=unknown
-always_export_symbols=no
-export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
-# include_expsyms should be a list of space-separated symbols to be *always*
-# included in the symbol list
-include_expsyms=
-# exclude_expsyms can be an egrep regular expression of symbols to exclude
-# it will be wrapped by ` (' and `)$', so one must not match beginning or
-# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
-# as well as any symbol that contains `d'.
-exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
-# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
-# platforms (ab)use it in PIC code, but their linkers get confused if
-# the symbol is explicitly referenced. Since portable code cannot
-# rely on this symbol name, it's probably fine to never include it in
-# preloaded symbol tables.
-extract_expsyms_cmds=
-
-case $host_os in
-cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
-openbsd*)
- with_gnu_ld=no
- ;;
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix3* | aix4* | aix5*)
- # On AIX, the GNU linker is very broken
- # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
- ld_shlibs=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- ;;
-
- amigaos*)
- archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can use
- # them.
- ld_shlibs=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- allow_undefined_flag=unsupported
- always_export_symbols=yes
-
- extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
- sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
- test -f $output_objdir/impgen.exe || (cd $output_objdir && \
- if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
- else $CC -o impgen impgen.c ; fi)~
- $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
-
- old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
-
- # cygwin and mingw dlls have different entry points and sets of symbols
- # to exclude.
- # FIXME: what about values for MSVC?
- dll_entry=__cygwin_dll_entry@12
- dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
- case $host_os in
- mingw*)
- # mingw values
- dll_entry=_DllMainCRTStartup@12
- dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
- ;;
- esac
-
- # mingw and cygwin differ, and it's simplest to just exclude the union
- # of the two symbol sets.
- dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
-
- # recent cygwin and mingw systems supply a stub DllMain which the user
- # can override, but on older systems we have to supply one (in ltdll.c)
- if test "x$lt_cv_need_dllmain" = "xyes"; then
- ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
- ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
- test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
- else
- ltdll_obj=
- ltdll_cmds=
- fi
-
- # Extract the symbol export list from an `--export-all' def file,
- # then regenerate the def file from the symbol export list, so that
- # the compiled dll only exports the symbol export list.
- # Be careful not to strip the DATA tag left be newer dlltools.
- export_symbols_cmds="$ltdll_cmds"'
- $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
- sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
-
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is.
- # If DATA tags from a recent dlltool are present, honour them!
- archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname-def;
- else
- echo EXPORTS > $output_objdir/$soname-def;
- _lt_hint=1;
- cat $export_symbols | while read symbol; do
- set dummy \$symbol;
- case \[$]# in
- 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
- *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
- esac;
- _lt_hint=`expr 1 + \$_lt_hint`;
- done;
- fi~
- '"$ltdll_cmds"'
- $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
- $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
- $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
- $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
- $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*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris* | sysv5*)
- if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- sunos4*)
- archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- *)
- if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs" = yes; then
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- case $host_os in
- cygwin* | mingw* | pw32*)
- # dlltool doesn't understand --whole-archive et. al.
- whole_archive_flag_spec=
- ;;
- *)
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
- ;;
- esac
- fi
-else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag=unsupported
- always_export_symbols=yes
- archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$link_static_flag"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
-
- aix4* | aix5*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- hardcode_direct=yes
- archive_cmds=''
- hardcode_libdir_separator=':'
- if test "$GCC" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- hardcode_direct=yes
- else
- # We have old collect2
- hardcode_direct=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- esac
-
- shared_flag='-shared'
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- shared_flag='${wl}-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall can do strange things, so it is better to
- # generate a list of symbols to export.
- always_export_symbols=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='-berok'
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
- archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
- else
- hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='${wl}-berok'
- # This is a bit strange, but is similar to how AIX traditionally builds
- # it's shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_from_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- ;;
-
- darwin* | rhapsody*)
- case "$host_os" in
- rhapsody* | darwin1.[[012]])
- allow_undefined_flag='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- allow_undefined_flag='-flat_namespace -undefined suppress'
- ;;
- esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
- archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
- # We need to add '_' to the symbols in $export_symbols first
- #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- whole_archive_flag_spec='-all_load $convenience'
- ;;
-
- freebsd1*)
- ld_shlibs=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- hpux9* | hpux10* | hpux11*)
- case $host_os in
- hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
- *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
- esac
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- hardcode_minus_L=yes # Not in the search PATH, but as the default
- # location of the library.
- export_dynamic_flag_spec='${wl}-E'
- ;;
-
- irix5* | irix6*)
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- link_all_deplibs=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- newsos6)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_shlibpath_var=no
- ;;
-
- openbsd*)
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- else
- case "$host_os" in
- openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
-
- #Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
-
- sco3.2v5*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- export_dynamic_flag_spec='${wl}-Bexport'
- ;;
-
- solaris*)
- # gcc --version < 3.0 without binutils cannot create self contained
- # shared libraries reliably, requiring libgcc.a to resolve some of
- # the object symbols generated in some cases. Libraries that use
- # assert need libgcc.a to resolve __eprintf, for example. Linking
- # a copy of libgcc.a into every shared library to guarantee resolving
- # such symbols causes other problems: According to Tim Van Holder
- # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
- # (to the application) exception stack for one thing.
- no_undefined_flag=' -z defs'
- if test "$GCC" = yes; then
- case `$CC --version 2>/dev/null` in
- [[12]].*)
- cat <<EOF 1>&2
-
-*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
-*** create self contained shared libraries on Solaris systems, without
-*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
-*** -no-undefined support, which will at least allow you to build shared
-*** libraries. However, you may find that when you link such libraries
-*** into an application without using GCC, you have to manually add
-*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
-*** upgrade to a newer version of GCC. Another option is to rebuild your
-*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
-
-EOF
- no_undefined_flag=
- ;;
- esac
- fi
- # $CC -shared without GNU ld will not create a library from C++
- # object files and a static libstdc++, better avoid it by now
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_shlibpath_var=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *) # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
- esac
- link_all_deplibs=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- sysv4)
- if test "x$host_vendor" = xsno; then
- archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- else
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- fi
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4.3*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='-Bexport'
- ;;
-
- sysv5*)
- no_undefined_flag=' -z text'
- # $CC -shared without GNU ld will not create a library from C++
- # object files and a static libstdc++, better avoid it by now
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- hardcode_libdir_flag_spec=
- hardcode_shlibpath_var=no
- runpath_var='LD_RUN_PATH'
- ;;
-
- uts4*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- dgux*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs=yes
- fi
- ;;
-
- sysv4.2uw2*)
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=no
- hardcode_shlibpath_var=no
- hardcode_runpath_var=yes
- runpath_var=LD_RUN_PATH
- ;;
-
- sysv5uw7* | unixware7*)
- no_undefined_flag='${wl}-z ${wl}text'
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- *)
- ld_shlibs=no
- ;;
- esac
-fi
-AC_MSG_RESULT([$ld_shlibs])
-test "$ld_shlibs" = no && can_build_shared=no
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-# Check hardcoding attributes.
-AC_MSG_CHECKING([how to hardcode library paths into programs])
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" || \
- test -n "$runpath_var"; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$hardcode_shlibpath_var" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-AC_MSG_RESULT([$hardcode_action])
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-striplib=
-old_striplib=
-AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-##
-## END FIXME
-
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-## FIXME: this should be a separate macro
-##
-# PORTME Fill in your ld.so characteristics
-AC_MSG_CHECKING([dynamic linker characteristics])
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}.so$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}.so$major'
- ;;
-
-aix4* | aix5*)
- version_type=linux
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[[01]] | aix4.[[01]].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can
- # not hardcode correct soname into executable. Probably we can
- # add versioning support to collect2, so additional links can
- # be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}.so$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}.so'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi4*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
- soname_spec='${libname}${release}.so$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- export_dynamic_flag_spec=-rdynamic
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- need_version=no
- need_lib_prefix=no
- case $GCC,$host_os in
- yes,cygwin*)
- library_names_spec='$libname.dll.a'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
- postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog .libs/$dlname \$dldir/$dlname'
- postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- ;;
- yes,mingw*)
- library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
- ;;
- yes,pw32*)
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
- ;;
- *)
- library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
- library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
- soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd*)
- objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- *)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-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
- 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.
- dynamic_linker="$host_os dld.sl"
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
- soname_spec='${libname}${release}.sl$major'
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-irix5* | irix6*)
- version_type=irix
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}.so$major'
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
- case $host_os in
- irix5*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux-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'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
- soname_spec='${libname}${release}.so$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case "$host_os" in
- openbsd2.[[89]] | openbsd2.[[89]].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-os2*)
- libname_spec='$name'
- need_lib_prefix=no
- library_names_spec='$libname.dll $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_version=no
- soname_spec='${libname}${release}.so'
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-sco3.2v5*)
- version_type=osf
- soname_spec='${libname}${release}.so$major'
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-solaris*)
- 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
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- version_type=linux
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
- soname_spec='${libname}${release}.so$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
- soname_spec='${libname}${release}.so$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-dgux*)
- 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
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
- soname_spec='$libname.so.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-AC_MSG_RESULT([$dynamic_linker])
-test "$dynamic_linker" = no && can_build_shared=no
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-# Report the final consequences.
-AC_MSG_CHECKING([if libtool supports shared libraries])
-AC_MSG_RESULT([$can_build_shared])
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-AC_MSG_CHECKING([whether to build shared libraries])
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case "$host_os" in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
-aix4*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-AC_MSG_RESULT([$enable_shared])
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-AC_MSG_CHECKING([whether to build static libraries])
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-AC_MSG_RESULT([$enable_static])
-##
-## END FIXME
-
-if test "$hardcode_action" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-AC_LIBTOOL_DLOPEN_SELF
-
-## FIXME: this should be a separate macro
-##
-if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- AC_MSG_CHECKING([whether -lc should be explicitly linked in])
- AC_CACHE_VAL([lt_cv_archive_cmds_need_lc],
- [$rm conftest*
- echo 'static int dummy;' > conftest.$ac_ext
-
- if AC_TRY_EVAL(ac_compile); then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_cv_prog_cc_wl
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
- then
- lt_cv_archive_cmds_need_lc=no
- else
- lt_cv_archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi])
- AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc])
- ;;
- esac
-fi
-need_lc=${lt_cv_archive_cmds_need_lc-yes}
-##
-## END FIXME
-
-## FIXME: this should be a separate macro
-##
-# The second clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- :
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- test -f Makefile && make "$ltmain"
-fi
-
-if test -f "$ltmain"; then
- trap "$rm \"${ofile}T\"; exit 1" 1 2 15
- $rm -f "${ofile}T"
-
- echo creating $ofile
-
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS \
- AR AR_FLAGS CC LD LN_S NM SHELL \
- reload_flag reload_cmds wl \
- pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
- thread_safe_flag_spec whole_archive_flag_spec libname_spec \
- library_names_spec soname_spec \
- RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
- old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
- postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
- old_striplib striplib file_magic_cmd export_symbols_cmds \
- deplibs_check_method allow_undefined_flag no_undefined_flag \
- finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
- global_symbol_to_c_name_address \
- hardcode_libdir_flag_spec hardcode_libdir_separator \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
-
- case $var in
- reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
- extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- cat <<__EOF__ > "${ofile}T"
-#! $SHELL
-
-# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996-2000 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.
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="sed -e s/^X//"
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
-
-# ### BEGIN LIBTOOL CONFIG
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$need_lc
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# The default C compiler.
-CC=$lt_CC
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC
-
-# The linker used to build libraries.
-LD=$lt_LD
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_wl
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_pic_flag
-pic_mode=$pic_mode
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_compiler_c_o
-
-# Can we write directly to a .lo ?
-compiler_o_lo=$lt_compiler_o_lo
-
-# Must we lock files when doing compilation ?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_link_static_flag
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_no_builtin_flag
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds
-archive_expsym_cmds=$lt_archive_expsym_cmds
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path"
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms
-
-# ### END LIBTOOL CONFIG
-
-__EOF__
-
- case $host_os in
- aix3*)
- cat <<\EOF >> "${ofile}T"
-
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-EOF
- ;;
- esac
-
- case $host_os in
- cygwin* | mingw* | pw32* | os2*)
- cat <<'EOF' >> "${ofile}T"
- # This is a source program that is used to create dlls on Windows
- # Don't remove nor modify the starting and closing comments
-# /* ltdll.c starts here */
-# #define WIN32_LEAN_AND_MEAN
-# #include <windows.h>
-# #undef WIN32_LEAN_AND_MEAN
-# #include <stdio.h>
-#
-# #ifndef __CYGWIN__
-# # ifdef __CYGWIN32__
-# # define __CYGWIN__ __CYGWIN32__
-# # endif
-# #endif
-#
-# #ifdef __cplusplus
-# extern "C" {
-# #endif
-# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
-# #ifdef __cplusplus
-# }
-# #endif
-#
-# #ifdef __CYGWIN__
-# #include <cygwin/cygwin_dll.h>
-# DECLARE_CYGWIN_DLL( DllMain );
-# #endif
-# HINSTANCE __hDllInstance_base;
-#
-# BOOL APIENTRY
-# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
-# {
-# __hDllInstance_base = hInst;
-# return TRUE;
-# }
-# /* ltdll.c ends here */
- # This is a source program that is used to create import libraries
- # on Windows for dlls which lack them. Don't remove nor modify the
- # starting and closing comments
-# /* impgen.c starts here */
-# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
-#
-# This file is part of GNU libtool.
-#
-# 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.
-# */
-#
-# #include <stdio.h> /* for printf() */
-# #include <unistd.h> /* for open(), lseek(), read() */
-# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
-# #include <string.h> /* for strdup() */
-#
-# /* O_BINARY isn't required (or even defined sometimes) under Unix */
-# #ifndef O_BINARY
-# #define O_BINARY 0
-# #endif
-#
-# static unsigned int
-# pe_get16 (fd, offset)
-# int fd;
-# int offset;
-# {
-# unsigned char b[2];
-# lseek (fd, offset, SEEK_SET);
-# read (fd, b, 2);
-# return b[0] + (b[1]<<8);
-# }
-#
-# static unsigned int
-# pe_get32 (fd, offset)
-# int fd;
-# int offset;
-# {
-# unsigned char b[4];
-# lseek (fd, offset, SEEK_SET);
-# read (fd, b, 4);
-# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
-# }
-#
-# static unsigned int
-# pe_as32 (ptr)
-# void *ptr;
-# {
-# unsigned char *b = ptr;
-# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
-# }
-#
-# int
-# main (argc, argv)
-# int argc;
-# char *argv[];
-# {
-# int dll;
-# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
-# unsigned long export_rva, export_size, nsections, secptr, expptr;
-# unsigned long name_rvas, nexp;
-# unsigned char *expdata, *erva;
-# char *filename, *dll_name;
-#
-# filename = argv[1];
-#
-# dll = open(filename, O_RDONLY|O_BINARY);
-# if (dll < 1)
-# return 1;
-#
-# dll_name = filename;
-#
-# for (i=0; filename[i]; i++)
-# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
-# dll_name = filename + i +1;
-#
-# pe_header_offset = pe_get32 (dll, 0x3c);
-# opthdr_ofs = pe_header_offset + 4 + 20;
-# num_entries = pe_get32 (dll, opthdr_ofs + 92);
-#
-# if (num_entries < 1) /* no exports */
-# return 1;
-#
-# export_rva = pe_get32 (dll, opthdr_ofs + 96);
-# export_size = pe_get32 (dll, opthdr_ofs + 100);
-# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
-# secptr = (pe_header_offset + 4 + 20 +
-# pe_get16 (dll, pe_header_offset + 4 + 16));
-#
-# expptr = 0;
-# for (i = 0; i < nsections; i++)
-# {
-# char sname[8];
-# unsigned long secptr1 = secptr + 40 * i;
-# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
-# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
-# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
-# lseek(dll, secptr1, SEEK_SET);
-# read(dll, sname, 8);
-# if (vaddr <= export_rva && vaddr+vsize > export_rva)
-# {
-# expptr = fptr + (export_rva - vaddr);
-# if (export_rva + export_size > vaddr + vsize)
-# export_size = vsize - (export_rva - vaddr);
-# break;
-# }
-# }
-#
-# expdata = (unsigned char*)malloc(export_size);
-# lseek (dll, expptr, SEEK_SET);
-# read (dll, expdata, export_size);
-# erva = expdata - export_rva;
-#
-# nexp = pe_as32 (expdata+24);
-# name_rvas = pe_as32 (expdata+32);
-#
-# printf ("EXPORTS\n");
-# for (i = 0; i<nexp; i++)
-# {
-# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
-# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
-# }
-#
-# return 0;
-# }
-# /* impgen.c ends here */
-
-EOF
- ;;
- esac
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
-
- mv -f "${ofile}T" "$ofile" || \
- (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
- chmod +x "$ofile"
-fi
-##
-## END FIXME
-
-])# _LT_AC_LTCONFIG_HACK
-
# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
-AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+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_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_DEFUN(AC_ENABLE_SHARED, [dnl
+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
+case "$enableval" in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
@@ -3015,22 +172,21 @@ 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_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_DEFUN(AC_ENABLE_STATIC, [dnl
+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
+case "$enableval" in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
@@ -3049,8 +205,7 @@ 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_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_STATIC(no)])
@@ -3058,14 +213,14 @@ AC_ENABLE_STATIC(no)])
# 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_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+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
+case "$enableval" in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
@@ -3083,120 +238,29 @@ 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 - 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_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_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
ac_prog=ld
-if test "$GCC" = yes; then
+if test "$ac_cv_prog_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
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
# Accept absolute paths.
- [[\\/]]* | [[A-Za-z]]:[[\\/]]*)
- re_direlt='/[[^/]][[^/]]*/\.\./'
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
# 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
@@ -3218,17 +282,17 @@ elif test "$with_gnu_ld" = yes; then
else
AC_MSG_CHECKING([for non-GNU ld])
fi
-AC_CACHE_VAL(lt_cv_path_LD,
+AC_CACHE_VAL(ac_cv_path_LD,
[if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ 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"
+ ac_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
+ if "$ac_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
@@ -3237,9 +301,9 @@ AC_CACHE_VAL(lt_cv_path_LD,
done
IFS="$ac_save_ifs"
else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
-LD="$lt_cv_path_LD"
+LD="$ac_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
@@ -3249,252 +313,56 @@ test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_PROG_LD_GNU
])
-# 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,
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_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
+ ac_cv_prog_gnu_ld=yes
else
- lt_cv_prog_gnu_ld=no
+ ac_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
-AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
-[AC_CACHE_CHECK([how to recognise dependant libraries],
-lt_cv_deplibs_check_method,
-[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
-aix4* | aix5*)
- 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=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
- ;;
- *) # 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*)
- 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
- ;;
-
-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* )
- 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
- ;;
-
-newos6*)
- 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
- ;;
-
-openbsd*)
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
- else
- lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
- fi
- ;;
-
-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
- 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*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- esac
- ;;
-esac
-])
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-])
-
-
# AC_PROG_NM - find the path to a BSD-compatible name lister
-AC_DEFUN([AC_PROG_NM],
-[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
-AC_MSG_CHECKING([for BSD-compatible nm])
-AC_CACHE_VAL(lt_cv_path_NM,
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
- lt_cv_path_NM="$NM"
+ ac_cv_path_NM="$NM"
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ 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
+ if test -f $ac_dir/nm || test -f $ac_dir/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"
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/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"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
break
else
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/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
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
fi])
-NM="$lt_cv_path_NM"
+NM="$ac_cv_path_NM"
AC_MSG_RESULT([$NM])
])
# AC_CHECK_LIBM - check for math library
-AC_DEFUN([AC_CHECK_LIBM],
+AC_DEFUN(AC_CHECK_LIBM,
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
LIBM=
-case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32*)
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
# These system don't have libm
;;
*-ncr-sysv4.3*)
@@ -3508,39 +376,33 @@ 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
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate 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'])
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/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.
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate 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_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
@@ -3551,8 +413,8 @@ AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
])
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'])
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
else
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
LIBLTDL="-lltdl"
@@ -3560,14 +422,14 @@ AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
fi
])
-# 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])
-
-# This is just to silence aclocal about the macro not being used
-ifelse([AC_DISABLE_FAST_INSTALL])
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
diff --git a/boehm-gc/mkinstalldirs b/boehm-gc/mkinstalldirs
index f9c37afd1b8..cc8783edce3 100755
--- a/boehm-gc/mkinstalldirs
+++ b/boehm-gc/mkinstalldirs
@@ -2,90 +2,29 @@
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
+# Last modified: 1994-03-25
# Public domain
-# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
-
errstatus=0
-dirmode=""
-
-usage="\
-Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
-
-# process command line arguments
-while test $# -gt 0 ; do
- case "${1}" in
- -h | --help | --h* ) # -h for help
- echo "${usage}" 1>&2; exit 0 ;;
- -m ) # -m PERM arg
- shift
- test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
- dirmode="${1}"
- shift ;;
- -- ) shift; break ;; # stop option processing
- -* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
- * ) break ;; # first non-opt arg
- esac
-done
-
-for file
-do
- if test -d "$file"; then
- shift
- else
- break
- fi
-done
-
-case $# in
-0) exit 0 ;;
-esac
-case $dirmode in
-'')
- if mkdir -p -- . 2>/dev/null; then
- echo "mkdir -p -- $*"
- exec mkdir -p -- "$@"
- fi ;;
-*)
- if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
- echo "mkdir -m $dirmode -p -- $*"
- exec mkdir -m "$dirmode" -p -- "$@"
- fi ;;
-esac
-
-for file
-do
+for file in ${1+"$@"} ; do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
- for d
- do
+ for d in ${1+"$@"} ; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
- echo "mkdir $pathcomp"
-
- mkdir "$pathcomp" || lasterr=$?
-
- if test ! -d "$pathcomp"; then
- errstatus=$lasterr
- else
- if test ! -z "$dirmode"; then
- echo "chmod $dirmode $pathcomp"
-
- lasterr=""
- chmod "$dirmode" "$pathcomp" || lasterr=$?
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
+ fi
- if test ! -z "$lasterr"; then
- errstatus=$lasterr
- fi
- fi
- fi
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
fi
pathcomp="$pathcomp/"
@@ -94,8 +33,4 @@ done
exit $errstatus
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 3
-# End:
# mkinstalldirs ends here
diff --git a/compile b/compile
new file mode 100644
index 00000000000..a81e000ae1a
--- /dev/null
+++ b/compile
@@ -0,0 +1,136 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2003-11-09.00
+
+# Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# 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.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit 0
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit 0
+ ;;
+esac
+
+
+prog=$1
+shift
+
+ofile=
+cfile=
+args=
+while test $# -gt 0; do
+ case "$1" in
+ -o)
+ # configure might choose to run compile as `compile cc -o foo foo.c'.
+ # So we do something ugly here.
+ ofile=$2
+ shift
+ case "$ofile" in
+ *.o | *.obj)
+ ;;
+ *)
+ args="$args -o $ofile"
+ ofile=
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ args="$args $1"
+ ;;
+ *)
+ args="$args $1"
+ ;;
+ esac
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no `-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # `.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$prog" $args
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
+while true; do
+ if mkdir $lockdir > /dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir $lockdir; exit 1" 1 2 15
+
+# Run the compile.
+"$prog" $args
+status=$?
+
+if test -f "$cofile"; then
+ mv "$cofile" "$ofile"
+fi
+
+rmdir $lockdir
+exit $status
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
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/tree-ssa.doxy b/contrib/tree-ssa.doxy
new file mode 100644
index 00000000000..957e2a6a796
--- /dev/null
+++ b/contrib/tree-ssa.doxy
@@ -0,0 +1,1113 @@
+# Doxyfile 1.3.5
+
+# 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@
+
+#-----------------------------------------------------------------------------
+
+
+
+
+#---------------------------------------------------------------------------
+# Project related 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, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = 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
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# 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 =
+
+# 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 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
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = 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
+# re-implements.
+
+INHERIT_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
+
+# 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 =
+
+# 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 OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# 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 classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# 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
+
+# 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 advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# 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 SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = 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
+
+# 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
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# 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 consists 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 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
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = 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 *.cs *.php *.php3 *.inc
+
+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 (i.e. when SOURCE_BROWSER is set to YES).
+
+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.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+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
+
+# 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 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
+
+# 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
+
+#---------------------------------------------------------------------------
+# 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. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+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 CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# 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, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). 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
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# 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
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# 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 optimized 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 assignments. 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.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML 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 `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# 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 Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# 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_ONLY_PREDEF 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, have an all uppercase name, 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 option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+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 superseded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = 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 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 the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_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 CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# 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 png, jpg, or gif
+# If left blank png 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
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# 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 intermediate 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
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/fastjar/configure.ac b/fastjar/configure.ac
new file mode 100644
index 00000000000..635836fd882
--- /dev/null
+++ b/fastjar/configure.ac
@@ -0,0 +1,102 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.59)
+AC_INIT(jartool.h)
+AM_INIT_AUTOMAKE(fastjar, 0.92-gcc)
+AM_CONFIG_HEADER(config.h)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PATH_PROG(RM, rm, /bin/rm, $PATH:/bin:/usr/bin:/usr/local/bin)
+AC_PATH_PROG(CP, cp, /bin/cp, $PATH:/bin:/usr/bin:/usr/local/bin)
+AC_PATH_PROG(STRIP, strip, /usr/bin/strip, $PATH:/bin:/usr/bin:/usr/local/bin)
+AC_PATH_PROG(CHMOD, chmod, /bin/chmod, $PATH:/bin:/usr/bin:/usr/local/bin)
+AC_EXEEXT
+
+AM_MAINTAINER_MODE
+
+dnl Add warning flags if we are using gcc.
+if test "$GCC" = yes; then
+ fastjar_warn_cflags='-W -Wall -pedantic -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings'
+fi
+AC_SUBST(fastjar_warn_cflags)
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_STRUCT_TM
+AC_CHECK_HEADERS(fcntl.h unistd.h sys/param.h stdlib.h limits.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_OFF_T
+AC_STRUCT_TM
+
+# mkdir takes a single argument on some systems.
+gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
+
+dnl Check for type-widths
+AC_COMPILE_CHECK_SIZEOF(char)
+AC_COMPILE_CHECK_SIZEOF(short)
+AC_COMPILE_CHECK_SIZEOF(int)
+AC_COMPILE_CHECK_SIZEOF(long)
+AC_CHECK_TYPES([long long],[AC_COMPILE_CHECK_SIZEOF(long long)])
+
+dnl Check byte order
+AC_C_BIGENDIAN_CROSS
+
+AC_ARG_WITH(system-zlib,
+[ --with-system-zlib use installed libz])
+
+ZLIBS=
+ZDEPS=
+ZINCS=
+use_zlib=maybe
+if test "$with_system_zlib" = yes; then
+ AC_CHECK_LIB(z, deflate, ZLIBS=-lz, use_zlib=no)
+else
+ use_zlib=no
+fi
+
+if test "$use_zlib" = no; then
+ # Brain dead way to find tree's zlib.
+ ZDEPS='$(top_builddir)/../zlib/libz.a'
+ ZLIBS="$ZDEPS -L\$(here)/../zlib/$libsubdir"
+ ZINCS='-I$(top_srcdir)/../zlib'
+fi
+AC_SUBST(ZLIBS)
+AC_SUBST(ZDEPS)
+AC_SUBST(ZINCS)
+
+# GCC LOCAL CHANGE
+# We would like to our source tree to be readonly. However when releases or
+# pre-releases are generated, the man pages need to be included as they are
+# converted from the texi files via perl which we don't require end users to
+# have installed.
+# Therefore we have --enable-generated-files-in-srcdir to do just that.
+
+AC_MSG_CHECKING([whether to place generated files in the source directory])
+ dnl generated-files-in-srcdir is disabled by default
+ AC_ARG_ENABLE(generated-files-in-srcdir,
+[ --enable-generated-files-in-srcdir
+ put copies of generated files in source dir
+ intended for creating source tarballs for users
+ without texinfo, perl, bison or flex.],
+ generated_files_in_srcdir=$enableval,
+ generated_files_in_srcdir=no)
+
+AC_MSG_RESULT($generated_files_in_srcdir)
+AM_CONDITIONAL(GENINSRC, test x$generated_files_in_srcdir = xyes)
+
+# Get the version trigger filename from the toplevel
+if test "${with_gcc_version_trigger+set}" = set; then
+ gcc_version_trigger=$with_gcc_version_trigger
+else
+ gcc_version_trigger=${srcdir}/version.c
+fi
+changequote(,)dnl
+gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*"\([^"]*\)".*/\1/'`
+gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
+changequote([,])dnl
+AC_SUBST(gcc_version)
+
+AC_OUTPUT(Makefile install-defs.sh)
diff --git a/fastjar/shift.c b/fastjar/shift.c
new file mode 100644
index 00000000000..dde90358719
--- /dev/null
+++ b/fastjar/shift.c
@@ -0,0 +1,166 @@
+/* shift.c -- utilities to move regions of data in a file.
+ 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. */
+
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "jartool.h"
+#include "shift.h"
+
+#define BUFFER_SIZE 1024
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/*
+ * Shift the contents of a file up by `amount' bytes, starting at `begin'.
+ * The file is not truncated, data from `amount' to `begin - amount' is
+ * overwritten. The current file pointer of `fd' is preserved. Note that
+ * this might be past the new "end" of the file.
+ *
+ * If this function is passed a `struct zipentry', then all `offset'
+ * fields from that entry down the list that are greater than or equal
+ * to `begin' will be decreased by `amount'.
+ *
+ * fd - The file descriptor.
+ * begin - The offset of the first byte that should be shifted.
+ * amount - The number of bytes to shift by.
+ * ze - A pointer into a list of zip entries that should be updated
+ * to reflect the modified offset.
+ */
+int
+shift_up (int fd, off_t begin, off_t amount, struct zipentry *ze)
+{
+ extern off_t end_of_entries;
+ int len, moved = 0;
+ ub1 buffer[BUFFER_SIZE];
+ off_t where, end, save;
+
+ if (amount <= 0)
+ return 0;
+
+ if ((save = lseek (fd, 0, SEEK_CUR)) == -1)
+ return 1;
+ if ((end = lseek (fd, 0, SEEK_END)) == -1)
+ return 1;
+ if (end < begin)
+ return 0;
+
+ where = begin;
+
+ do
+ {
+ if (lseek (fd, where, SEEK_SET) < 0)
+ return 1;
+ if ((len = read (fd, buffer, BUFFER_SIZE)) < 0)
+ return 1;
+ if (len == 0)
+ break;
+ if (lseek (fd, where - amount, SEEK_SET) < 0)
+ return 1;
+ if (write (fd, buffer, len) < 0)
+ return 1;
+ where += len;
+ }
+ while (where < end);
+
+ for (; ze; ze = ze->next_entry)
+ {
+ if (ze->offset >= begin)
+ {
+ ze->offset -= amount;
+ moved = 1;
+ }
+ }
+ if (moved)
+ end_of_entries -= amount;
+
+ if (lseek (fd, save, SEEK_SET) == -1)
+ return 1;
+ return 0;
+}
+
+/*
+ * Shift the contents of this file down by `amount' bytes, extending the
+ * end of file, starting at `begin'. This function will preserve the
+ * current file pointer of `fd'. Naturally, this function will fail if
+ * `fd' is not seekable.
+ *
+ * If this function is passed a `struct zipentry', then all `offset'
+ * fields from that entry down the list that are greater than or equal
+ * to `begin' will be increased by `amount'.
+ *
+ * fd - The file descriptor.
+ * begin - The offset of the first byte that should be shifted.
+ * amount - The number of bytes to shift by.
+ * ze - A pointer into a list of zip entries that should be updated
+ * to reflect the modified offset.
+ */
+int
+shift_down (int fd, off_t begin, off_t amount, struct zipentry *ze)
+{
+ extern off_t end_of_entries;
+ int off, len, moved = 0;
+ ub1 buffer[BUFFER_SIZE];
+ off_t where, save;
+
+ if (amount <= 0)
+ return 0;
+
+ if ((save = lseek (fd, 0, SEEK_CUR)) == -1)
+ return 1;
+ if ((where = lseek (fd, 0, SEEK_END)) == -1)
+ return 1;
+ if (where < begin)
+ return 0;
+ off = (where - begin) % BUFFER_SIZE;
+ if (off == 0)
+ where -= BUFFER_SIZE;
+ else
+ where -= off;
+
+ do
+ {
+ if (lseek (fd, where, SEEK_SET) < 0)
+ return 1;
+ if ((len = read (fd, buffer, BUFFER_SIZE)) < 0)
+ return 1;
+ if (lseek (fd, where + amount, SEEK_SET) < 0)
+ return 1;
+ if (write (fd, buffer, len) < 0)
+ return 1;
+ where -= BUFFER_SIZE;
+ }
+ while (where >= begin);
+
+ for (; ze; ze = ze->next_entry)
+ {
+ if (ze->offset >= begin)
+ {
+ ze->offset += amount;
+ moved = 1;
+ }
+ }
+ if (moved)
+ end_of_entries += amount;
+
+ if (lseek (fd, save, SEEK_SET) == -1)
+ return 1;
+
+ return 0;
+}
diff --git a/fastjar/shift.h b/fastjar/shift.h
new file mode 100644
index 00000000000..0a792555c79
--- /dev/null
+++ b/fastjar/shift.h
@@ -0,0 +1,29 @@
+/* shift.h -- utilities to move regions of data in a file.
+ 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. */
+
+
+#ifndef __FASTJAR_SHIFT_H__
+#define __FASTJAR_SHIFT_H__
+
+#include <sys/types.h>
+#include "jartool.h"
+
+int shift_down (int, off_t, off_t, struct zipentry *);
+int shift_up (int, off_t, off_t, struct zipentry *);
+
+#endif /* __FASTJAR_SHIFT_H__ */
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6bac39831e9..91f391a5ed4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,34 +1,3 @@
-2003-10-27 Jakub Jelinek <jakub@redhat.com>
- Jan Hubicka <jh@suse.cz>
-
- * reload1.c (struct elim_table): Change offset, initial_offset and
- previous_offset fields to HOST_WIDE_INT.
- (offsets_at): Change from int to HOST_WIDE_INT.
- (reload): Adjust offsets_at initialization.
- (eliminate_regs_in_insn): Change type of offset to HOST_WIDE_INT.
- (verify_initial_elim_offsets): Change type of t to HOST_WIDE_INT.
- * config/i386/i386.c (ix86_compute_frame_layout): Change offset type
- to HOST_WIDE_INT. Don't save regs using mov for huge frame sizes
- if TARGET_64BIT.
- (pro_epilogue_adjust_stack): New function.
- (ix86_expand_prologue, ix86_expand_epilogue): Use it.
- * config/i386/i386.md (pro_epilogue_adjust_stack): Remove.
- (pro_epilogue_adjust_stack_1): Remove * in front of name.
- (pro_epilogue_adjust_stack_rex64): Handle -2147483648 properly.
- (pro_epilogue_adjust_stack_rex64_2): New insn.
-
- * config/i386/i386.c (ix86_expand_epilogue): Fix comment typo.
-
- * config/i386/i386.c (ix86_expand_call): Replace 40 with
- FIRST_REX_INT_REG + 3 /* R11 */.
-
-2003-10-26 Richard Henderson <rth@redhat.com>
-
- * config/alpha/alpha.md (attr cannot_copy): New.
- (call_osf_2_er, call_value_osf_2_er, ldgp_er_1, ldgp_er_2,
- prologue_ldgp_er_2, prologue_ldgp_1): Set it.
- * config/alpha/alpha.c (alpha_cannot_copy_insn_p): Test it.
-
2003-10-26 Daniel Berlin <dberlin@dberlin.org>
* ggc-zone.c: New file, zone allocating collector.
diff --git a/gcc/ChangeLog.10 b/gcc/ChangeLog.10
new file mode 100644
index 00000000000..83a80fd8664
--- /dev/null
+++ b/gcc/ChangeLog.10
@@ -0,0 +1,16352 @@
+2003-12-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * print-rtl.c (print_rtx): For hard register, write out register
+ number and register name instead of calling PRINT_REG.
+ * defaults.h (PRINT_REG): Deleted.
+ * config/i386/i386.c (print_reg): Remove handling of CODE of -1.
+ Move comments here from i386.h.
+ (print_operand, print_operand_address): Call print_reg directly.
+ * config/i386/i386.h (PRINT_REG): Deleted.
+
+2003-12-31 Roger Sayle <roger@eyesopen.com>
+
+ * config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Define
+ _INCLUDE_LONGLONG.
+
+2003-12-31 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (init_spec): Add -lunwind to shared case too if
+ USE_LIBUNWIND_EXCEPTIONS.
+
+2003-12-31 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/include/texinfo.tex: Update to version 2003-12-21.10.
+ * doc/gcc.texi, doc/gccint.texi: Don't set font for
+ @def... commands.
+ * doc/invoke.texi: Don't use empty @opindex.
+
+2003-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (c_expand_expr): Remove code to return a value
+ different from that returned by expand_expr.
+ * expr.c (store_expr): Use the validity of a target MEM, rather
+ than checking DECL_RTL (exp), to figure out if a copy is
+ required.
+
+2003-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/v850/lib1funcs.asm: Fix comment formatting.
+ * config/v850/v850.c: Likewise.
+ * config/v850/v850.h: Likewise.
+ * config/v850/v850.md: Likewise.
+
+2003-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.md (*movqi_insv_2): Remove AND in the
+ set source.
+
+2003-12-31 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config.gcc: Added m32r-linux m32rle-elf and m32le-linux targets.
+ * doc/invoke.texi: Document -mflush-func, -mflush-trap options.
+ Also add documentation for -mdebug, -malign-loops, -missue-rate,
+ and -mbranch-cost options.
+ * config/m32r/t-linux: New file: m32r-linux support.
+ * config/m32r/xm-linux.h: Likewise.
+ * config/m32r/xm-m32r.h: Likewise.
+ * config/m32r/linux.h: Likewise.
+ * config/m32r/little.h: New file: Little endian code generation
+ support.
+ * config/m32r/m32r-protos.h (m32r_legitimize_pic_address,
+ m32r_legitimate_pic_operand_p, load_pic_register): Add
+ prototypes.
+ * config/m32r/m32r.c (m32r_init): Add options for cache-flush.
+ (addr24_operand): Changes for PIC code generation.
+ * config/m32r/m32r.h (LABEL_ALIGN): Define to calculate PNOP
+ length at labels.
+ (ASM_SPEC): Add PIC support.
+ (FUNCTION_PROFILER): New define.
+ (TRAMPOLINE_SIZE, INITIALIZE_TRAMPOLINE): Changed to support
+ trampoline.
+ (CONDITIONAL_REGISTER_USAGE, CONSTANT_ADDRESS_P,
+ LEGITIMIZE_ADDRESS, JUMP_TABLES_IN_TEXT_SECTION,
+ PIC_OFFSET_TABLE_REGNUM, FINALIZE_PIC, LEGITIMATE_PIC_OPERAND_P,
+ ASM_OUTPUT_ADDR_DIFF_ELT, CASE_VECTOR_MODE): Define for PIC.
+ (move_src_operand, m32r_compute_frame_size, m32r_expand_prologue,
+ m32r_finalize_pic): Changes for PIC and profile support.
+ (global_offset_table, load_pic_register, m32r_legitimate_pic_operand_p,
+ m32r_legitimize_pic_address): Add for PIC support.
+ (m32r_file_start): Changed for little-endian-target.
+ * config/m32r/m32r.md (mvqi, movhi, movsi, movdi, movsf, movdf,
+ tablejump, tablejump_insn, call, call_value, call_value_via_label):
+ Changes for PIC.
+ (pic_load_addr, get_pc, builtin_setjmp_receiver): Added for PIC.
+ (flush_icache): Changes for cache-flush trap.
+
+2003-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.h: Remove an unnecessary #undef.
+
+2003-12-30 Roger Sayle <roger@eyesopen.com>
+
+ * cppfiles.c (pch_open_file): Minor tweak to work-around native
+ HPPA compiler bug.
+
+2003-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/rs6000/aix.h: Fix comment formatting.
+ * config/rs6000/rs6000-modes.def: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+
+2003-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-protos.h: Remove prototype for
+ const_int_1_operand.
+ * config/i386/i386.c (const_int_1_operand): Remove.
+ * config/i386/i386.h (PREDICATE_CODES): Remove
+ const_int_1_operand.
+ * config/i386/i386.md: Replace all uses of const_int_1_operand
+ with const1_operand.
+ * config/i386/pentium.md: Likewise.
+
+2003-12-30 Geoffrey Keating <geoffk@greed.local>
+
+ * doc/tm.texi (PREFERRED_RELOAD_CLASS): Describe use of NO_REGS
+ with constants.
+
+2003-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * stor-layout.c (layout_decl): Turn bitfields into ordinary
+ fields, even if they are the first field in a structure.
+
+2003-12-30 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <COND_EXPR>: Don't require strict type
+ equality, instead just prevent replacing a COND_EXPR of non-void
+ type by one of its operands of void type.
+
+2003-12-30 Andreas Schwab <schwab@suse.de>
+
+ * doc/c-tree.texi: Fix @item vs. @itemx.
+ * doc/cpp.texi: Likewise.
+ * doc/install.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (expand_builtin_apply_args_1): Fix typo in previous
+ change.
+
+2003-12-30 Jan Hubicka <jh@suse.cz>
+
+ PR target/11936
+ * i386.h (CLASS_LIKELY_SPILLED_P): Return true for
+ FP_TOP_REG/FP_SECOND_REG.
+
+2003-12-30 Steven Bosscher <steven@gcc.gnu.org>
+
+ Backport from tree-ssa (relevant changes only):
+ 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.
+ * 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.
+ * cfg.c {exit_entry_blocks): Update initializer.
+ * 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.
+ * 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-30 Jan Hubicka <jh@suse.cz>
+
+ PR target/13456
+ * i386.md (allocate_stack_worker): Use different pattern for pre and
+ post reload expansion.
+ (allocate_stack_worker_1, allocate_stack_worker_rex64): Use
+ match_scratch.
+ (allocate_stack_worder_1_postreload,
+ allocate_stack_worker_rex64_postreload): New.
+
+2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (expand_builtin_apply_args_1): Add pretend args size
+ to the virtual incoming args pointer for downward stacks.
+
+2003-12-29 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/12632
+ * fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
+ if the type of the selected branch doesn't match its' parent.
+
+2003-12-29 Jan Hubicka <jh@suse.cz>
+
+ * coverage.c (read_counts_file): Better error messages; cause corrupted
+ profiles to produce hard errors, not just warnings
+ (get_coverage_counts): Similarly.
+
+ * toplev.c (rest_of_handle_loop_optimize): Enable LOOP_AUTO_UNROLL.
+
+2003-12-29 Phil Edwards <phil@codesourcery.com>
+
+ * doc/cppopts.texi: Use of -idirafter, -iprefix, -iwithprefix, and
+ -iwithprefixbefore is not discouraged.
+
+2003-12-28 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * sbitmap.c (sbitmap_union_of_diff_cg, sbitmap_a_and_b_cg,
+ sbitmap_a_xor_b_cg): Accumulate "changed" properly.
+ (sbitmap_not): Zero all bits past n_bit.
+
+2003-12-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR opt/13159
+ * cfgloopanal.c (mark_irreducible_loops): Fix the strongly connected
+ components detection.
+ * loop-unswitch.c (unswitch_loop): Preserve simple preheaders.
+
+2003-12-27 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/uclinux.h (LIB_SPEC): Add elf2flt magic required for
+ correct linking of executables using id-based shared libraries.
+
+2003-12-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-interix.h: Remove uses of "register"
+ specifier in declarations of arguments and local variables.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386elf.h: Likewise.
+ * config/i386/ptx4-i.h: Likewise.
+ * config/i386/sysv4.h: Likewise.
+
+2003-12-26 Fariborz Jahanian <fjahanian@apple.com>
+ Geoffrey Keating <geoffk@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (legitimate_offset_address_p): Do not
+ restrict DFmode and TFmode to word alignment.
+ * config/rs6000/rs6000.md (movdf_hardfloat64): Use 'o' constraint
+ for ld/std and order before mr.
+
+2003-12-26 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/darwin.h (LINK_COMMAND_SPEC): Arrange
+ -fprofile-generate to imply -lgcov.
+
+2003-12-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (ldm_h8300s_2_normal): Use HImode for
+ addresses.
+
+2003-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Remove a constraint from a splitter.
+
+2003-12-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/13429, C/11944
+ * c-common.c (c_build_qualified_type): Return early when type is
+ error_mark_node.
+ (c_apply_type_quals_to_decl): Likewise.
+
+2003-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha-modes.def: Fix comment formatting.
+ * config/alpha/alpha.c: Likewise.
+ * config/alpha/alpha.h: Likewise.
+ * config/alpha/elf.h: Likewise.
+ * config/alpha/lib1funcs.asm: Likewise.
+ * config/alpha/openbsd.h: Likewise.
+ * config/alpha/vms-cc.c: Likewise.
+ * config/alpha/vms-crt0-64.c: Likewise.
+ * config/alpha/vms-crt0.c: Likewise.
+ * config/alpha/vms-ld.c: Likewise.
+ * config/alpha/vms-psxcrt0-64.c: Likewise.
+ * config/alpha/vms-psxcrt0.c: Likewise.
+ * config/alpha/vms.h: Likewise.
+ * config/arc/arc.c: Likewise.
+ * config/arm/aof.h: Likewise.
+ * config/arm/arm-modes.def: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/linux-elf.h: Likewise.
+ * config/arm/vxworks.h: Likewise.
+ * config/avr/avr.c: Likewise.
+ * config/avr/avr.h: Likewise.
+
+2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/xtensa/elf.h: Fix comment formatting.
+ * config/xtensa/xtensa-protos.h: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+ * config/xtensa/xtensa.h: Likewise.
+
+2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.c: Fix comment formatting.
+ * config/avr/avr.md: Likewise.
+
+2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/12721.
+ * config/avr/avr.c: Include ggc.h.
+ (tmp_reg_rtx): Declare with GTY.
+ (zero_reg_rtx): Likewise.
+ (ldi_reg_rtx): Remove.
+ (avr_override_options): Initialize zero_reg_rtx and
+ ldi_reg_rtx.
+ (avr_init): Remove.
+ Include gt-avr.h.
+ * config/avr/avr.h (LDI_REG_REGNO): Remove.
+ Remove externs for tmp_reg_rtx, zero_reg_rtx, and ldi_reg_rtx.
+
+2003-12-24 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/md.texi: Document PowerPC vector register constraint letter.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * calls.c (expand_call): Recognize calls to "sqrt" and create
+ corresponding notes.
+
+2003-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/mips.c (override_options): Use `inform' instead
+ of `warning' for -g -mabi=32 and native assembler.
+
+ * config/mips/t-iris6 (CRTSTUFF_T_CFLAGS, TARGET_LIBGCC2_CFLAGS):
+ Don't pass -Wno-error.
+
+2003-12-23 David Edelsohn <edelsohn@gnu.org>
+
+ * function.c (assign_parms): Update max_parm_reg and
+ parm_reg_stack_loc when adding new parm reg.
+
+2003-12-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ns32k/ns32k.c: Convert to ISO-C.
+
+2003-12-23 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.c (ia64_va_arg): Pass pointer for
+ variable-sized type through convert_memory_address.
+ (ia64_in_small_data_p): Always return false for FUNCTION_DECLs.
+
+2003-12-23 Jan Hubicka <jh@suse.cz>
+
+ * common.opt (fprofile-generate,fprofile-use): Add.
+ * gcc.c (LINK_COMMAND_SPEC): Arrange -fprofile-generate to imply -lgcov
+ * opts.c (profile_arc_flag_set, flag_profile_values_set,
+ flag_unroll_loops_set, flag_tracer_set,
+ flag_value_profile_transformations_set,
+ flag_peel_loops_set): New static variables.
+ (common_handle_option): Deal with -fprofile-generate/-fprofile-use
+ * invoke.texi (-fprofile-generate, -fprofile-use): Describe.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (OBJS-common): Remove dwarfout.o.
+ (dwarfout.o): Remove.
+ * common.opt: Remove -gdwarf, -gdwarf+.
+ * defaults.h (PREFERRED_DEBUGGING_TYPE): Do not check for
+ DWARF_DEBUGGING_INFO.
+ * dwarf2out.c: Fix typo in comment.
+ * dwarfout.c: Remove.
+ * opts.c (common_handle_option): Remove OPT_gdwarf, OPT_gdwarf_.
+ * toplev.c (process_options): Remove check for
+ DWARF_DEBUGGING_INFO.
+ * config/elfos.h (DWARF_DEBUGGING_INFO): Do not #define it or
+ #undef it.
+ * config/netware.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/ptx4.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/vxworks.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/alpha/unicosmk.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/arc/arc.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/i386/sco5.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/i386/x86-64.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/m32r/m32r.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/mcore/mcore-elf.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/linux64.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/liteelf.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/sol26-sld.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/sp86x-elf.h (DWARF_DEBUGGING_INFO): Likewise.
+ * doc/invoke.texi: Do not mention -gdwarf, -gdwarf-1, -gdwarf-1+,
+ or -gdwarf+.
+ * doc/tm.texi: Likewise.
+
+ * c-common.c (flag_abi_version): Default to 2.
+ * c-cppbuiltin.c (c_cpp_builtins): Define __GXX_ABI_VERSION
+ uniformly for versions above 2.
+ * doc/invoke.texi: Update documentation for -fabi-version.
+
+2003-12-22 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md: Change many instances of '!
+ TARGET_POWERPC64' to 'TARGET_32BIT' when the pattern being guarded
+ was guarded only because it changed CR0 or the carry bit in XER.
+
+2003-12-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13394
+ * toplev.c (rest_of_compilation): Move call to
+ check_function_return_warnings right after the sibcall
+ optimization pass.
+
+2003-12-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/13382
+ * c-typeck.c (convert_for_assignment): When converting from
+ integral type to pointer type, always call convert.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi: Deprecate -fwritable-strings.
+
+ * c-common.c (flag_external_templates): Remove.
+ (flag_alt_external_templates): Likewise.
+ * c-common.h (flag_external_templates): Remove.
+ (flag_alt_external_templates): Likewise.
+ * c-opts.c (c_common_handle_option): Unsupport
+ -falt-external-templates and -ftemplates.
+ * doc/invoke.texi: Remove mention of -fexternal-templates and
+ -falt-external-templates.
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/13466
+ * config.gcc (powerpc-*-darwin): Remove overridden value of need_64bit_hwint.
+
+ * emit-rtl.c (copy_rtx_if_shared): Add comment about its use of
+ copy_rtx_if_shared_1.
+ (copy_rtx_if_shared_1): Add comment about what the function does.
+
+ * c-decl.c (finish_function): Change order of checks.
+ (c_expand_body): Likewise.
+
+2003-12-22 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (legitimate_offset_address_p): Correct
+ check for the legitimate offset when memory of
+ DImode/DFmode/TFmode/TImode mode is being referenced and target
+ is TARGET_POWERPC64.
+
+2003-12-22 Dale Johannesen <dalej@apple.com>
+
+ * reload1.c: Add reg_reloaded_call_part_clobbered.
+ (reload_as_needed): Use it.
+ (forget_old_reloads_1): Ditto.
+ (emit_reload_insns): Ditto.
+
+2003-12-22 Dale Johannesen <dalej@apple.com>
+
+ PR optimization/12828
+ * loop.c: Add find_regs_nested to look inside CLOBBER(MEM).
+ (scan_loop): Call it.
+ * regclass.c (reg_scan_mark_regs): Look inside CLOBBER(MEM).
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/9163
+ * c-decl.c (poplevel): Only set DECL_INITIAL of a current function
+ if it is non-null.
+ (finish_function): Check for error_mark_node or null on DECL_RESULT and
+ DECL_RESULT of fndecl.
+ (c_expand_body): Only expand when DECL_INITIAL of fndecl is not
+ error_mark_node and not null.
+
+2003-12-21 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * rtl.h (dump_rtx_statistics): Declare it.
+ * rtl.c (rtx_alloc_counts, rtx_alloc_sizes, rtvec_alloc_counts,
+ rtx_alloc_sizes): New static vars.
+ (rtx_alloc, rtvec_alloc): Update them.
+ (dump_rtx_statistics): New function.
+ * toplev.c (finalize): Call it.
+ * ggc-page.c (struct globals): Fix comments. Add new member
+ total_allocated_per_order.
+ (ggc_alloc): Keep track of the total allocated memory.
+ (ggc_print_statistics): Clarify message. Print total allocated
+ memory stats.
+ * configure.in (gather-detailed-mem-stats): New flag.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * doc/install.texi (Configuration): Document
+ --enable-gather-detailed-mem-stats.
+
+2003-12-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (CONVERT_HARD_REGISTER_TO_SSA_P): Poison.
+ * config/i386/i386.h (CONVERT_HARD_REGISTER_TO_SSA_P): Remove.
+
+2003-12-21 Roger Sayle <roger@eyesopen.com>
+
+ * config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Define _ILP32
+ when compiling in ILP32 mode.
+
+2003-12-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (rs6000_tls_referenced_p): Return early if
+ TARGET_HAVE_TLS is false.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ip2k/ip2k-protos.h: Remove the prototype for
+ asm_output_section_name.
+ * config/ip2k/ip2k.c (asm_output_section_name): Remove.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Fix comment formatting.
+ * alloc-pool.c: Likewise.
+ * bitmap.c: Likewise.
+ * bitmap.h: Likewise.
+ * bt-load.c: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-decl.c: Likewise.
+ * c-opts.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * caller-save.c: Likewise.
+ * cfghooks.h: Likewise.
+ * cgraph.c: Likewise.
+ * collect2.c: Likewise.
+ * cppfiles.c: Likewise.
+ * cpplib.h: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * final.c: Likewise.
+ * function.c: Likewise.
+ * gcov.c: Likewise.
+ * gcse.c: Likewise.
+ * genemit.c: Likewise.
+ * ggc.h: Likewise.
+ * haifa-sched.c: Likewise.
+ * ifcvt.c: Likewise.
+ * libgcc2.h: Likewise.
+ * loop.c: Likewise.
+ * predict.h: Likewise.
+ * unwind-libunwind.c: Likewise.
+ * varasm.c: Likewise.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300.c (mn10300_encode_section_info): Fix
+ a warning.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c: Convert to ISO-C.
+ * config/avr/avr.h: Likewise.
+ * config/fr30/fr30.c: Likewise.
+ * config/ip2k/ip2k.c: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+
+2003-12-20 Andrew Pinski <pinskia@gcc.gnu.org>
+ Matt Thomas <matt@3am-software.com>
+
+ PR target/12749
+ * config/i386/i386.c (print_operand): Print only the first
+ 8 characters of the float in hex.
+
+2003-12-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (TRAMPOLINE_TEMPLATE): Shorten sequence when generating PA
+ 2.0 code.
+ (TRAMPOLINE_CODE_SIZE, MIN_CACHELINE_SIZE): New defines.
+ (INITIALIZE_TRAMPOLINE): Rework to pass line length, and aligned start
+ and end addresses to I and D cache instruction patterns.
+ * pa.md (anddi3, iordi3): Change predicates of operands 1 and 2 to
+ and_operand and ior_operand, respectively. When generating 64-bit
+ code, only one operand needs to be a register operand.
+ (xordi3): Change predicates of operands 1 and 2 to register_operand.
+ (one_cmpldi2): Change predicate of operand 1 to register_operand.
+ (dcacheflush, icacheflush): Revise to flush an arbitrary number of
+ cache lines.
+
+2003-12-20 Josef Zlomek <zlomekj@suse.cz>
+
+ PR optimization/13430, PR optimization/12322
+ * bb-reorder.c (copy_bb_p): Do not allow block with many successors to
+ be copied.
+ (find_traces_1_round): Surround check for fake edges by
+ #ifdef ENABLE_CHECKING #endif.
+
+2003-12-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR other/7956
+ * genmultilib: New variable disable_multilib. Set it to 'yes'
+ if enable_multilib was set to 'no'. Emit DISABLE_MULTILIB
+ if disable_multilib was set to 'yes'.
+ * gcc.c: Include multilib.h before tm.h.
+ * config/sparc/sol2-bi.h (LINK_ARCH_SPEC): Emit an error
+ message for multiarch options if DISABLE_MULTILIB is set.
+ * config/sparc/sol2-gld-bi.h (LINK_ARCH_SPEC): Likewise.
+
+2003-12-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/12085
+ * c-typeck.c (build_function_call): Issue a warning if a
+ function is called through an incompatible prototype and
+ replace the call by a trap in this case.
+
+2003-12-19 James E Wilson <wilson@specifixinc.com>
+
+ * install.texi (ia64-*-linux): Document minimum libunwind version
+ number.
+
+2003-12-19 Per Bothner <per@bothner.com>
+
+ * langhooks.c (lhd_print_error_function): Fix for PR c/13110.
+ Don't do pp_newline; it causes an extra blank line.
+ * pretty-print.c (pp_base_flush): Clear pp_needs_newline.
+
+2003-12-19 Jason Merrill <jason@redhat.com>
+
+ * tree.c (get_unwidened): Decide whether to narrow a bitfield
+ reference based on TYPE_SIZE, not TYPE_PRECISION.
+
+ * stmt.c (parse_output_constraint): Warn about in-out constraint
+ that doesn't allow a register.
+ (parse_input_constraint): Warn about matching constraint that
+ doesn't allow a register.
+
+2003-12-19 James E Wilson <wilson@specifixinc.com>
+
+ * flow.c (mark_set_regs, case PARALLEL): Scan loop forwards.
+ Add case for ASM_OPERANDS.
+ * global.c (global_alloc): Set regs_ever_live for regs_asm_clobbered
+ registers.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c (check_max_integer_computation_mode): Remove.
+ * dojump.c (do_jump): Don't use MAX_INTEGER_COMPUTATION_MODE.
+ * fold-const.c (fold): Likewise.
+ * system.h (MAX_INTEGER_COMPUTATION_MODE): Poison.
+ * doc/tm.texi (MAX_INTEGER_COMPUTATION_MODE): Remove.
+
+2003-12-19 James E Wilson <wilson@specifixinc.com>
+
+ * configure.in: Delete libunwind_has_eh_support test.
+ * configure: Regenerate.
+ * config.gcc (ia64*-*-linux*): Delete reference to t-libunwind-no-eh
+ and libunwind_has_eh_support check.
+ * config/t-libunwind-no-eh: Delete.
+
+2003-12-19 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-format.c (print_char_table): Allow 'I' flag on floating point
+ decimal formats.
+
+2003-12-19 Stuart Hastings <stuart@apple.com>
+
+ * gcc/config/i386/i386.c (ix86_expand_call, x86_output_mi_thunk):
+ Trivial fixes for i386.c on Darwin/x86.
+
+2003-12-19 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): Add code to
+ recognize macho-style lo_sum adrress patterns.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dwarfout.c: Remove uses of "register" specifier in
+ declarations of arguments and local variables.
+ * gensupport.c: Likewise.
+ * local-alloc.c: Likewise.
+ * regclass.c: Likewise.
+
+2003-12-19 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * config.guess: Remove.
+
+2003-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/unwind-ia64.c (ia64_copy_rbs): New function.
+ (unw_access_gr): Only call ia64_rse_rnat_addr if addr is above
+ regstk_top.
+ (uw_frame_state_for): Handle locations inside bundles.
+ (uw_init_context_1): Initialize context->rnat.
+ Set context->regstk_top to lowest rbs address which has nat collection
+ in context->rnat.
+ (uw_install_context): Fix rnat restoring.
+ Restore ar.rsc to previous state.
+ * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR,
+ MD_HANDLE_UNWABI): Handle unwinding through SA_ONSTACK frames.
+
+2003-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/13239
+ * builtins.c (expand_builtin_expect_jump): Update
+ TREE_VALUE (arglist) if unsave_expr_now langhook
+ created a new tree.
+
+2003-12-19 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_base_register_rtx_p): Use regno in comparison against
+ FIRST_PSEUDO_REGISTER.
+
+2003-12-18 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (USE_ALTIVEC_FOR_ARG_P): Don't check
+ for SVR4 ABI.
+
+2003-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/aix.h (OS_MISSING_POWERPC64): Define.
+ (OS_MISSING_ALTIVEC): Define.
+ * config/rs6000/darwin.h (ASM_SPEC): Be generous about supplying
+ -force_cpusubtype_ALL.
+ * config/rs6000/rs6000.c (rs6000_override_options): Rearrange
+ CPU information table; now always set all CPU-specific values.
+ Also, use Altivec and powerpc64 when chip and OS supports them.
+
+2003-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * fixinc/inclhack.def (darwin_macho_dyldh): New.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-12-18 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ * version.c (version_string): Renumber as 3.4.0
+ * doc/include/gcc-common.texi: Likewise
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * genrecog.c (print_host_wide_int): New.
+ (write_switch, write_cond): Use it.
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (check_bitfield_type_and_width): Remove enum special
+ case suppression of pedwarn.
+ * system.h (ENUM_BITFIELD): Use __extension__.
+ (CHAR_BITFIELD): Likewise.
+
+2003-12-18 Ulrich Weigand <uweigand@de.ibm.com>
+ Mark Dettinger <dettinge@de.ibm.com>
+
+ * config/s390/s390.md (UNSPEC_SRST): New constant.
+ ("strlendi", "strlensi"): New expanders.
+ ("*strlendi", "*strlensi"): New insns.
+
+2003-12-18 Mark Mitchell <mark@codesourcery.com>
+
+ * config/sol2.h (LINK_ARCH32_SPEC): Define in terms of ...
+ (LINK_ARCH32_SPEC_BASE): ... this new macro.
+ * config/sparc/sol2-bi.h (LINK_ARCH64_SPEC): Define in terms of
+ ...
+ (LINK_ARCH64_SPEC_BASE): ... this new macro.
+ * config/sparc/sol2-gld-bi.h (LINK_ARCH32_SPEC): New macro.
+ (LINK_ARCH64_SPEC): Likewise.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/13234
+ * tree-dump.c (dequeue_and_dump): Handle 'r' and 's' code
+ classes.
+
+2003-12-18 Steven Bosscher <stevenb@suse.de>
+
+ * Makefile.in (tracer.o, bb-reorder.o): Depend on timevar.h
+ * toplev.c (rest_of_handle_reorder_blocks, rest_of_handle_tracer):
+ Don't push and pop TV_REORDER_BLOCKS timevars, do it...
+ * bb-reorder.c (reorder_basic_blocks): ...here, and...
+ * tracer.c (tracer): here.
+
+2003-12-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * loop.c (move_movables): Handle combination of m->consec,
+ m->move_insn_first, and m->insert_temp all nonzero correctly.
+
+2003-12-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c (load_register_parameters): Don't use
+ LOAD_ARGS_REVERSED.
+ * system.h (LOAD_ARGS_REVERSED): Poison.
+ * doc/tm.texi (LOAD_ARGS_REVERSED): Remove.
+
+2003-12-17 Per Bothner <per@bothner.com>
+
+ * emit-rtl.c (set_new_first_and_last_label_num): Remove function.
+ * rtl.h (set_new_first_and_last_label_num): Remove declaration.
+
+2003-12-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.c (frv_ifcvt_modify_insn): Don't leave alone
+ scratch insns of the then branch that clobber regs needed by the
+ else branch.
+
+2003-12-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c (expand_call): Update comments.
+ * system.h (PRETEND_OUTGOING_VARARGS_NAMED): Poison.
+ * targhooks.c: Do not refer to PRETEND_OUTGOING_VARARGS_NAMED.
+
+2003-12-17 James E Wilson <wilson@specifixinc.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ * Makefile.in (gcse.o): Add $(TREE_H) to dependencies.
+ * gcse.c: Include tree.h.
+ (implicit_set_cond_p): New.
+ (find_implicit_sets): Call it.
+
+2003-12-17 Santiago Vila <sanvila@unex.es>
+
+ * config/kfreebsdgnu.h (TARGET_OS_CPP_BUILTINS): Rename from
+ TARET_OS_CPP_BUILTINS.
+
+2003-12-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * emit-rtl.c: Fix signed/unsigned comparison warnings.
+
+2003-12-17 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * predict.c (struct block_info_def, struct edge_info_def): Change
+ bit-fields of width 1 to unsigned int.
+
+2003-12-16 Geoffrey Keating <geoffk@apple.com>
+
+ PR 12480
+ * c-pch.c (pch_init): Improve error message when precompiled
+ header can't be written.
+
+ PR 12606
+ * c-pch.c (pch_init): Make a PCH file appear invalid while it's
+ being written.
+ (c_common_write_pch): Make it valid once it's done.
+
+2003-12-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR target/11992
+ * config/s390/s390.md ("*cmpmem_long_64"): Use CLCLE instruction
+ instead of CLCL.
+ ("*cmpmem_long_31"): Likewise.
+
+2003-12-17 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c: Add more comments about insn bundling.
+
+2003-12-17 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/10592
+ * caller-save.c (mark_referenced_regs): Don't short-circuit a reg
+ or subreg in SET_DEST if it isn't a hard register.
+
+2003-12-17 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (main): Add -fno-profile-arcs -fno-test-coverage
+ -fno-branch-probabilities to arguments when compiling ctors and
+ dtors.
+
+2003-12-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sol2.h: Set SUPPORTS_INIT_PRIORITY to 0.
+ * config/sparc/sol2-gld.h: Set SUPPORTS_INIT_PRIORITY to 1.
+
+2003-12-17 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_base_register_rtx_p): Don't allow virtual registers
+ as base registers for sub-word operations.
+ (thumb_legitimate_address_p): Simplify REG+REG test.
+
+2003-12-17 Segher Boessenkool <boessen@de.ibm.com>
+
+ * opts.c (wrap_help): Fix overflow.
+
+2003-12-17 Fred Fish <fnf@redhat.com>
+
+ * configure.in: Remove code to examine linker scripts and set
+ HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES.
+ * configure, config.in: Regenerate.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12218
+ * varasm.c (initializer_constant_valid_p): Allow a conversion from
+ an integral constant to an OFFSET_TYPE.
+
+2003-12-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/11012
+ * config/m32r/m32r.c (gen_compare): Call gen_addsi3 instead of
+ gen_cmp_ne_small_const_insn.
+ * config/m32r/m32r.md (cmp_ne_small_const_insn): Remove.
+
+2003-12-17 Neil Booth <neil@daikokuya.co.uk>
+ Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/3347
+ * c-decl.c (enum_decl_context): Remove BITFIELD.
+ (grokdeclarator): Take bit-field width as an input.
+ Perform bit-field width validation with
+ check_bitfield_type_and_width rather than waiting for
+ finish_struct.
+ (groktypename, groktypename_in_parm_context, start_decl,
+ push_parm_decl, grokfield, start_function): Update calls to
+ grokdeclarator.
+ (check_bitfield_type_and_width): New function.
+ (finish_struct): Move bit-field validation to grokdeclarator
+ and check_bitfield_type_and_width.
+
+2003-12-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR bootstrap/13386
+ * configure.in (gcc_cv_ld_hidden): Set to yes on hppa64*-*-hpux* when
+ using HP native linker.
+ * configure: Rebuilt.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13275
+ * c-common.h (enum rid): Add RID_OFFSETOF.
+ * c-parser.in (rid_to_yy): Ignore RID_OFFSETOF.
+ * ginclude/stddef.h (offsetof): Reimplement for C++, using
+ __offsetof__.
+ * doc/extend.texi: Document __offsetof__.
+
+2003-12-16 Stan Cox <scox@redhat.com>
+
+ * config/iq2000/iq2000.h: Formatting.
+ (MAX_INT_TYPE_SIZE, MAX_INT_TYPE_SIZE, CONST_COSTS, RTX_COSTS)
+ (ADDRESS_COST, ASM_OUTPUT_INTERNAL_LABEL, ASM_OUTPUT_INTERNAL_LABEL)
+ (IMPLICIT_FIX_EXPR, EASY_DIV_EXPR, SLOW_ZERO_EXTEND): Remove
+ * config/iq2000/iq2000.c: Formatting.
+ (iq2000_rtx_costs): New.
+
+2003-12-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (addsi3_carryin_shift): Add missing register constraints.
+
+2003-12-16 Loren James Rittle <ljrittle@acm.org>
+
+ * testsuite/g++.old-deja/g++.eh/badalloc1.C: Tweak to
+ pass with -pthread on FreeBSD systems.
+
+2003-12-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_file_end): Only write symbols that have
+ been referenced at some point.
+
+2003-12-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c: Include langhooks.h
+ (mips_build_builtin_va_list): Use lang_hooks.types.make_type.
+
+2003-12-16 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13313
+ * combine.c (make_extraction) [REG]: Do not use
+ gen_lowpart_for_combine when POS is non-zero.
+
+2003-12-16 Hartmut Penner <hpenner@de.ibm.com>
+
+ * altivec.h (vec_cmple, vec_all_numeric): Fix typo.
+ * testsuite/gcc.dg/altivec-10.c: Test for above.
+
+2003-12-15 David O'Brien <obrien@FreeBSD.org>
+
+ * Makefile.in (CPPFLAGS): Initialize from configure.
+
+2003-12-15 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/13400
+ * ifcvt.c (noce_process_if_block): Disable unconditional write
+ optimizations if we could introduce a store to trapping memory
+ that wasn't present previously.
+
+2003-12-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (DEFAULT_CALLER_SAVES): Poison.
+ * toplev.c (flag_caller_saves): Always initialize with 0.
+ * doc/tm.texi (DEFAULT_CALLER_SAVES): Remove.
+
+2003-12-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * flow.c (EXIT_IGNORE_STACK): Move to ...
+ * defaults.h (EXIT_IGNORE_STACK): ... here.
+ * dojump.c (clear_pending_stack_adjust): Don't use #ifdef
+ EXIT_IGNORE_STACK.
+ * function.c (expand_function_end): Likewise.
+ * global.c (global_alloc): Likewise.
+ * ra.c (init_ra): Likewise.
+ * reload1.c (init_elim_table): Likewise.
+ * reorg.c (fill_simple_delay_slots): Likewise.
+ * resource.c (init_resource_info): Likewise.
+ * doc/tm.texi (EXIT_IGNORE_STACK): Document that the default
+ is 0.
+
+2003-12-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * reload.c (reg_overlap_mentioned_for_reload_p):
+ When looking at a PLUS in X, avoid spuriously returning nonzero
+ when IN is a REG or another simple PLUS, or a MEM containing one.
+
+ * loop.c (loop_invariant_p): Amend comment about where new registers
+ might come from.
+
+2003-12-15 Andreas Jaeger <aj@suse.de>
+
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Remove
+ handling of obsolete language CHILL.
+
+2003-12-15 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * tree.c (initializer_zerop): Add test for empty set.
+ * integrate.c (function_cannot_inline_p): Forbid inlining
+ functions calling `longjmp'.
+
+2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11773
+ * doc/gcov.texi (Gcov and Optimization): Document inline function
+ behaviour. Fix some file suffixes.
+
+2003-12-14 David O'Brien <obrien@FreeBSD.org>
+
+ * config/i386/i386.h (__amd64, __amd64__): Remove duplicates.
+
+2003-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.h (c_parse_error): Declare it.
+ * c-common.c (c_parse_error): New function.
+ * c-parse.y (yyerror): Use it.
+
+2003-12-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/13054
+ * pa-protos.h (indexed_memory_operand, borx_reg_operand,
+ move_dest_operand, move_src_operand): New protypes.
+ (basereg_operand, move_operand, reg_or_nonsymb_mem_operand): Deleted.
+ * pa.c (copy_reg_pointer, indexed_memory_operand, move_dest_operand,
+ move_src_operand): New functions.
+ (basereg_operand, reg_or_nonsymb_mem_operand, move_operand): Delete.
+ (reg_or_0_or_nonsymb_mem_operand): Return false for unscaled indexed
+ address until cse is not expected on targets with non-equivalent
+ space registers.
+ (hppa_legitimize_address): Canonicalize unscaled indexed addresses
+ on targets non-equivalent space registers.
+ (emit_move_sequence): Break out indexed addresses from destination
+ operand. Similarly, break out unscaled indexed addresses from
+ source operand on targets with non-equivalent space registers. Fix
+ REG_POINTER flag when possible. Mark register pointer when creating
+ new pointers.
+ (print_operand): Handle unscaled index addresses.
+ * pa.h (IS_INDEX_ADDR_P, IS_LO_SUM_DLT_ADDR_P): New macro subroutines
+ for EXTRA_CONSTRAINT.
+ (EXTRA_CONSTRAINT): Rework to make more readable.
+ (MODE_OK_FOR_SCALED_INDEXING_P, MODE_OK_FOR_UNSCALED_INDEXING_P): New
+ subroutines for GO_IF_LEGITIMATE_ADDRESS.
+ (GO_IF_LEGITIMATE_ADDRESS): Rework using new subroutines. Allow scaled
+ and unscaled addresses. Canonicalize unscaled indexed addresses on
+ targets with non-equivalent space registers. Document issues in
+ handling indexed address modes on PA-RISC.
+ (PREDICATE_CODES): Update for new and deleted predicates.
+ * pa.md (move_dest_operand, move_src_operand, indexed_memory_operand):
+ Use new predicates in move patterns.
+ Add peephole2 patterns to optimize floating point stores. Fix
+ constrain preferencing in move patterns. Delete patterns for handling
+ unscaled indexed memory loads. Add missing load and store with
+ base-register modification patterns. Correct SFmode floating point
+ store pattern. Add missing zero extension loads.
+
+2003-12-13 Steven Bosscher <stevenb@suse.de>
+
+ * ggc-zone.c (struct alloc_zone): Don't pre-declare, it already
+ comes in with ggc.h. Add a new bool field `dead'.
+ (destroy_ggc_zone): Don't destroy a zone at once. Instead, only
+ set the `dead' flag for the dead zone. Wrap a sanity check in
+ ENABLE_CHECKING.
+ (ggc_collect_1): Always mark and sweep if a zone has the `dead'
+ flag set.
+ (ggc_collect): Free dead zones after collecting.
+
+2003-12-13 Jan Hubicka <jh@suse.cz>
+
+ * coverage.c (get_coverage_counts): Use inform instead of warning
+ about missing profile.
+
+2003-12-12 Steven Bosscher <stevenb@suse.de>
+
+ * Makefile.in (opts.o, explow.o): Depend on langhooks.h
+
+2003-12-12 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc <i[34567]86-*-darwin*>: Don't use fixproto.
+ <powerpc-*-darwin*>: Likewise.
+
+2003-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/linux.h (IA64_GATE_AREA_END): Increase by 64K.
+ (MD_FALLBACK_FRAME_STATE_FOR): Set fpsr_loc, br_loc[6] and
+ br_loc[7]. Update comment.
+ (MD_HANDLE_UNWABI): Define.
+ * config/ia64/unwind-ia64.c (struct unw_state_record): Add
+ unwabi field.
+ (struct _Unwind_Context): Increase br_loc array size to 8 entries.
+ (desc_abi): Set unwabi.
+ (uw_update_reg_address): Allow br up to 7.
+ (uw_update_context): Invoke MD_HANDLE_UNWABI if defined.
+ (uw_install_context): Load b1..b5 from correct locations.
+ Fix insn loading ar.fpsr.
+ * doc/tm.texi: Document MD_HANDLE_UNWABI.
+
+2003-12-12 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/13037
+ * loop.c (update_giv_derive): Ignore redundant sets of a biv when
+ calculating how to derive a giv from a biv.
+
+2003-12-12 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/12935 preprocessor/12952 preprocessor/13046
+ * cpplib.c (prepare_directive_trad): Clear skipping only in
+ #if and #elif directives.
+ (do_undef): Call the handler even if the identifier is not a macro.
+ * cpptrad.c (scan_parameters): Emit an error message.
+ (_cpp_create_trad_definition): Remember the params list even on
+ failure.
+
+2003-12-11 Zack Weinberg <zack@codesourcery.com>
+
+ * arm.c (ARM_ADDRESS_COST, THUMB_ADDRESS_COST): Convert macros
+ to inline functions: arm_arm_address_cost, arm_thumb_address_cost
+ respectively.
+ (arm_address_cost): Use 'em.
+
+2003-12-12 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/alpha/osf.h (TARGET_OS_CPP_BUILTINS): Define
+ __STDC_VERSION__ to ISO C94 for C++.
+
+ * fixinc/inclhack.def (alpha_wchar): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/wchar.h: New file.
+
+2003-12-11 David Mosberger <davidm@hpl.hp.com>
+
+ * unwind-libunwind.c (_Unwind_SetGR): Clear the NaT bit as
+ required by C++ ABI for Itanium.
+ * config/t-libunwind (LIB2ADDEH): Remove unwind-libunwind.c.
+ * config/t-libunwind-no-eh: New file.
+ * configure.in: Check libunwind for _Unwind_Resume() and if it's
+ present, set libunwind_has_eh_support to "yes".
+ * configure: Regenerate.
+ * config.gcc (ia64*-*-linux*): If $libunwind_has_eh_support is
+ set to yes, use t-libunwind, otherwise, use t-libunwind-no-eh.
+
+2003-12-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_global_pointer): Force functions with
+ a nonlocal goto to set up $gp.
+
+2003-12-11 James E Wilson <wilson@specifixinc.com>
+
+ PR target/13132
+ * function.c (gen_mem_addressof): When no decl, explicitly clear flag
+ bits.
+
+2003-12-12 Nick Clifton <nickc@redhat.com>
+
+ * config/m32r/m32r.c: Convert to ISO-C
+
+2003-12-12 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * doc/invoke.texi: Replace Mitsubishi with Renesas.
+ * config/m32r/m32r.h: Ditto.
+ * config/m32r/m32r.c: Ditto.
+ * config/m32r/m32r.md: Ditto.
+
+2003-12-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * basic-block.h (BLOCK_HEAD, BLOCK_END): Remove.
+ (BLOCK_HEAD_TREE, BLOCK_END_TREE): Remove.
+ (basic_block_def): Rename `head' to `head_' and `end' to `end_'.
+ (BB_HEAD, BB_END): New accessor macros for the `head_' and `end_'
+ fields of a basic block.
+ * bb-reorder.c, bt-load.c, caller-save.c, cfg.c, cfganal.c,
+ cfgbuild.c, cfgcleanup.c, cfglayout.c, cfgloop.c, cfgloopanal.c,
+ cfgloopmanip.c, cfgrtl.c, combine.c, conflict.c, df.c, emit-rtl.c,
+ final.c, flow.c, function.c, gcse.c, global.c, graph.c,
+ haifa-sched.c, ifcvt.c, lcm.c, local-alloc.c, loop-unswitch.c,
+ loop.c, postreload.c, predict.c, profile.c, ra-build.c, ra-debug.c,
+ ra-rewrite.c, ra.c, recog.c, reg-stack.c, regclass.c, regmove.c,
+ regrename.c, reload1.c, resource.c, sched-ebb.c, sched-rgn.c,
+ sibcall.c, tracer.c, config/frv/frv.c, config/i386/i386.c,
+ config/ia64/ia64.c: Use the BB_HEAD and BB_END macros instead of
+ accessing the `head' and `end' fields of a basic block directly.
+
+ * gengtype.c: Teach about "void**" pointers and "void *" function
+ types. Fixes earlier commit.
+
+2003-12-10 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/extend.texi (Vector Extensions): Document that bitwise
+ operations also work on vectors.
+
+2003-12-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md: New split patterns for optimizing bitfield accesses.
+
+2003-12-10 Steven Bosscher <stevenb@suse.de>
+
+ * README.Portability: Remove K+R section.
+
+ * gengtype-lex.l: Teach about "void**" pointers and
+ "void*" function types.
+
+2003-12-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/13354
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Load DELTA
+ manually if one can do that with only one instruction.
+
+2003-12-10 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc (arm-linux): Include linux.h in tm_file so that
+ LINUX_TARGET_OS_CPP_BUILTINS is defined.
+ * config/arm/linux-elf.h (LIB_SPEC): Protect the definition.
+
+2003-12-09 James E Wilson <wilson@specifixinc.com>
+
+ * rtl.def (CODE_LABEL, NOTE): Correct operand numbers in comments.
+
+2003-12-09 Matt Austern <austern@apple.com>
+
+ PR c/13134
+ * c-decl.c (duplicate_decls): Copy visibility flag when appropriate.
+
+2003-12-09 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h: Add support for m32r2 processor. Including
+ a new command line option -m32r2 to select it.
+ * config/m32r/m32r.c: Add support for the new processor variant.
+ * config/m32r/m32r.md: Likewise.
+ * config/m32r/t-m32r: Add m32r2 multilibs.
+ * doc/invoke.texi: Document the new command line switch.
+
+2003-12-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * defaults.h (LOCAL_REGNO): Give the default definition.
+ * flow.c (LOCAL_REGNO): Remove.
+ * reload1.c (LOCAL_REGNO): Likewise.
+
+2003-12-08 Geoffrey Keating <geoffk@apple.com>
+
+ PR target/11848
+ * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Allow change of mode
+ in floating-point registers between TFmode and DImode.
+ * rs6000.c (rs6000_emit_move): Split moves early.
+ (secondary_reload_class): Random Whitespace Change.
+ (rs6000_split_multireg_move): Support moves involving FP registers.
+ Emit instructions directly.
+ * rs6000-protos.h (rs6000_split_multireg_move): Update prototype.
+ * altivec.md: Update for changes to rs6000_split_multireg_move.
+ * rs6000.md: Update for changes to rs6000_split_multireg_move.
+ (movtf_internal): Support moves to/from GPRs.
+
+2003-12-08 Stuart Hastings <stuart@apple.com>
+
+ * config/i386/i386.md: Typo in split of fp-valued if_then_else.
+
+2003-12-08 James E Wilson <wilson@specifixinc.com>
+
+ PR target/13132
+ * expmed.c (extract_bit_field): Only call mode_for_size for scalar
+ integer modes.
+
+2003-12-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Revert change of Dec 7; gcc is still a 2.13
+ directory.
+
+2003-12-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.md (subdi2): Merge with _internal insn_and_split,
+ by using match_scratch.
+ (negdi2): New.
+
+2003-12-08 Jason Merrill <jason@redhat.com>
+ Daniel Berlin <dberlin@dberlin.org>
+
+ PR debug/11114
+ Support namespaces in DWARF 2 output.
+ * dwarf2out.c (gen_namespace_die): New function.
+ (force_namespace_die, setup_namespace_context): New fns.
+ (declare_in_namespace): New fn.
+ (gen_decl_die): Call declare_in_namespace. Handle namespaces.
+ (dwarf2out_decl): Handle namespaces.
+ (scope_die_for): Pass through a namespace scope.
+ (class_scope_p): Rename to class_or_namespace_scope_p.
+ (gen_subprogram_die, gen_variable_die): Adjust.
+ (gen_struct_or_union_die): Always emit a declaration
+ if context_die is a namespace.
+
+2003-12-08 Jan Hubicka <jh@suse.cz>
+
+ * unwind-pe.h (read_uleb128): Fix handling of large values
+ (read_sleb128): Fix handling of large values
+
+2003-12-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/10060
+ * emit-rtl.c (copy_rtx_if_shared): Split out into ...
+ (copy_rtx_if_shared_1): here and optimize the last one
+ in the sequence into tail-recursion.
+ (reset_used_flags): Optimize the last one
+ in the sequence into tail-recursion.
+
+2003-12-08 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md: New split to transform ((X << y) - 1) into ~(~(X-1) << y)
+ for constant X.
+
+2003-12-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * calls.c (expand_call): Don't try using tail or recursive calls
+ after the function body has been expanded.
+
+2003-12-08 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (cmpstr expander): Obey TARGET_INLINE_ALL_STRINGOPS
+
+2003-12-08 Arnaud Charlet <charlet@act-europe.fr>
+
+ PR ada/13324, PR ada/12614
+ * doc/install.texi: Update requirements for building Ada.
+
+2003-12-07 David Edelsohn <edelsohn@gnu.org>
+ Graham Reed <greed@pobox.com>
+
+ * collect2.c (GCC_OK_SYMBOL): Add support for AIX C_WEAKEXT.
+ (GCC_UNDEF_SYMBOL): Same.
+
+2003-12-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * final.c (final_scan_insn): Don't use FINAL_PRESCAN_LABEL.
+ * system.h (FINAL_PRESCAN_LABEL): Poison.
+ * doc/tm.texi (FINAL_PRESCAN_LABEL): Remove.
+
+2003-12-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (compare): Combine toplevel and $(SUBDIRS) cases.
+
+2003-12-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in, aclocal.m4: Revert to pre-2.5x conversion status.
+ * configure: Regenerate with autoconf 2.13.
+
+ * configure.in: Replace AC_INIT, AC_OUTPUT, AC_CANONICAL_SYSTEM
+ with modern equivalents.
+ * configure: Regenerate.
+
+ * configure.in: Replace gcc_AC_CHECK_TYPE with AC_CHECK_TYPE.
+ * aclocal.m4 (gcc_AC_CHECK_TYPE): Remove.
+ * configure: Regenerate.
+
+ * configure: Regenerate with (preferred) autoconf 2.57.
+ * doc/install.texi: Note that 'gcc' is now a 2.57 directory.
+
+2003-12-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12965
+ * caller-save.c (save_call_clobbered_regs): Do not save/restore
+ registers around no-return calls.
+
+2003-12-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Make minimum necessary changes for autoconf 2.5x.
+ * aclocal.m4: Make minimum necessary changes for autoconf 2.5x.
+ * configure: Regenerate with autoconf 2.58.
+
+2003-12-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13318
+ * loop.c (express_from): Protect integer division from overflow.
+
+2003-12-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13060
+ * function.c (fixup_var_refs_1) [SUBREG]: Recognize even if a
+ replacement already exists. Fix again the whole insn if that fails.
+
+2003-12-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (macho_branch_islands): Use
+ HOST_WIDE_INT_PRINT_UNSIGNED.
+
+2003-12-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * varasm.c (incorporeal_function_p): New.
+ (assemble_external): Use it as a filter.
+ * config/mips/mips.c (mips_output_external): Don't check for builtin
+ functions here.
+
+2003-12-06 Richard Earnshaw <reanrsha@arm.com>
+
+ * arm.md (IOR (COMPARISON) (AND)): New define_splits.
+
+2003-12-06 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (program_transform_cross_name): Delete.
+ (GCC_CROSS_NAME, CPP_CROSS_NAME): Delete.
+ (PROTOIZE_CROSS_NAME, UNPROTOIZE_CROSS_NAME): Delete.
+ (AR_FOR_TARGET, RANLIB_FOR_TARGET, NM_FOR_TARGET): Adjust for above.
+ (install_cpp, install_driver, install-man, uninstall): Likewise.
+
+2003-12-06 Alan Modra <amodra@bigpond.net.au>
+
+ PR 13169
+ * basic-block.h (PROP_ASM_SCAN): Define.
+ * final.c (regs_asm_clobbered): New array.
+ * regs.h (regs_asm_clobbered): Declare.
+ * flow.c (life_analysis): Init it.
+ (mark_set_regs): Set PROP_ASM_SCAN for asms.
+ (mark_set_1): Set regs_asm_clobbered.
+ * global.c (global_alloc): Don't set eliminable_regset when
+ regs_asm_clobbered.
+
+2003-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/ia64.h (MUST_PASS_IN_STACK): Define.
+
+ PR c++/13314
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Robustify.
+
+2003-12-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR driver/13211
+ * gcc.c (execute) Increment execution_count when returning
+ early because verbose_only_flag is true.
+
+2003-12-05 Per Bothner <pbothner@apple.com>
+
+ * cppfiles.c (file_hash_hash): New static function.
+ (hash_string_eq): Renamed static function to file_hash_eq.
+ (_cpp_init_files): Create file_hash table with above callbacks.
+ (cpp_included): Must use htab_find_with_hash insead of htab_find.
+ (_cpp_find_find, make_cpp_dir): Must use htab_find_slot_with_hash.
+
+2003-12-05 Per Bothner <pbothner@apple.com>
+
+ * line-map.h (source_location): New typedef.
+ (fileline): Redefined as source_location.
+ (struct line_map, linemap_add, linemap_lookup): Replace filefile
+ by source_location.
+ * line-map.c (linemap_add, linemap_lookup): Use source_location.
+
+2003-12-05 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_build_builtin_va_list): Add dummy
+ field to suppress -Wpadded warnings.
+
+2003-12-05 Stuart Hastings <stuart@apple.com>
+
+ * config/rs6000/rs6000.md: Correct macro test of TARGET_MACHO.
+
+2003-12-05 Stuart Menefy <stuart.menefy@st.com>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR target/13302
+ * sh.c (sh_build_builtin_va_list): Use (*lang_hooks.types.make_type).
+
+2003-12-05 Roger Sayle <roger@eyesopen.com>
+
+ * dojump.c (do_jump): If the expression being compared against
+ zero, is the subreg of a promoted variable, perform the comparison
+ in the promoted mode.
+ * simplify-rtx.c (simplify_unary_operation): Optimize sign and
+ zero-extensions of subregs of promoted variables where the
+ extension is identical to that used to promote the variable.
+
+2003-12-05 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/13256
+ * resource.h (enum mark_resource_type): Remove member MARK_DEST.
+ The only user changed as follows:
+ * resource.c (mark_set_resources) <case SET>: Always recurse for
+ SET_SRC (x).
+ <case SIGN_EXTRACT, case ZERO_EXTRACT>: Always recurse on
+ operands.
+ <case STRICT_LOW_PART>: Delete, deferring to default code.
+
+2003-12-05 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * stmt.c (expand_nl_goto_receiver): Copy hard register clobbers
+ and ASM_INPUT barrier from expand_builtin_setjmp_receiver.
+
+2003-12-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_call): Don't allow laziy binding
+ for n32 & n64 abicalls.
+
+2003-12-05 Richard Sandiford <rsandifo@redhat.com>
+
+ PR bootstrap/13145
+ * config/mips/mips.h (FIRST_PSEUDO_REGISTER): Adjust comment.
+ * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Add $fcall.
+ (mips_load_got): Always create a constant MEM.
+ (mips_expand_call): Use load_callsi and load_calldi.
+ * config/mips/mips.md (UNSPEC_LOAD_CALL, FAKE_CALL_REGNO): New consts.
+ (load_callsi, load_calldi): New patterns.
+
+2003-12-05 Peter Gerwinski <peter@gerwinski.de>
+
+ * tree.def (PLACEHOLDER_EXPR): Clarify commentary.
+
+2003-12-05 Steven Bosscher <stevenb@suse.de>
+
+ * config/d30v/d30v-protos.h , config/d30v/d30v.c,
+ config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
+ config/fr30/fr30-protos.h, config/fr30/fr30.c,
+ config/i370/i370-protos.h, config/i370/i370.c,
+ config/i960/i960-protos.h, config/i960/i960.c,
+ config/ip2k/ip2k-protos.h, config/ip2k/ip2k.c,
+ config/m32r/m32r-protos.h, config/m32r/m32r.c,
+ config/mn10300/mn10300-protos.h, config/mn10300/mn10300.c,
+ config/ns32k/ns32k-protos.h, config/ns32k/ns32k.c:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-12-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/extend.texi (Constructing Calls): Add warning about
+ the limitations of the functions.
+
+2003-12-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/11151
+ * function.h (struct function): New field 'x_naked_return_label'.
+ * function.c (free_after_compilation): Set it to NULL.
+ (expand_function_end): Emit 'naked_return_label' if it exists.
+ * rtl.h (expand_naked_return): Declare.
+ * stmt.c (expand_naked_return): New function to generate a
+ jump to 'naked_return_label'.
+ * builtins.c (expand_builtin_return): Call expand_naked_return
+ instead of expand_null_return.
+ * config/sparc/sparc.md (untyped_return): Likewise.
+
+2003-12-04 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/11322
+ * config/sh/netbsd-elf.h (NO_PROFILE_COUNTERS): Define.
+
+ PR target/12467
+ * config/rs6000/altivec.md (altivec_vmsummbm): Fix typo.
+
+2003-12-04 Stuart Hastings <stuart@apple.com>
+
+ * rs6000.c (output_call, macho_branch_islands,
+ add_compiler_branch_island, no_previous_def, get_previous_label)
+ Revisions of xx_stub functions for branch islands,
+ add -fPIC support for Darwin.
+ * rs6000-protos.h (output_call) Prototype.
+ * rs6000.md Use output_call.
+ * invoke.texi Explain Darwin semantics of -longcall.
+ * testsuite/gcc.dg/darwin-abi-1.c Revise testcase for -longcall/jbsr.
+
+2003-12-04 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (addqi3_carry): Use q not r constraints.
+ (subqi3_carry): Likewise.
+
+2003-12-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR optimization/13260
+ * sh-protos.h (sh_expand_t_scc): Declare.
+ * sh.h (PREDICATE_CODES): Add cmpsi_operand.
+ * sh.c (cmpsi_operand, sh_expand_t_scc): New functions.
+ * sh.md (cmpsi): Use cmpsi_operand. If T_REG is compared to
+ something that is not a CONST_INT, copy it into a pseudo register.
+ (subc): Fix description of new T value.
+ (slt, sgt, sge, sgtu): Don't clobber T after rtl generation is over.
+ (sltu, sleu, sgeu): Likewise.
+ (seq, sne): Likewise. Use sh_expand_t_scc.
+
+2003-12-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Generalize the CONFIG_HEADERS pattern under which
+ we stamp cstamp-h.
+ * configure: Regenerate.
+
+ * configure.in: Pull AC_CHECK_HEADER call out of shell if statement
+ to avoid trouble when updating to autoconf 2.5x.
+ * configure: Regenerate (with autoconf 2.13 still).
+
+2003-12-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (truncdiqi2): Use andi opcode for immediate.
+ (reload_outdf+1,reload_outdf+2): Remove constraints.
+ (movv16sf_i): Fxi multiplier for SUBREG_BYTE.
+ (movv8qi_i+2): Zero-extend low byte before adding it to high byte.
+ (fipr, ftrv): Add .s suffix to opcode.
+
+2003-12-04 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/13186
+
+ Revert all of the following patch, except the addition of
+ hook_bool_machine_mode_true:
+
+ 2003-11-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (targhooks.o, reload.o): Update dependencies.
+ (GTFILES): Add targhooks.c.
+ (gt-targhooks.h): New rule; depend on s-gtype.
+ * target.h (direct_pool_load_p): New hook.
+ * target-def.h (TARGET_DIRECT_POOL_LOAD_P): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_direct_pool_load_p): Declare.
+ (hook_bool_machine_mode_true): Declare.
+ * targhooks.c: Include insn-config.h, recog.h, ggc.h and
+ gt-targhooks.h.
+ (pool_symbol): New variable.
+ (default_direct_pool_load_p): New function.
+ (hook_bool_machine_mode_true): New function.
+ * reload.c: Include target.h.
+ (find_reloads): If an alternative will force a constant into memory,
+ count an extra reload if constant pool symbols are not valid
+ addresses. If an alternative uses memory to move values between
+ registers, count the move as two reloads rather than one.
+ * config/s390/s390.c (TARGET_DIRECT_POOL_LOAD_P): Define.
+ * doc/tm.texi (TARGET_DIRECT_POOL_LOAD_P): Document.
+
+2003-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/hpux.h (TARGET_HAVE_TLS): Define it to false.
+ * config/ia64/ia64.h (TARGET_HAVE_TLS): Define it to true if
+ HAVE_AS_TLS is true.
+ * config/ia64/ia64.c (TARGET_HAVE_TLS): Do not define it.
+
+2003-12-03 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (init_spec): Pass -lunwind to init_gcc_specs in eh_name.
+
+ * gcc-page.c (extra_order_size_tab): Correct comment.
+
+2003-12-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (push): Call gen_push_h8300hs_advanced
+ instead of gen_push_h8300hs.
+ (pop): Call gen_pop_h8300hs_advanced instead of
+ gen_pop_h8300hs.
+ * config/h8300/h8300.h (TRAMPOLINE_SIZE): Use Pmode.
+ * config/h8300/h8300.md (*tablejump_h8300hs_advanced):
+ Tighten the predicate.
+ (*tablejump_h8300hs_normal): Tighten the predicate.
+ (push_h8300hs): Change to
+ push_h8300hs_advanced.
+ (pop_h8300hs): Change to pop_h8300hs_advanced.
+
+2003-12-03 Eric Christopher <echristo@redhat.com>
+
+ * rtl.c: Fix typo.
+ * config/mips/mips.h: Ditto. Fix formatting.
+
+2003-12-04 Ben Elliston <bje@wasabisystems.com>
+
+ * future.options: Remove. Move to gnu.org web pages.
+
+2003-12-03 Eric Christopher <echristo@redhat.com>
+
+ * c-parse.in (c_in_iteration_stmt, c_in_case_stmt): Move
+ from here...
+ * c-tree.h: to here.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+
+ PR optimization/12324
+ * toplev.c (rest_of_decl_compilation): Do not deffer when compiling
+ in unit-at-a-time mode.
+
+2003-12-03 Jakub Jelinek <jakub@redhat.com>
+
+ * expr.c (store_constructor): Only set RTX_UNCHANGING_P for
+ read-only field if cleared is 0.
+
+2003-12-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Mark obsolete targets for GCC 3.4.
+
+2003-12-03 Zack Weinberg <zack@codesourcery.com>
+
+ * aclocal.m4 (AM_ICONV): Add explicit check for iconv.h.
+ * config.in, configure.in: Regenerate.
+ * cpphash.h: Check both HAVE_ICONV and HAVE_ICONV_H before
+ including iconv.h.
+
+2003-12-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/11229
+ * cse.c (cse_insn): Set classp using src_const_elt if
+ src_eqv_elt is NULL.
+
+2003-12-03 Richard Earnshaw <rearnsha@arm.com>
+
+ * gcse.c (reg_clear_last_set): New function.
+ (reg_set_info): If data is non-null, treat it as an sbitmap of
+ registers, set the bit for the register being set.
+ (compute_store_table): Allocate last_set_in with xcalloc. Do not
+ memset this array on each iteration. Pass reg_set_in_block[bb->index]
+ to note_stores while computing last_set_in instead of scanning
+ last_set_in after the first pass through the insns.
+ Clear last_set_in using reg_clear_last_set instead of explicitly
+ rescanning after each insn. If checking is enabled, assert that
+ last_set_in is completely zeroed after each bb has been processed.
+
+2003-12-02 Geoffrey Keating <geoffk@geoffk.org>
+
+ * df.c (df_uses_record) <MEM>: The argument of a MEM is read-only,
+ never read-write.
+ <REG>: Delete incorrect comment.
+ <SET>: Remove 'use_flags' variable.
+
+2003-12-03 David Edelsohn <edelsohn@gnu.org>
+
+ * function.c (assign_parms): Make sure parm PARALLEL combined
+ in reg is composed of more than one object and the mode really
+ produces a reg.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Make it 64bit clean.
+
+2003-12-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_output_external): Replace checks for
+ specific builtin-in functions with a check for DECL_BUILTIN_IN.
+
+2003-12-02 Richard Henderson <rth@redhat.com>
+
+ * rtl.h (PUT_CODE, PUT_MODE): Remove ENUM_BITFIELD cast.
+ * tree.h (TREE_SET_CODE): Likewise.
+ * recog.h (struct insn_operand_data): Move const after ENUM_BITFIELD.
+
+2003-12-02 Ben Elliston <bje@wasabisystems.com>
+
+ * dbxstclass.h: Rename from this ..
+ * xcoff.h: .. to this.
+ * xcoffout.c: Include xcoff.h.
+
+2003-12-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (GCC_CFLAGS): Add -Wold-style-definition.
+
+2003-12-01 James Lemke <jim@wasabisystems.com>
+
+ * config/arm/arm.c (arm_rtx_costs): Improve for xscale multiply.
+
+2003-12-01 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11634
+ * recog.c (split_insn): Factor test of INSN_P and handling of
+ set_noop_p out of here into the two callers.
+ (split_all_insns): Add INSN_P test and set_noop_p handling here.
+ If deleting a no-op set after reload that has a REG_UNUSED note,
+ mark the basic block as changed and recalculate life information.
+ (split_all_insns_noflow): Add INSN_P test and set_noop_p handling
+ here.
+
+2003-12-01 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12322
+ * gcse.c (struct ls_expr): Change type of hash_index from int to
+ unsigned int.
+ (hash_expr): Document hash_table_size parameter and wrap long line.
+ (ldst_entry): Calculate expression's hash_index and record in ptr.
+ (trim_ld_motion_mems): Use hash_index to search a single bucket
+ instead of scanning the entire hash_table. Remove the "del" local
+ variable and use the equivalent "expr == 0" instead. Change last
+ to be a pointer to the pointer to the current element, to simplify
+ and speed-up deleting from a linked list.
+
+2003-12-01 James E Wilson <wilson@specifixinc.com>
+
+ * doc/contrib.texi: Update David Mosberger.
+
+ * doc/c-tree.texi (CONSTRUCTOR): Clarify element order and handling
+ of missing fields.
+
+ PR target/8407
+ * config/ia64/ia64.c (ia64_function_arg): For single-reg HFA, call
+ gen_rtx_REG to create new reg with argument mode.
+
+2003-12-01 Steven Bosscher <stevenb@suse.de>
+
+ * ggc.h (struct alloc_zone): Move forward declaration up.
+ (new_ggc_zone): New function prototype.
+ (destroy_ggc_zone): Ditto.
+ * ggc-simple.c (new_ggc_zone): New function, does nothing.
+ (destroy_ggc_zone): Ditto.
+ * ggc-page.c (new_ggc_zone): New function, does nothing.
+ (destroy_ggc_zone): Ditto.
+ * ggc-zone.c (struct page_entry): Fix comment.
+ (ggc_alloc_typed): Use a switch statement instead of ifs.
+ (new_ggc_zone): New function to set up a new GC zone.
+ (destroy_ggc_zone): New function to remove a GC zone.
+ init_ggc): Use new_ggc_zone to set up the default zones.
+ (ggc_collect): Walk a list of zones, instead of just the
+ default zones. Report statistics using the zone name.
+
+2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * unroll.c (find_splittable_givs): Add missing extend_value_for_giv.
+
+2003-12-01 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12628
+ * toplev.c (rest_of_handle_jump_bypass): Call reg_scan.
+ * regclass.c (reg_scan): Include allocate_reg_info time in
+ TV_REG_SCAN. Minor clean-ups.
+ (reg_scan_update): Minor clean-ups.
+
+2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.gcc (s390x-ibm-tpf*): Add extra_parts.
+
+2003-12-01 James E Wilson <wilson@specifixinc.com>
+
+ * config/ia64/ia64.h (FUNCTION_ARG_REGNO_P): Use AR_REG_FIRST not
+ GR_ARG_FIRST.
+
+2003-12-01 Zack Weinberg <zack@codesourcery.com>
+
+ * common.opt: Remove -fgnu-linker.
+ * flags.h: Remove flag_gnu_linker.
+ * opts.c: Don't handle OPT_fgnu_linker.
+ * toplev.c: Don't initialize flag_gnu_linker.
+ Remove gnu-linker entry from f_options.
+ * config/dsp16xx/dsp16xx.h (OPTIMIZATION_OPTIONS):
+ Don't reset flag_gnu_linker.
+ * config/mips/mips.c (override_options): Likewise.
+ * doc/invoke.texi: Remove all mention of -fgnu-linker.
+
+2003-12-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * ggc-zone.c (ggc_pch_write_object): Calculate object size using
+ ggc_get_size (which accounts for large objects properly).
+
+2003-12-01 Jeff Sturm <jsturm@one-point.com>
+
+ PR optimization/13024
+ * toplev.c (rest_of_handle_new_regalloc): Remove rebuild_notes
+ parameter.
+ (rest_of_handle_old_regalloc): Likewise. Add rebuild_notes
+ declaration. Rebuild jump labels following local_alloc if necessary.
+ (rest_of_compilation): Remove rebuild_label_notes_after_reload
+ declaration. Don't pass rebuild_notes parameter to
+ rest_of_handle_new_regalloc and rest_of_handle_old_regalloc.
+ Don't rebuild jump labels.
+
+2003-12-01 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-12-01 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * builtins.c (expand_builtin_longjmp): Added two memory clobbers.
+
+2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads_address): Split addresses of type
+ (plus (plus (reg) (reg)) (const_int)) only if one register
+ is either a valid base register or else one of the stack
+ frame related registers (sp/fp/ap).
+
+2003-12-01 Steven Bosscher <stevenb@suse.de>
+
+ * function.c (update_epilogue_consts): Don't use PARAMS.
+ * rtl.h (web_main): Ditto.
+ * target.h (is_costly_dependence): Ditto
+
+2003-12-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/7847
+ * expr.c (expand_expr) [normal_inner_ref]: When 'offset' is non-zero,
+ do not recheck that 'op0' is a MEM. Move comment. When testing for
+ unaligned objects, take also into account the alignment of 'op0' and
+ 'mode1' if 'op0' is a MEM.
+
+2003-12-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * doc/c-tree.texi (Function Bodies): Update HANDLER documentation.
+
+2003-12-01 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/install.texi: Note that fastjar is built with automake 1.7.x
+ and autoconf 2.57.
+
+2003-12-01 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Test
+ target_flags directly rather than using TARGET_* defines.
+
+2003-11-30 Ben Elliston <bje@wasabisystems.com>
+
+ * doschk.c: Remove.
+
+2003-11-30 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12727
+ * config/mips/mips.c (mips_save_reg): Fix frame information for sdc1
+ on 32-bit big-endian targets.
+
+2003-11-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genemit.c (register_constraints): Remove.
+
+2003-11-30 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("tmdi_reg", "tmsi_reg", "*movdi_64", "*movdi_31",
+ "iordi3"): Insns now use multiple letter constraints.
+ ("*movdi_lhi", "*movdi_lli", "*movdi_lay"): Insns deleted. They are now
+ covered by "*movdi_64".
+ ("*movsi_lhi", "*movsi_lli", "*movsi_lay"): Insns deleted. They are now
+ covered by "*movsi_zarch" and "*movsi_esa".
+ ("*movsi_zarch", "*movsi_!zarch"): New insns.
+ ("*llgt_sisi_split", "*llgt_didi_split"): Insns deleted. Now covered
+ by "*andsi3_zarch" and "anddi3".
+ ("*anddi3_ni"): Insn merged with "anddi3".
+ ("*andsi3_ni"): Insn merged with "*andsi3_zarch".
+ ("*andsi3_zarch", "*andsi3_esa"): New insns.
+ ("*iordi3_oi"): Insn merged with "iordi3".
+ ("*iorsi3_oi"): Insn merged with "*iorsi3_zarch".
+ ("*iorsi3_zarch", "*iorsi3_esa"): New insns.
+
+ * config/s390/s390.c (s390_single_qi, s390_single_hi): Functions
+ merged to s390_single_part.
+ (s390_single_part): New function.
+ NOTE: Semantics have changed a bit. Now the value of the part must
+ be different from the others to get a non-negative return value.
+ (s390_extract_qi, s390_extract_hi): Functions merged to
+ s390_extract_part.
+ (s390_extract_part, s390_extra_constraint_str,
+ s390_const_ok_for_constraint_p): New functions. The L constraint got a
+ new meaning and the N constraint was added as a multiple letter
+ constraint.
+ (s390_extra_constraint): Function deleted.
+ (print_operand): New output modifier 'i' and 'j' added.
+ All uses of CONST_OK_FOR_LETTER_P were replaced by
+ CONST_OK_FOR_CONSTRAINT_P.
+
+ * config/s390/s390-protos.h: Function prototypes adapted.
+ * doc/md.texi: Documentation for new constraint letters added.
+
+2003-11-30 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.in ($(DESTDIR)$(infodir)/%.info): Fix missing semicolon.
+
+2003-11-29 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (init_spec): Pass -lunwind to init_gcc_specs in eh_name
+ instead of in shared_name.
+
+ * final.c (final_start_function): Delete code for NON_SAVING_SETJMP.
+ * reload1.c (reload): Re-add it here.
+
+2003-11-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_elf_section_type_flags): Don't
+ set SECTION_WRITE on TARGET_RELOCATABLE.
+
+2003-11-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (LIBCALL_VALUE): Use R0_REG.
+
+2003-11-28 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (MOTOROLA): Move from here...
+ * config/m68k/m68k.h (MOTOROLA): ... to here.
+ (OUTPUT_JUMP): Use do {...} while (0).
+ * config/m68k/m68k.md: Replace #ifdef MOTOROLA with C statements.
+
+2003-11-28 Gunther Nikl <gni@gecko.de>
+
+ * config.gcc (m68020-*-elf*, m68k-*-elf*, m68010-*-netbsdelf*,
+ m68k*-*-netbsdelf*, m68k-*-rtems*): Add tm_defines containing
+ MOTOROLA and USE_GAS.
+ * config/m68k/rtemself.h (MOTOROLA): Delete.
+ * config/m68k/netbsd-elf.h (MOTOROLA, USE_GAS): Delete.
+ * config/m68k/m68kelf.h (MOTOROLA, USE_GAS, SGS_CMP_ORDER): Delete.
+
+2003-11-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (WORDS_BIG_ENDIAN): Update the comment.
+
+2003-11-29 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (install-info): Install gccinstall.info too.
+
+2003-11-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("cmpint_di"): Fix incorrect instruction lengths.
+
+2003-11-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movhi"): Do not emit extender pattern
+ when loading from a (MEM (ADDRESSOF ...)).
+ ("movqi"): Likewise.
+
+2003-11-29 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/10333
+ * c-parse.in (typespec_reserved_nonattr): Reject typeof on
+ bit-fields.
+
+2003-11-29 Richard Sandiford <rsandifo@redhat.com>
+
+ * stmt.c (expand_asm_operands): Check whether force_const_mem
+ succeeded.
+
+2003-11-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/gnu.h (HURD_TARGET_OS_CPP_BUILTINS): New.
+ * config/linux.h (LINUX_TARGET_OS_CPP_BUILTINS): New.
+
+ * config/alpha/gnu.h, config/alpha/linux.h,
+ config/arm/linux-elf.h, config/cris/cris.h, config/cris/linux.h,
+ config/i370/linux.h, config/i386/gnu.h, config/i386/i386.h,
+ config/i386/linux-aout.h, config/i386/linux.h,
+ config/i386/linux64.h, config/ia64/linux.h, config/m68k/linux.h,
+ config/m68k/uclinux.h, config/mips/linux.h,
+ config/mn10300/linux.h, config/pa/pa-linux.h,
+ config/rs6000/sysv4.h, config/s390/linux.h, config/sh/linux.h,
+ config/sparc/linux.h, config/sparc/linux64.h,
+ config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Use
+ HURD_TARGET_OS_CPP_BUILTINS/LINUX_TARGET_OS_CPP_BUILTINS or ensure
+ all necessary assertions are included.
+
+2003-11-28 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (set_used_flags): New.
+ (verify_rtx_sharing, verify_rtl_sharing): New.
+ (unshare_all_rtl_1): Rename to....
+ (unshare_all_rtl_in_chain): ... this one; make static.
+ (copy_rtx_if_shared): LABEL_REF chan be shared.
+ * ifcvt.c (unshare_ifcvt_sequence): New.
+ (noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
+ noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask,
+ noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax,
+ noce_try_abs, noce_process_if_block, find_cond_trap
+ * rtl.h (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
+ Declare.
+
+2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix a comment typo.
+
+2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*movsf_h8300h): Change to
+ *movsf_h8300hs.
+ (addsi_h8300): Change to *addsi_h8300.
+ (addsi_h8300h): Change to *addsi_h8300hs.
+ (subsi3_h8300): Change to *subsi3_h8300.
+ (subsi3_h8300h): Change to *subsi3_h8300hs.
+ (neghi2_h8300h): Change to *neghi2_h8300hs.
+ (negsi2_h8300h): Change to *negsi2_h8300hs.
+
+2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*subhi3_h8300): Remove '&' from the
+ constraint.
+ (*subhi3_h8300hs): Likewise.
+
+2003-11-28 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (MASK_MFCRF): New.
+ (TARGET_MFCRF): Test target_flags, not processor type.
+ (TARGET_SWITCHES): Add mfcrf and no-mfcrf.
+ Change Don't to Do not.
+ * config/rs6000/rs6000.c (processors_target_table): Add MASK_MFCRF
+ to power4, 970, G5.
+
+2003-11-27 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cse.c (cse_set_around_loop): When changing a constant load
+ to a register -register copy, add a REG_EQUAL note.
+
+2003-11-27 Randolph Chung <tausq@debian.org>
+ John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (hppa_profile_hook): Split gen_call_profiler into separate
+ insns. Use the regular call expander for the call to the profiler.
+ * pa.md (call_profiler): Delete.
+ (load_offset_label_address): New insn to load the address of the
+ current function for the profiler.
+ (lcla1, lcla2): New insns to output a code label and load its address.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * final.c (final_scan_insn): Remove commented-out code.
+
+2003-11-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Remove ADAC reference and make accurate.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (FUNCTION_VALUE): Use R0_REG.
+ (FUNCTION_VALUE_REGNO_P): Likewise.
+ * config/h8300/h8300.md: Define R0_REG.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Fix formatting.
+ * config/h8300/h8300.md: Likewise.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (ELIMINABLE_REGS): Update a comment.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Give names to anonymous insns.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (extendqisi2): Remove constraints.
+
+2003-11-27 Gunther Nikl <gni@gecko.de>
+
+ * doc/tm.texi (SYSROOT_HEADERS_SUFFIX_SPEC): Fix typo.
+
+2003-11-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13041
+ * final.c (frame_pointer_needed): Fix comment.
+ * reload1.c (reload): Decrease alignment of the frame
+ pointer if it was used for register allocation.
+
+2003-11-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12900
+ * reg-stack (move_for_stack_reg): New prototype. Return
+ whether a control flow insn was deleted.
+ (subst_stack_regs_pat): Likewise, using the information provided
+ by move_for_stack_reg.
+ (subst_stack_regs): Likewise, using the information provided
+ by subst_stack_regs_pat.
+ (convert_regs_1): Record whether a control flow insn was deleted,
+ using the information provided by subst_stack_regs. Purge dead
+ edges only if a control flow insn was deleted.
+
+2003-11-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/8028
+ PR middle-end/9890
+ PR middle-end/11151
+ PR middle-end/12210
+ PR middle-end/12503
+ PR middle-end/12692
+ * builtins.c (expand_builtin_apply): Use virtual_outgoing_args_rtx
+ as the base address to copy the memory arguments to.
+
+2003-11-26 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (ASM_OUTPUT_DEF_FROM_DECLS): Declare
+ function aliases as functions.
+
+2003-11-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * aclocal.m4 (gcc_AC_PROG_GNAT): Rewrite to account for removal
+ of ADAC.
+ * configure: Regenerate.
+
+ * Makefile.in: Remove references to ADAC.
+
+ * configure.in: Remove check for whether ${ADAC} accepts -Wno-long-long.
+ * configure: Regenerate.
+
+2003-11-26 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Olivier Hainque <hainque@act-europe.fr>
+
+ PR target/6466
+ * config/sparc/sparc-protos.h (compute_frame_size): New prototype.
+ (sparc_flat_compute_frame_size): Likewise.
+ (sparc_flat_save_restore): Move prototype...
+ * config/sparc/sparc.c (sparc_flat_save_restore): ...here.
+ (save_regs): New prototype.
+ (build_big_number): Likewise.
+ (apparent_fsize): Change type to HOST_WIDE_INT.
+ (actual_fsize): Likewise.
+ (frame_base_offset): Likewise.
+ (build_big_number): Add support for HOST_BITS_PER_WIDE_INT == 64.
+ Change string descriptor to HOST_WIDE_INT_PRINT_DEC.
+ [TARGET_ARCH64]: Use the sequence of sparc_emit_set_const64_longway
+ to load a 64-bit constant.
+ (sparc_nonflat_function_prologue): Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Change offset type to HOST_WIDE_INT.
+ (output_restore_regs): Change offset type to HOST_WIDE_INT.
+ (sparc_nonflat_function_epilogue): Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Use build_big_number.
+ (output_sibcall): Change size type to HOST_WIDE_INT. Use
+ build_big_number. Change string descriptor to HOST_WIDE_INT_PRINT_DEC.
+ (sparc_frame_info): Change types for several components.
+ (sparc_flat_compute_frame_size): Update types according to previous
+ change.
+ (sparc_flat_function_prologue): Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Change offset type to int. Use
+ build_big_number.
+ (sparc_flat_function_epilogue): Change offset type to int.
+ Rename 'size1' into 'reg_offset1'. Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Use build_big_number. Change big number
+ limit to 4096 instead of 4095.
+
+ * config/sparc/sparc.c (mems_ok_for_ldd_peep): Change offset type to
+ HOST_WIDE_INT.
+
+2003-11-24 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * function.c: Make outer_function-chain external.
+ * function.h: Likewise.
+
+2003-11-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config.gcc (mips-sgi-irix6*): Add t-iris6gld to tmake_file when
+ using GNU ld.
+ * config/mips/iris6.h (IRIX6_STARTFILE_SPEC): New, taking the
+ whole of the previous STARTFILE_SPEC except crtbegin.o%s.
+ (IRIX6_ENDFILE_SPEC): Likewise ENDFILE_SPEC and crtend.o%s.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Define in terms of the above.
+ (SUBTARGET_EXTRA_SPECS): Define.
+ * config/mips/iris6gld.h (LINK_SPEC): Change -init function
+ to __gcc_init and -fini function to __gcc_fini.
+ (STARTFILE_SPEC): Redefine, including irix6-crti.o before crtbegin.o.
+ (ENDFILE_SPEC): Likewise, including irix6-crtn.o after crtend.o.
+ (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Define.
+ * config/mips/t-iris6gld,
+ * config/mips/irix6-crti.asm,
+ * config/mips/irix6-crtn.asm: New files.
+
+2003-11-24 Eric Christopher <echristo@redhat.com>
+
+ PR C/13014
+ * c-decl.c (c_in_iteration_stmt, c_in_case_stmt): New.
+ (start_function): Use.
+ (c_push_function_context): Ditto.
+ (c-pop_function_context): Ditto.
+ (language_function): Move...
+ * c-tree.h: ... here. Add x_in_iteration_stmt, and
+ x_in_case_stmt.
+ * c-parse.in (do_stmt_start, select_or_iter_stmt, stmt): Use
+ c_in_iteration_stmt, c_in_case_stmt for parser state. Move
+ check for valid break or continue statment here...
+ * c-semantics.c (genrtl_break_stmt, genrtl_continue_stmt): From
+ here. Change original errors to abort.
+
+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 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (tablejump_h8300): Change to
+ *tablejump_h8300.
+ (tablejump_h8300h): Change to *tablejump_h8300hs_advanced.
+ (tablejump_normal_mode): Change to *tablejump_h8300hs_normal.
+ (indirect_jump_h8300): Change to *indirect_jump_h8300.
+ (indirect_jump_h8300h): Change to
+ *indirect_jump_h8300hs_advanced.
+ (indirect_jump_normal_mode): Change to
+ *indirect_jump_h8300hs_normal.
+
+2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Remove constraints from expanders.
+
+2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: (stm_h8300s_2): Change the name to
+ stm_h8300s_2_advanced.
+ (stm_h8300s_2_normal): New.
+ (stm_h8300s_2): Likewise.
+ (stm_h8300s_3): Change the name to stm_h8300s_3_advanced.
+ (stm_h8300s_3_normal): New.
+ (stm_h8300s_3): Likewise.
+ (stm_h8300s_4): Change the name to stm_h8300s_4_advanced.
+ (stm_h8300s_4_normal): New.
+ (stm_h8300s_4): Likewise.
+ (ldm_h8300s_2): Change the name to ldm_h8300s_2_advanced.
+ (ldm_h8300s_2_normal): New.
+ (ldm_h8300s_2): Likewise.
+ (ldm_h8300s_3): Change the name to ldm_h8300s_3_advanced.
+ (ldm_h8300s_3_normal): New.
+ (ldm_h8300s_3): Likewise.
+ (ldm_h8300s_4): Change the name to ldm_h8300s_4_advanced.
+ (ldm_h8300s_4_normal): New.
+ (ldm_h8300s_4): Likewise.
+ (two peephole2's): Enable only with !TARGET_NORMAL_MODE.
+ (two peephole2's): New.
+
+2003-11-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * genattrtab.c (simplify_cond): Update indices correctly.
+ (attr_alt_subset_p, attr_alt_subset_of_compl_p, attr_alt_intersection,
+ attr_alt_union, attr_alt_complement, attr_alt_bit_p, mk_attr_alt): New.
+ (check_attr_test, encode_units_mask, compute_alternative_mask,
+ make_alternative_compare, simplify_and_tree,
+ attr_rtx_cost, simplify_test_exp, gen_attr,
+ write_test_expr, walk_attr_value): Handle EQ_ATTR_ALT.
+ * rtl.def (EQ_ATTR_ALT): New.
+
+2003-11-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * genattrtab.c (strcmp_check, DEF_ATTR_STRING): New macros.
+ (length_str, delay_type_str, delay_1_0_str, num_delay_slots_str):
+ New variables.
+ (main): Initialize them.
+ (find_attr): Canonicalize the attribute name string.
+ (attr_rtx_1, copy_boolean, expand_delays, gen_unit): Always canonicalize
+ string arguments.
+ (attr_printf, attr_eq): Use DEF_ATTR_STRING.
+ (check_attr_test, check_attr_value, make_length_attrs,
+ write_length_unit_log, simplify_by_exploding, gen_attr,
+ write_test_expr, write_attr_value, write_eligible_delay,
+ write_complex_function, make_internal_attr,
+ write_const_num_delay_slots): Changed due to change of type of
+ find_attr.
+ (fill_attr, evaluate_eq_attr, simplify_and_tree,
+ attr_rtx_cost, simplify_by_exploding, walk_attr_value): Use
+ strcmp_check.
+
+2003-11-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/13122
+ * config/h8300/h8300.c (push): Call push_h8300hs_normal in
+ normal mode.
+ (pop): Call pop_h8300hs_normal in normal mode.
+ * config/h8300/h8300.md: Likewise.
+ (pushqi1_h8300hs_normal): New.
+ (pushqi1): Call pushqi1_h8300hs_normal in normal mode.
+ (pushhi1_h8300hs_normal): New.
+ (pushhi1): Call pushhi1_h8300hs_normal in normal mode.
+ (push_h8300hs_normal): New.
+ (pop_h8300hs_normal): Likewise.
+
+2003-11-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * genattrtab.c (count_sub_rtxs): Removed.
+
+2003-11-23 Richard Earnshaw <rearnsha@arm.com>
+
+ * recog.c (preprocess_constraints): Only zero those elements of
+ recog_op_alt that are needed for this insn.
+ * arm.c (note_invalid_constants): A function can't contain invalid
+ constants if it has no constraints.
+
+2003-11-22 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Pass __float128 in memory.
+ (ix86_return_in_memory): Likewise.
+ (ix86_libcall_value): Likewsie.
+
+2003-11-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (dosize): Convert to ISO-C.
+
+2003-11-22 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * flow.c (update_life_info): Amend comment about when a register
+ can become dead.
+
+2003-11-21 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/.cvsignore: Delete.
+
+2003-11-21 Daniel Berlin <dberlin@dberlin.org>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * dwarf2out.c (add_location_or_const_value_attribute): Add support
+ for PARALLEL.
+
+2003-11-21 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/t-iris6 (CRTSTUFF_T_CFLAGS): Add -Wno-error.
+ (TARGET_LIBGCC2_CFLAGS): Define.
+
+ * crtstuff.c [HAS_INIT_SECTION] (__do_global_dtors): Declare.
+ (__do_global_ctors): Likewise.
+
+2003-11-21 Mark Wielaard <mark@klomp.org>
+
+ * doc/invoke.texi (-O2): Doesn't enable -fweb.
+
+2003-11-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Mention dV and dZ.
+
+2003-11-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Update dump file names.
+ Remove de, dW, and dX.
+
+2003-11-20 James E Wilson <wilson@specifixinc.com>
+
+ PR c/13133
+ * reload1.c (reload): Delete special handling for setjmp.
+
+2003-11-21 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * mklibgcc.in: Evaluate shlib_slibdir_qual during link
+ step too.
+ * config/t-slibgcc-darwin: Adjust install path.
+ * config/rs6000/t-darwin: Revert multilib matches since
+ it is not used on darwin.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * ssa.c, ssa-dce.c, ssa-ccp.c: Remove files.
+ * Makefile.in (OBJS-common, GTFILES): Don't reference them.
+ (gtype-desc.o, toplev.o, flow.o): Remove ssa.h.
+ (ssa.o, ssa-dce.o, ssa-ccp.o): Remove.
+ * flow.c: Don't include ssa.h.
+ (set_phi_alternative_reg): Remove.
+ (calculate_global_regs_live): Don't call it.
+ (mark_used_regs): Don't handle PHI.
+ * gengtype.c (open_base_files): Don't reference ssa.h.
+ * rtl.def (PHI): Remove.
+ * timevar.def (TV_TO_SSA, TV_SSA_CCP, TV_SSA_DCE, TV_FROM_SSA): Kill.
+ * common.opt: Remove -fssa, -fssa-ccp, -fssa-dce.
+ * opts.c (common_handle_option): Likewise.
+ * toplev.c (f_options): Likewise.
+ (DFI_ssa, DFI_ssa_ccp, DFI_ssa_dce, DFI_ussa): Remove.
+ (dump_file): Update to match.
+ (flag_ssa, flag_ssa_ccp, flag_ssa_dce): Remove.
+ (rest_of_handle_ssa): Remove.
+ (rest_of_compilation): Don't call it.
+ * toplev.h (flag_ssa, flag_ssa_dce, flag_ssa_ccp): Remove.
+ * doc/invoke.texi: Remove -fssa, -fssa-ccp, -fssa-dce.
+ * doc/passes.texi (SSA optimizations): Remove.
+
+2003-11-20 Bob Wilson <bob.wilson@acm.org>
+
+ * configure.in: Add xtensa-*-* targets to test for dwarf2 debug_line.
+ * configure: Regenerate.
+
+2003-11-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (Makefile): Pass along CONFIG_SHELL.
+
+2003-11-20 David Mosberger <davidm@hpl.hp.com>
+
+ * config/t-libunwind (LIB2ADDEH): Add unwind-c.c.
+ (SHLIB_LC): Define.
+ * unwind-libunwind.c (_Unwind_GetCFA): Implement.
+ (_Unwind_GetBSP) [UNW_TARGET_IA64]: New function.
+
+2003-11-20 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * calls.c (expand_call): Allocate new temp in pass1.
+ (store_one_arg): If PARALLEL, calculate excess using mode size of
+ rtvec elt.
+ * expr.c (emit_push_insn): If PARALLEL, calculate offset using
+ mode size of rtvec elt.
+ * function.c (assign_parms): Use parm in register, if available.
+
+2003-11-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (MOVP): Remove.
+ (ADDP): Likewise.
+ (CMPP): Likewise.
+
+2003-11-20 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (use_return_insn): New argument, SIBLING. Support returning
+ with a single instruction if the stack has been decremented by 4
+ and we have a frame pointer. Update all callers.
+ (output_return_instruction): Likewise.
+ (arm_output_epilogue): Change argument to SIBLING. Calculate
+ really_return from the new argument. Update all callers.
+ * arm.h (USE_RETURN_INSN): Pass NULL for the sibling.
+ * arm.md (sibcall_epilogue): Call use_return_insn directly, and
+ pass the sibling call.
+ * arm-protos.h (use_return_insn, arm_output_epilogue): Update
+ prototypes.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in (extraclean): Delete.
+ * configure.in (target_list): Remove extraclean.
+ * configure: Regenerate.
+ * doc/makefile.texi, doc/sourcebuild.texi: Update.
+ * objc/Make-lang.in (objc.extraclean): Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in (lang_checks): Add.
+ (check-c++, check-f77, check-java, check-g++, check-g77,
+ check-objc): Remove hardcoded targets.
+ * doc/sourcebuild.texi: Document testsuite hooks.
+ * objc/Make-lang.in (check-objc, lang_checks): Add.
+
+2003-11-19 Scott Snyder <snyder@fnal.gov>
+
+ PR target/13131
+ * dwarf2out.c (gen_array_type_die): DW_AT_declaration should be a
+ flag, not a constant.
+
+2003-11-19 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/arc/arc-protos.h: Update to C90 prototypes.
+ * config/arc/arc.c: Likewise.
+ * config/arc/initfini.c: Likewise.
+
+2003-11-19 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * stmt.c (expand_goto): Memory clobbers added.
+
+2003-11-19 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * reload.c (find_reloads): Added missing type casts.
+
+2003-11-19 James E Wilson <wilson@specifixinc.com>
+
+ * combine.c (sets_function_arg_p): Delete unused function.
+
+2003-11-19 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Revert 2 previous checkins.
+
+2003-11-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cpptrad.c (_cpp_scan_out_logical_line): Improve test for
+ whether directive begins at the beginning of a line.
+
+2003-11-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_init_libfuncs): Correct ufix_optab entries.
+
+2003-11-19 Gerald Pfeifer <gp@suse.de>
+
+ * doc/install.texi (Specific): Remove information on old versions
+ of glibc versus old versions of GCC.
+
+2003-11-19 Richard SAndiford <rsandifo@redhat.com>
+
+ * emit-rtl.c (gen_lowpart): Don't force MEMs into a register unless
+ the register lowpart is a TRULY_NOOP_TRUNCATION.
+
+2003-11-19 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (print_reg): Handle QI and HI modes for
+ non Q regs.
+
+2003-11-19 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * config/config.gcc (powerpc-*-darwin*): Add libgcc build
+ specification file.
+ * config/t-slibgcc-darwin: New file, libgcc build specification.
+ * config/t-darwin: Add libgcc2 flag -fPIC.
+ * config/rs6000/t-darwin: Multilib matches float.
+ * libgcc-darwin.ver: New file, contains libgcc symbols.
+
+2003-11-18 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/ns32k/ns32k.h: Remove obsolete comment.
+
+2003-11-18 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11821
+ * config/arm/arm.c (arm_rtx_costs_1): Improve estimate of the code
+ size for calls to libgcc's div & mod subroutines when using -Os.
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (change_decl_assembler_name): Avoid bogus warnings.
+
+2003-11-18 Marc Espie <espie@openbsd.org>
+
+ * config/rs6000/sysv4.h: OpenBSD hooks.
+
+2003-11-18 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_expr): Don't look through constant arrays if
+ they don't bind locally.
+
+2003-11-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (convert_move): Use GET_MODE_PRECISION instead of bitsize
+ when seeing if truncation or extension.
+
+2003-11-17 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Fix previous change.
+
+2003-11-17 Scott Snyder <snyder@fnal.gov>
+
+ PR debug/11325
+ * dwarf2out.c (struct die_struct): Add die_definition field.
+ (add_AT_specification): New.
+ (gen_subprogram_die, gen_variable_die,
+ gen_struct_or_union_type_die): Use it.
+ (prune_unused_types_mark): If we're marking a forward declaration,
+ also mark the full definition, if it exists.
+
+2003-11-16 Nick Clifton <nickc@redhat.com>
+
+ * config/stormy16/stormy16.h (BUILD_VA_LIST_TYPE): Delete.
+ * config/stormy16/stormy16-protos.h (xstormy16_build_va_list):
+ Remove prototype.
+ * config/stormy16/stormy16.c (xstormy16_build_va_list): Rename
+ to xstormy16_build_builtin_va_list and make static.
+ (TARGET_BUILD_BUILTIN_VA_LIST): Define.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add the prototype for
+ same_cmp_following_p.
+ * config/h8300/h8300.c (same_cmp_following_p): New.
+ * config/h8300/h8300.md (peephole2): Use it.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Don't use REGNO when its operand is
+ not guaranteed to be a REG.
+
+2003-11-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (expr.o): Depend on $(TARGET_H).
+ * target.h (return_in_msb): New target hook.
+ * target-def.h (TARGET_RETURN_IN_MSB): New macro.
+ (TARGET_CALLS): Include it.
+ * calls.c (shift_returned_value): New function.
+ (expand_call): Use it.
+ * expr.c: Include target.h.
+ (copy_blkmode_from_reg): Check targetm.calls.return_in_msb when
+ deciding what padding is needed. Change the name of the local
+ padding variable from big_endian_correction to padding_correction.
+ * stmt.c (shift_return_value): New function.
+ (expand_return): Use it. Adjust memory->register copy in the same
+ way as copy_blkmode_from_reg. Only change the return register's
+ mode if it was originally BLKmode.
+ * doc/tm.texi (TARGET_RETURN_IN_MSB): Document.
+ * config/mips/mips.c (TARGET_RETURN_IN_MSB): Define.
+ (mips_fpr_return_fields): New, split out from mips_function_value.
+ (mips_return_in_msb, mips_return_fpr_pair): New functions.
+ (mips_function_value): Rework to use the functions above.
+ * config/mips/irix6-libc-compat.c: Delete.
+ * config/mips/t-iris6 (LIB2FUNCS_STATIC_EXTRA): Undefine.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi (--enable-checking): Update valgrind's URL.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix warnings by replacing -2147483648
+ with -2147483647 - 1.
+
+2003-11-16 Gerald Pfeifer <gerald@pfeifer.com>
+
+ Fix links in online manuals.
+ * doc/invoke.texi (H8/300 Options): @xref to ld, not ld.info.
+ (Precompiled Headers): @pxref to cpp, not cpp.info.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in, objc/Make-lang.in (objc.tags): Create TAGS.sub
+ files in each directory and TAGS files that include them for each
+ front end.
+
+2003-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divnorm): Store the sign in bit
+ 3 of S2L.
+ (modnorm): Likewise.
+ (exitdiv): Look at bit 3 of S2L only.
+
+2003-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (DO_GLOBAL_CTORS_BODY): Fix warnings.
+ (DO_GLOBAL_DTORS_BODY): Likewise.
+
+2003-11-15 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install.texi (Prerequisites): Refine documentation of
+ autoconf, automake and perl requirements. Document required
+ gettext version.
+
+<2003-11-14 Jason Merrill <jason@redhat.com>
+
+ * function.c (assign_parms): Use TREE_TYPE to determine the real
+ type of the argument object.
+
+2003-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___udivsi3): Peel off the first
+ iteration.
+
+2003-11-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_move_block_from_reg):
+ New routine to save vararg registers on stack. Support for
+ -mpowerpc64 in mixed mode.
+
+2003-11-14 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c: Use C statements instead of #ifdef's when testing
+ for MOTOROLA versus MIT syntax. Improves readability and provides
+ better compile-time error checking for both code paths.
+
+2003-11-14 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/frv/frv-protos.h: Update for C90.
+ * config/frv/frv.h: Likewise.
+ * config/frv/frvbegin.c: Likewise.
+ * config/frv/frv.c: Likewise.
+ (frv_adjust_field_align): Delete unused variable.
+
+2003-11-14 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md: Add 'DEFAULT_ABI == ABI_DARWIN'
+ to each place where TARGET_LONG_DOUBLE_128 is used with
+ DEFAULT_ABI == ABI_AIX.
+
+ * cppfiles.c (_cpp_find_file): Make 'one or more PCH files were found'
+ message comply with GNU standards.
+
+2003-11-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ PR/6552
+ * function.c (struct epi_info): New field const_equiv.
+ (update_epilogue_consts): New function.
+ (keep_stack_depressed): Clear new field and verify scratch register
+ doesn't have it set.
+ Call new function via note_stores.
+ (handle_epilogue_set): Allow setting SP equiv reg in different mode.
+ Allow PLUS where second operand is register known set to constant.
+ (emit_equiv_load): Write load using proper mode if source different.
+ * config/mips/mips.md (return_internal): Put (return) first.
+
+2003-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___udivsi3): Add a comment.
+
+2003-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (modsi3): Don't save unused
+ registers.
+ (divsi3): Likewise.
+ (reti): Don't restore unused registers.
+
+2003-11-14 Nick Clifton <nickc@redhat.com>
+
+ * config/fr30/fr30.c: Include toplev.h
+
+2003-11-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * except.c (sjlj_emit_function_enter): Mark internal label as LOCAL.
+
+2003-11-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_emit_vector_const, arm_output_load_gr): Use ISO C
+ function definition syntax.
+
+2003-11-14 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Revert previous patch. Make
+ check for assignment into reg_equiv_address stricter.
+
+2003-11-14 Arnaud Charlet <charlet@act-europe.fr>
+
+ * Makefile.in (POSTSTAGE1_FLAGS_TO_PASS): Pass ADAFLAGS.
+
+2003-11-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_in_small_data_p): Return false for unknown
+ section names.
+
+2003-11-14 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/12526
+ * tree.c (build): A CALL_EXPR has side-effects if its arguments do.
+ * calls.c (call_expr_flags): New fn.
+ * tree.h: Declare it.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (__udivsi3): Remove.
+ (divmodsi3): Change the name to ___udivsi3.
+ Update all callers.
+
+2003-11-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libgcc2.c (__negdi2, __addvsi3, __addvdi3, __subvsi3, __subvdi3,
+ __mulvsi3, __negvsi2, __negvdi2, __mulvdi3, __lshrdi3, __ashldi3,
+ __ashrdi3, __ffsDI2, __muldi3, __clzDI2, __ctzDI2, __parityDI2,
+ __udivmoddi4, __divdi3, __moddi3, __cmpdi2, __ucmpdi2,
+ __fixunstfDI, __fixunsxfDI, __fixunsdfDI, __fixunssfDI,
+ __floatdixf, __floatditf, __floatdidf, __floatdisf, __gcc_bcmp):
+ Const-ify and/or initialize automatic variables at declaration.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divmodsi4): Replace all the uses
+ of er4 with er3. Adjust all callers.
+
+2003-11-13 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_output_possible_stub_label):
+ Allow stub symbol be not defined when outputting possible
+ stub label.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___udivsi3): Jump to reti
+ instead of exitdiv.
+ (___umodsi3): Likewise.
+ (exitdiv): Do not restore any register.
+ (reti): Restore registers.
+
+2003-11-13 Steven Bosscher <stevenb@suse.de>
+
+ * tree-inline.c (walk_tree): Handle PLACEHOLDER_EXPR.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm: Fix comment typos.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (udivsi3): Don't save/restore
+ unused registers. Don't jump to exitdiv.
+ (umodsi3): Likewise.
+
+2003-11-13 Mark Mitchell <mark@codesourcery.com>
+ Kean Johnston <jkj@sco.com>
+
+ PR c/13029
+ * toplev.c (check_global_declarations): Do not warn about unused
+ static consts.
+
+2003-11-13 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (DenHighNonZero): Optimize using
+ the approximate quotient method.
+
+2003-11-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * combine.c (distribute_notes): When re-distributing the notes from
+ an insn we are about to delete, ensure we can't end up with a cyclic
+ list of notes.
+
+2003-11-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12926
+ * expr.c (expand_assignment) [COMPONENT_REF]: Don't put
+ the UNCHANGING_RTX_P flag on memory references to read-only
+ components that are not addressable.
+
+2003-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divmodsi4): Clear S0P in
+ DenHighNonZero.
+
+2003-11-13 Jan Hubicka <jh@suse.cz>
+
+ PR opt/12275
+ * c-decl.c (finish_decl): Use change_decl_assembler_name.
+ * c-pragma.c (handle_pragma_redefine_extname): Likewise.
+ * varasm.c (make_decl_rtl): Likewise.
+ * cgraph.c (change_decl_assembler_name): New function.
+ * tree.h (set_decl_assembler_name): Kill dead declaration.
+ (change_decl_assembler_name): Declare.
+
+ * decl.c (make_rtl_for_nonlocal_decl): Use change_decl_assembler_name.
+ * decl2.c (make_rtl_for_nonlocal_decl): Use change_decl_assembler_name.
+
+2003-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___mulsi3): Don't save/restore
+ an unused register.
+
+2003-11-12 Richard Sandiford <rsandifo@redhat.com>
+
+ PR bootstrap/12752
+ * config/mips/t-iris6 (MULTILIB_OPTIONS): Put -mabi=n32 first.
+ (MULTILIB_OSDIRNAMES): Reorder accordingly.
+
+2003-11-12 Janis Johnson <janis187@us.ibm.com>
+
+ * rs6000-protos.h (rs6000_initial_elimination_offset): Add.
+ (rs6000_stack_info): Remove. (debug_stack_info): Remove.
+ (rs6000_emit_eh_reg_restore): Add
+ * rs6000.c (rs6000_stack_t): Move from rs6000.h, change data type
+ of vars_size and total_size to HOST_WIDE_INT.
+ (emit_frame_save): Change parameter size to HOST_WIDE_INT.
+ (rs6000_stack_info): Make static; change data size to HOST_WIDE_INT.
+ (debug_stack_info): Make static; change output format of HOST_WIDE_INT
+ values.
+ (rs6000_emit_eh_reg_restore): New, with code formerly in rs6000.md.
+ (rs6000_initial_elimination_offset): New, with code formerly in
+ INITIAL_ELIMINATION_OFFSET.
+ * rs6000.h (rs6000_stack_t): Remove.
+ (INITIAL_ELIMINATION_OFFSET): Replace code with call to function
+ rs6000_initial_elimination_offset.
+ * rs6000.md (UNSPECV_EH_RR split): Replace code with call to
+ rs6000_emit_eh_reg_restore.
+
+2003-11-12 Mike Stump <mrs@apple.com>
+
+ * c-typeck.c (c_convert_parm_for_inlining): Add argnum, which
+ is the argumnt we are processing so that warnings and errors
+ will have that information.
+ * c-tree.h (c_convert_parm_for_inlining): Add argnum.
+ * lang-hooks-def.h
+ (lhd_tree_inlining_convert_parm_for_inlining): Likewse.
+ * langhooks.c (lhd_tree_inlining_convert_parm_for_inlining): Likewise.
+ * langhooks.h (convert_parm_for_inlining): Likewise.
+ * tree-inline.c (initialize_inlined_parameters): Compute and
+ pass argnum down.
+
+2003-11-12 Alexey Starovoytov <alexey.starovoytov@sun.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12953
+ * tree-inline.c (inline_forbidden_p_1): Added check for BUILT_IN
+ before switch by FUNCTION_CODE.
+
+2003-11-12 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (storehi): Avoid use of explicit subreg.
+ (storehi_bigend, storeinthi, movhi_bigend): Likewise.
+
+2003-11-12 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/sh/sh.md (prefetch): New pattern.
+
+2003-11-11 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Verify that addresses for
+ reg_equiv_* are valid for the architecture.
+
+2003-11-11 Eric Christopher <echristo@redhat.com>
+
+ * function.c (purge_addressof_1): Add libcall check.
+ Remove test for cached replacements on fallback case.
+ Simplify mode comparisons. Add libcall test for
+ paradoxical subregs.
+
+2003-11-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/t-h8300: Fix an obsolete comment.
+
+2003-11-11 James E Wilson <wilson@specifixinc.com>
+
+ * expmed.c (store_bit_field, extract_bit_field): Revert last two
+ changes.
+
+2003-11-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm: Replace DenHighZero with
+ DenHighNonZero.
+
+2003-11-11 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_function_possibly_inlined_p): Use
+ really_no_inline.
+
+2003-11-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (TRAMPOLINE_TEMPLATE): Fix flushing of cache lines when
+ generating 64-bit code.
+
+2003-11-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): Remove
+ accidental commit in previous change.
+
+2003-11-10 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.h (STACK_SIZE_MODE): Add definition.
+ * config/rs6000/rs6000.c (reg_or_mem_operand): Add macho-style
+ address recognition.
+ (macho_lo_sum_memory_operand): Routine to recognize macho-style
+ address recognition.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (gen_label_die): Cope with DECL_RTL not set.
+
+2003-11-10 Matt Austern <austern@apple.com>
+
+ * config/darwin-protos.h (darwin_assemble_visibility): Declare.
+ * config/darwin.c (darwin_assemble_visibility): Define. Warn for
+ anything other than VISIBILITY_DEFAULT and VISIBILITY_HIDDEN.
+ * config/darwin.h (TARGET_ASM_ASSEMBLE_VISIBILITY): Use
+ darwin_assemble_visibility instead of default.
+
+2003-11-10 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ PR target/12865
+ * config/sparc/sparc.c (sparc_initialize_trampoline): Call
+ __enable_execute_stack only after writing onto the stack.
+ (sparc64_initialize_trampoline): Likewise.
+
+2003-11-09 Roger Sayle <roger@eyesopen.com>
+
+ * loop.c (check_dbra_loop): Try swapping the comparison operands
+ of the loop condition to identify a suitable induction variable.
+ * unroll.c (loop_iterations): Likewise.
+
+2003-11-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/sparc/sparc.h (TARGET_CPU_CPP_BUILTINS): Fix sparc vs
+ sparc64 #cpu and #machine assertions.
+
+2003-11-09 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (rtlanal.o): Depend on BASIC_BLOCK_H.
+
+2003-11-09 Jan Hubicka <jh@suse.cz>
+
+ * tree-optimize.c (tree_rest_of_compilation): Fix warning.
+
+ * cgraphunit.c (cgraph_expand_function): Use
+ cgraph_possibly_inlined_p.
+ * tree-optimize.c (tree_rest_of_compilation): Do not kill saved tree.
+
+ * opts.c (common_handle_option): Do not set max-inline-insns.
+ * params.def: Update comments.
+ (PARAM_MAX_INLINE_INSNS): Kill.
+ * invoke.texi (max-inline-insns): Kill.
+
+2003-11-08 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/3190
+ PR c/8714
+ * c-format.c (set_Wformat): Do not enable -Wformat-y2k by default.
+ * invoke.texi: Update.
+
+2003-11-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12630
+ * pa.c (compute_movstrsi_length): Rename to compute_movstr_length.
+ Handle length computation 64-bit moves.
+ (compute_clrstr_length, output_block_clear): Implement block clear.
+ (output_block_move): Handle 64-bit moves.
+ (pa_adjust_insn_length): Use compute_movstr_length and
+ compute_clrstr_length.
+ * pa.md (movstrsi): Revise operand order and comments. Don't use
+ match_scratch.
+ (movstrsi_internal): Delete.
+ (movstrsi_prereload, movstrsi_postreload): New insns. Define splitter
+ and peephole2 patterns to transform prereload to postreload form.
+ (movstrdi, movstrdi_prereload, movstrdi_postreload, clrstrsi,
+ clrstrsi_prereload, clrstrsi_postreload, clrstrdi, clrstrdi_prereload,
+ clrstrdi_postreload): New patterns for 64-bit block move, and block
+ clear.
+ * pa-protos.h (output_block_clear): New prototype.
+
+2003-11-08 Andreas Schwab <schwab@suse.de>
+
+ * dbxout.c (current_file): Also wrap inside DBX_DEBUGGING_INFO ||
+ XCOFF_DEBUGGING_INFO.
+
+2003-11-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dbxout.c (current_file): Wrap declaration in DBX_USE_BINCL.
+
+2003-11-07 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_legitimize_address): Remove
+ redundant parens.
+
+ * cppfiles.c (pch_open_file): New parameter 'invalid_pch', set it.
+ (find_file_in_dir): Likewise.
+ (_cpp_find_file): Print message if no header file is found
+ but an invalid PCH file was.
+
+2003-11-08 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (pedantic_lvalue_warning): Deprecate compound
+ expressions as lvalues.
+ (internal_build_compound_expr): Remove special handling for
+ non-pedantic case.
+ * doc/extend.texi: Document that all extended lvalues are now
+ deprecated.
+
+2003-11-07 Geoffrey Keating <geoffk@apple.com>
+
+ PR 11654
+ * dbxout.c (struct dbx_file): Do not save for PCH.
+ (current_file): Likewise.
+ (dbxout_init): Don't allocate struct dbx_file using GC.
+ (dbxout_start_source_file): Likewise.
+
+2003-11-07 Falk Hueffner <falk@debian.org>
+
+ * config/alpha/elf.h, config/alpha/unicosmk.h,
+ config/alpha/vms.h: Convert to ISO C90.
+
+2003-11-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/arm/pe.h: Convert to ISO C90.
+
+2003-11-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh-protos.h (sh_pch_valid_p): Declare.
+ * sh.c ("intl.h"): Include.
+ (TARGET_PCH_VALID_P): Override.
+ (sh_target_switches): New variable.
+ (target_switches): Define.
+ (sh_pch_valid_p): New function.
+
+ * sh.h (MODE_AFTER): Don't change mode unless TARGET_HITACHI.
+
+2003-11-07 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_64_sign_extended_value): Return false from tls variables.
+ (x86_64_zero_extended_value): likewise.
+
+2003-11-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (loadgp): Take $25 as a second operand.
+ * config/mips/mips.c (mips_expand_prologue): Modify accordingly.
+
+2003-11-06 Matt Austern <austern@apple.com>
+
+ * c-common.c (handle_visibility_attribute): Set DECL_VISIBILITY
+ field instead of hanging an attribute object off the decl.
+ * tree.h (DECL_VISIBLITY): New accessor macro for
+ symbol_visibility field in struct tree_decl.
+ (enum symbol_visibility): Move definition to before tree_decl.
+ (struct tree_decl): Define new two-bit field, symbol_visibility.
+ (decl_visibility): Remove declaration.
+ * varasm.c (maybe_assemble_visibility): Use DECL_VISIBILITY
+ instead of decl_visibility.
+ (default_binds_local_p_1): Use DECL_VISIBILITY instead of
+ decl_visibility.
+ (decl_visibility): Remove.
+
+2003-11-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_emit_epilogue): Recognize more cases
+ where register 14 will be saved.
+
+2003-11-06 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.h (USE_FP_FOR_ARG_P): Move to rs6000.c.
+ (USE_ALTIVEC_FOR_ARG_P): Likewise.
+ * config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Move from rs6000.h.
+ Take a pointer as the CUM parameter. Update callers.
+ (USE_ALTIVEC_FOR_ARG_P): Likewise. Also correct for Darwin/AIX
+ 32-bit ABIs.
+ (function_arg_advance): Use USE_ALTIVEC_FOR_ARG_P. Correct case
+ of vector parameters as named arguments of stdarg function.
+ (function_arg): Likewise.
+
+ * config/rs6000/darwin.h (ASM_SPEC): Use -force_cpusubtype_ALL when
+ -maltivec is specified, not the non-existent -faltivec.
+
+2003-11-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_function_value): Declare.
+ * config/s390/s390.c (TARGET_RETURN_IN_MEMORY): Define.
+ (s390_return_in_memory): New function.
+ (s390_function_value): New function.
+ (s390_function_arg_float): Return false for all arguments larger
+ than 8 bytes.
+ (s390_function_arg_pass_by_reference): Likewise. Return true for
+ all vector arguments.
+ (s390_function_arg_integer): New function.
+ (s390_function_arg_advance): Call it. Add sanity checks.
+ (s390_function_arg): Likewise.
+ * config/s390/s390.h (FUNCTION_VALUE): Call s390_function_value.
+ (LIBCALL_VALUE): Likewise.
+ (RET_REG): Remove.
+ (RETURN_IN_MEMORY): Remove.
+
+2003-11-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_initial_elimination_offset): Change
+ return type to HOST_WIDE_INT.
+ * config/mips/mips.c (mips_frame_info): Give sizes type HOST_WIDE_INT.
+ Make initialized a bool. Make register masks unsigned ints.
+ (compute_frame_size): Make same mask change here. Use HOST_WIDE_INT
+ where appropriate.
+ (mips_initial_elimination_offset): Return a HOST_WIDE_INT.
+ (mips_output_function_prologue): Print sizes as HOST_WIDE_INTs.
+
+2003-11-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_initial_elimination_offset): Remove bogus
+ negation.
+
+2003-11-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.h (ASM_OUTPUT_ALIGN_WITH_NOP): Define.
+
+2003-11-06 Momchil Velikov <velco@fadata.bg>
+
+ * config/mips/mips.c (override_options): Set MASK_SOFT_FLOAT
+ for VR4111 too.
+
+2003-11-06 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (simplify_builtin_strrchr, simplify_builtin_strpbrk): Add
+ missing casts.
+
+2003-11-06 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c: Change the word "bitsize" to "precision" throughout.
+ * machmode.def: Likewise.
+ * machmode.h (GET_MODE_SIZE): Cast value to unsigned short.
+ (GET_MODE_BITSIZE): Define as GET_MODE_SIZE * BITS_PER_UNIT.
+ (GET_MODE_PRECISION): New macro.
+ (mode_bitsize): Renamed mode_precision.
+ * stor-layout.c (mode_for_size, smallest_mode_for_size):
+ Use GET_MODE_PRECISION; clarify comments.
+
+2003-11-05 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install-old.texi: Remove old documentation of building
+ cross-compilers.
+ * doc/install.texi: Move some of it to here.
+
+2003-11-05 Per Bothner <pbothner@apple.com>
+
+ PR preprocessor/12891
+ * c-opts.c (finish_options): Set include_cursor to disable premature
+ calls to push_command_line_include from cpp_scan_nooutput.
+ Fixes bug reported by DJ Delorie.
+
+2003-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (setup_incoming_varargs): Remove
+ code supporting old-style varargs.
+
+ * config/rs6000/rs6000.c (rs6000_machopic_legitimize_pic_address): Use
+ an intermediate register for better optimisation.
+
+2003-11-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/10080
+ * cfgloopanal.c (variable_initial_value, variable_initial_values,
+ simple_loop_exit_p): Record the fact that initial value is extended
+ from inner mode.
+ (count_strange_loop_iterations, count_loop_iterations): Handle
+ ivs that iterate in a narrower mode. Fix handling of overflows.
+ Improve handling of NE conditions.
+ (inverse, fits_in_mode_p): New static functions.
+ (simple_increment): Detect variables that iterate in a narrower mode.
+ * cfgloop.h (struct loop_desc): Fields inner_mode and extend added.
+
+2003-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (compute_vrsave_mask): Correct off-by-one
+ error.
+
+ * config/rs6000/darwin.h (SUBTARGET_OVERRIDE_OPTIONS): Darwin
+ needs VRSAVE.
+
+2003-11-05 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (pedantic_lvalue_warning): Deprecate use of
+ conditional expressions as lvalues.
+
+2003-11-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tsystem.h: Add the prototype of strlen.
+ * unwind-pe.h (read_encoded_value_with_base): Add an
+ appropriate cast to handle a case where the pointer size is
+ smaller than sizeof (int).
+
+2003-11-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_global_pic_constant_p): Delete.
+ (mips_delegitimize_address): Delete.
+ (mips_gotoff_global, mips_load_got_page): Declare.
+ (mips_load_got_global, mips_rewrite_small_data): Declare.
+
+ * config/mips/mips.h (FIND_BASE_TERM): Remove definition.
+ (DANGEROUS_FOR_LA25_P): Use global_got_operand.
+ (PREDICATE_CODES): Add global_got_operand, local_got_operand and
+ small_data_pattern. Remove CONST from const_arith_operand's entry.
+
+ * config/mips/mips.c (UNSPEC_ADDRESS_P, CONST_GP_P): New macros.
+ (UNSPEC_ADDRESS, UNSPEC_ADDRESS_TYPE): Likewise.
+ (mips_constant_type): Delete.
+ (mips_symbol_type): Add SYMBOL_GOTOFF_PAGE, SYMBOL_GOTOFF_GLOBAL,
+ SYMBOL_GOTOFF_CALL and SYMBOL_GOTOFF_LOADGP.
+ (NUM_SYMBOL_TYPES): New macro.
+ (mips_address_type): Remove ADDRESS_INVALID.
+ (machine_function): Add has_gp_insn_p.
+ (mips_constant_info): Delete.
+ (mips_address_info): Add the address type as an extra field. Replace
+ the c field with symbol_type.
+ (mips_split_p, mips_lo_relocs, mips_hi_relocs): New arrays.
+ (TARGET_DELEGITIMIZE_ADDRESS): Remove definition.
+ (mips_reloc_offset_ok_p, mips_classify_constant): Delete.
+ (mips_split_const, mips_symbolic_constant_p): New functions.
+ (mips_symbolic_address_p): Take the symbol type and mode as arguments.
+ (mips_classify_address): Return true if the address is valid, storing
+ its type in INFO. Use mips_symbolic_constant_p. Use mips_lo_relocs[]
+ to test whether a LO_SUM address is allowed.
+ (mips_symbol_insns): Return 0 for general mips16 symbols.
+ Reorder SYMBOL_GOT_GLOBAL case to match mips_symbol_type definition.
+ Handle the new SYMBOL_GOTOFF_*s.
+ (mips_address_insns): Update call to mips_classify_address.
+ (mips_const_insns): Be more fussy about HIGH constants. Remove use
+ of mips_classify_constant. Be more accurate about CONSTs.
+ (mips_global_pic_constant_p): Delete.
+ (const_arith_operand): Only accept CONST_INTs.
+ (call_insn_operand): Remove call to mips_classify_constant.
+ Let mips_symbolic_constant_p check for invalid offsets.
+ (move_operand): Check for general_operands first. Only accept symbolic
+ constants if they satisfy mips_symbolic_constant_p and cannot be split.
+ (symbolic_constant): Use mips_symbolic_constant_p.
+ (global_got_operand, local_got_operand): New predicates.
+ (stack_operand): Update call to mips_classify_address.
+ (mips_legitimate_address_p): Likewise.
+ (mips_reloc, mips_lui_reloc): Delete.
+ (mips_force_temporary): Only use the given temporary if no_new_pseudos.
+ Use emit_move_insn.
+ (mips_split_symbol, mips_unspec_address): New functions.
+ (mips_unspec_offset_high): New function.
+ (mips_load_got): Replace reloc argument with a symbol_type.
+ Use mips_unspec_address to create the address and put it in a
+ LO_SUM with the base register.
+ (mips_load_got16, mips_load_got32): Delete.
+ (mips_emit_high, mips_legitimize_symbol): Delete.
+ (mips_gotoff_global): New function.
+ (mips_load_got_page, mips_load_got_global): New functions.
+ (mips_legitimize_symbol): Inline handling of LO_SUM splits.
+ (mips_legitimize_const_move): Likewise. Remove HIGH handling.
+ Inline code to handle constants plus invalid offsets. Use
+ mips_split_symbol to legitimize constant pool addresses.
+ (mips_delegitimize_address): Delete.
+ (mips_rtx_costs): Give legitimate symbolic constants and CONST_DOUBLEs
+ a cost of 1 insn. Give the rest a cost of CONSTANT_POOL_ADDRESS.
+ (mips_subword): Pass memrefs through mips_rewrite_small_data.
+ (mips_output_move): Remove use of mips_classify_constant.
+ (mips_expand_call): Use mips_unspec_offset_high to calculate the
+ high part of the GOT address for calls to global functions.
+ (override_options): Initialize mips_split_p[], mips_lo_relocs[]
+ and mips_hi_relocs[].
+ (print_operand): Use print_operand_reloc to handle '%h' and '%R'.
+ Remove use of mips_classify_constant.
+ (mips_reloc_string): Delete.
+ (print_operand_reloc): New function.
+ (print_operand_address): Update call to mips_classify_address.
+ (mips_rewrite_small_data_p, small_data_pattern_1): New functions.
+ (small_data_pattern): New predicate.
+ (mips_rewrite_small_data_1, mips_rewrite_small_data): New functions.
+ (mips_function_has_gp_insn): New function.
+ (mips_global_pointer): Use it.
+ (mips_gp_insn): Delete.
+ (mips_expand_prologue): When compiling for n32/n64 abicalls, use a
+ single loadgp pattern to initialize $gp. Pass it the offset of _gp
+ from the start of the current function.
+ (mips16_gp_pseudo_reg): Revert last patch.
+
+ * config/mips/mips.md (RELOC_*): Delete.
+ (UNSPEC_LOADGP, UNSPEC_FIRST_ADDRESS): New constants.
+ (got): New insn attribute.
+ (type): Set to "load" if got == load.
+ (length): Set to 4 if got == load, 8 if got == xgot_high.
+ (lui[sd]i): Delete.
+ (*xgot_hi[sd]i, *xgot_lo[sd]i): New patterns.
+ (*got_disp[sd]i, *got_page[sd]i): Likewise.
+ (*low[sd]i): Change constraints to "d". Add a new define_split to
+ rewrite small data constants into LO_SUMs.
+ (loadgp): New insns.
+
+2003-11-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/_tilib.c: Use _ABI* in _MIPS_SIM tests.
+
+2003-11-04 DJ Delorie <dj@redhat.com>
+
+ * config/v850/v850.md (mulhisi3): Expand the const_int case
+ separately to avoid trying to sign extend the const.
+
+2003-11-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * emit-rtl.c (copy_rtx_if_shared): Don't allow MEMs with constant
+ addresses to be shared.
+ (force_const_mem): Return a copy of the pool entry.
+
+2003-11-03 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (GCC_CFLAGS): Remove @WERROR@ again.
+
+2003-11-03 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (cpp.dvi): New target split from cpp.info.
+ (gcc.dvi): New target split from gcc.info.
+ (gccint.dvi): New target split from gccint.info.
+ (cppinternals.dvi): New target split from cppinternals.info
+ (gccinstall.info): New specific rule.
+ (gccinstall.dvi): Likewise.
+ (dvi): Move targets to $(docobjdir).
+ ($(docobjdir)/%.dvi): New implicit rule.
+
+2003-11-03 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * doc/gty.texi (tag, desc): Say more about role of desc values in
+ selecting between tags.
+
+2003-11-03 Alexander Kabaev <ak03@gte.com>
+
+ * real.c (encode_ieee_single): Ensure proper promotion.
+
+2003-11-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/contrib.texi: Add Giovanni Bajo, Dara Hazeghi, Falk Hueffner,
+ and Andrew Pinski.
+
+2003-11-03 Syd Polk <spolk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Add G3, G4, and G5
+ marketing names to the list of supported processors.
+ * config/rs6000/rs6000.h: Ditto.
+ * doc/invoke.texi: Ditto.
+ * config.gcc: Ditto.
+
+2003-11-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (stdio_va_list): Allow tab before va_list.
+ Merge two substitutions.
+ * fixinc/fixincl.x: Regenerate.
+ Fixes PR bootstrap/12666.
+
+2003-11-03 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install-old.texi: Remove VMS documentation.
+
+2003-11-03 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (override_options): Remove hack enabling 128bit long double
+ commited by accident.
+
+2003-11-02 Per Bothner <per@bothner.com>
+
+ * c-opts.c (needValue): Do cpp_find_main_file before processing
+ any imacros flags, so pfile->main_file is set for the latter.
+
+2003-11-03 Andreas Jaeger <aj@suse.de>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (GCC_CFLAGS): Allow blacklisting of warnings.
+ (SYSCALLS.c.X-warn): Suppress warnings.
+
+2003-11-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12845
+ * pa.c (output_cbranch): Use cmpb for DImode comparisons with 0.
+
+2003-11-02 Zack Weinberg <zack@codesourcery.com>
+
+ * print-rtl.c (print_rtx): Call PRINT_REG with second argument -1.
+ * config/i386/i386.c (print_reg): Abort on a virtual register
+ if code != -1; not if file == asm_out_file.
+ * config/i386/i386.h (PRINT_REG): Document meaning of CODE == -1.
+ (DEBUG_PRINT_REG): Delete, unused.
+
+2003-11-02 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/fde-glibc.c (_GNU_SOURCE): Define to 1 instead of
+ empty to avoid conflict with the definition from configure.
+
+2003-11-02 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/10817
+ * ifcvt.c (noce_emit_move_insn): Improve documentation comment.
+ (noce_try_move): New function to optimize an if-the-else into an
+ unconditional move, i.e. "if (a!=b) x=a; else x=b" into "x=a".
+ (noce_process_if_block): Attempt simplification with noce_try_move.
+
+ * simplify-rtx.c (simplify_ternary_operation): Some minor fixes
+ and improvements to the optimizations of IF_THEN_ELSE expressions.
+ (simplify_subreg): Silence signed/unsigned comparison warning.
+
+2003-11-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (targhooks.o, reload.o): Update dependencies.
+ (GTFILES): Add targhooks.c.
+ (gt-targhooks.h): New rule; depend on s-gtype.
+ * target.h (direct_pool_load_p): New hook.
+ * target-def.h (TARGET_DIRECT_POOL_LOAD_P): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_direct_pool_load_p): Declare.
+ (hook_bool_machine_mode_true): Declare.
+ * targhooks.c: Include insn-config.h, recog.h, ggc.h and
+ gt-targhooks.h.
+ (pool_symbol): New variable.
+ (default_direct_pool_load_p): New function.
+ (hook_bool_machine_mode_true): New function.
+ * reload.c: Include target.h.
+ (find_reloads): If an alternative will force a constant into memory,
+ count an extra reload if constant pool symbols are not valid
+ addresses. If an alternative uses memory to move values between
+ registers, count the move as two reloads rather than one.
+ * config/s390/s390.c (TARGET_DIRECT_POOL_LOAD_P): Define.
+ * doc/tm.texi (TARGET_DIRECT_POOL_LOAD_P): Document.
+
+2003-11-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12799
+ * postreload.c (reload_cse_move2add): Generate the add2
+ patterns manually.
+
+2003-11-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_partial_nregs) [TARGET_ARCH64]:
+ Return 0 for all complex modes whose size is lesser or equal to
+ a word. Add a ??? comment for the condition used with 16-byte
+ aligned modes.
+
+2003-11-01 Kelley Cook <kcook@gcc.gnu.org>
+
+ * .cvsignore: Remove c-parse* and tradcif.c.
+ * objc/.cvsignore: Delete.
+
+2003-11-01 Roger Sayle <roger@eyesopen.com>
+
+ * unwind-sjlj.c (_Unwind_GetCFA): Return (_Unwind_Word)0 instead
+ of NULL.
+
+2003-11-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.h (DO_GLOBAL_DTORS_BODY): Change to C90 declaration.
+
+ * libgcc2.c (SYMBOL__MAIN): Provide C90 declaration.
+
+ * collect2.c (scan_libraries): Fix typos.
+
+ PR preprocessor/12847
+ * cppfiles.c, cppexp.c, cpperror.c, cpplib.h, cpplib.c, cpplex.c,
+ cppinit.c, cpptrad.c, cppmacro.c, fix-header.c, cpppch.c, c-pch.c,
+ c-incpath.c, cppcharset.c (DL_WARNING, DL_WARNING_SYSHDR, DL_PEDWARN,
+ DL_ERROR, DL_ICE, DL_EXTRACT, DL_WARNING_P): Prefix macro names with
+ "CPP_".
+
+2003-11-01 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_mixed_function_arg): Correct
+ no_units calculation.
+
+2003-11-01 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2.c (_Unwind_FrameState): Remove commas at end of
+ enumeration list.
+
+2003-11-01 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/sysv4.h (SDATA_SECTION_FUNCTION): Update to C90
+ prototypes.
+ (SBSS_SECTION_FUNCTION): Likewise.
+
+2003-11-01 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (GCC_CFLAGS): Add @WERROR@ for target files.
+
+2003-11-01 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * config/rs6000/sysv4.h (EXTRA_SECTION_FUNCTIONS): Update to C90
+ prototypes.
+
+2003-11-01 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2.c (_Unwind_FindEnclosingFunction): Constify variable.
+ (uw_frame_state_for): Constify variables.
+ (extract_cie_info): Constify first argument.
+
+ * unwind-dw2-fde-darwin.c: Adjust prototype of
+ _Unwind_Find_registered_FDE for recent changes.
+ (examine_objects): Constify return value and local variable result.
+ (_Unwind_Find_FDE): Constify return value and local variable ret.
+
+2003-10-31 Per Bothner <pbothner@apple.com>
+
+ * c-opts.c (finish_options): Change to returns boolean - false iff
+ the call to cpp_find_main_file fails.
+ (c_common_init): Skip preprocess_file if finish_options failed.
+ (c_common_parse_file): Break if finish_options failed.
+ Fixes PR preprocessor/12545.
+
+2003-10-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * aclocal.m4: Blacklist ultrix* for mmap file.
+ * configure: Rebuilt.
+
+ * function.c (assign_parms): Add ATTRIBUTE_UNUSED to variable
+ reg_parm_stack_space.
+ * toplev.c (default_get_pch_validity): Fix warning.
+
+ * vax.c: Include toplev.h.
+ (vax_init_libfuncs): Fix typo (umod).
+ * vax.h (ASM_COMMENT_START): Define.
+ (PRINT_OPERAND): Fix warning when HOST_WIDE_INT is a long long.
+
+2003-10-31 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11968
+ * expr.c (expand_expr <MULT_EXPR>): Remove inappropriate and
+ confusing comment; distributivity isn't handled in expand_expr.
+ * fold-const.c (extract_muldiv_1 <PLUS_EXPR>): Allow overflow
+ in distributivity, if wrap-around semantics are specified with
+ -fwrapv.
+
+2003-11-01 Alan Modra <amodra@bigpond.net.au>
+
+ PR 12315
+ * final.c (profile_function): Allow for NULL svrtx.
+
+2003-10-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_select_section): Use new style declaration.
+ * som.h (readonly_data): Likewise.
+
+2003-10-31 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/rs6000/rs6000.c: Update to C90 prototypes.
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/7513
+ * arm.h (CONDITIONAL_REGISTER_USAGE): Disable use of LR in Thumb
+ code.
+
+2003-10-31 Andreas Jaeger <aj@suse.de>,
+ Zack Weinberg <zack@codesourcery.com>
+
+
+ * crtstuff.c (__register_frame_info, __register_frame_info_bases)
+ (__deregister_frame_info, __deregister_frame_info_bases):
+ Constify void * argument.
+ * unwind-dw2-fde.h (struct fde_vector):
+ Constify 'orig_data' and 'array' fields.
+ (__register_frame_info, __register_frame_info_bases)
+ (__deregister_frame_info, __deregister_frame_info_bases):
+ Constify void * argument.
+ (get_cie, next_fde, _Unwind_Find_FDE): Constify arguments,
+ return values, and casts of type fde *, struct dwarf_fde *,
+ and struct dwarf_cie *.
+ * unwind-dw2-fde.c (__register_frame_info, __register_frame_info_bases)
+ (__deregister_frame_info, __deregister_frame_info_bases):
+ Constify void * argument.
+ (get_cie_encoding, ): Constify struct dwarf_cie * argument.
+ (get_fde_encoding, fde_unencoded_compare, fde_single_encoding_compare)
+ (fde_mixed_encoding_compare, fde_compare_t, start_fde_sort, fde_insert)
+ fde_split, SWAP, frame_downheap, frame_heapsort)
+ (classify_object_over_fdes, add_fdes, linear_search_fdes,
+ binary_search_unencoded_fdes, binary_search_single_encoding_fdes,
+ binary_search_mixed_encoding_fdes, search_object, _Unwind_Find_FDE):
+ Constify arguments, local variables, return values, and casts
+ of type fde *, fde **, struct dwarf_fde *, and struct dwarf_cie *.
+ Use const pointer types in sizeof expressions, for clarity.
+ * unwind-dw2-fde-glibc.c
+ (_Unwind_find_registered_FDE, _Unwind_find_FDE): Constify return value.
+ (struct unw_eh_callback_data): Constify 'ret' field.
+
+2003-10-31 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New.
+ (function_arg): Call it.
+ (rs6000_function_value): Widen integral return value to mode based
+ on TARGET_32BIT, not word_mode.
+ * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise.
+ (UNITS_PER_ARG): New.
+ (RS6000_ARG_SIZE): Use it.
+
+2003-10-31 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * .cvsignore: No longer ignore gengtype-lex.c, gengtype-yacc.c,
+ and gengtype-yacc.h.
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/8896
+ * postreload.c (reload_combine): Check that REGY doesn't die in an
+ insn of the form (set (regx) (plus (regx) (regy))), ie REGX != REGY.
+
+2003-10-31 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/10239
+ * cfgrtl.c (delete_insn): Decrease LABEL_NUSES for all REG_LABEL notes.
+
+2003-10-31 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/11640
+ * cfgrtl.c (try_redirect_by_replacing_jump): Move jump
+ immediatelly before BARRIER.
+
+2003-10-31 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (STRICT2_WARN): Add -Wold-style-definition.
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/11271
+ * reload.c (find_reloads_address): Handle any register in
+ (PLUS (PLUS (REG) (REG)) (CONST_INT).
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ * ggc-page.c (ggc_pch_read): Wrap call to poison_pages in
+ ENABLE_GC_CHECKING not in GGC_POISON.
+
+2003-10-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR bootstrap/9863
+ * configure.in: Bail out if awk is missing.
+ * configure: Regenerate.
+
+ PR ada/12761
+ * Makefile.in: Move default definitions of X_ADA_CFLAGS,
+ T_ADA_CFLAGS, X_ADAFLAGS, T_ADAFLAGS from ada/Make-lang.in to here.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * c-objc-common.c (c_tree_printer): Handle types correctly.
+ Factor code a bit.
+
+2003-10-30 Kelley Cook <kcook@gcc.gnu.org>
+
+ * value-prof.c, web.c: Update to C90.
+
+2003-10-30 Eric Christopher <echristo@redhat.com>
+
+ * function.c (purge_addressof_1): Add case for REG_RETVAL
+ notes when modes are unequal.
+
+2003-10-31 Jan Hubicka <jh@suse.cz>
+
+ * i386-modes.def: Add XFmode format adjustment.
+
+2003-10-30 Jan Hubicka <jh@suse.cz>
+
+ * real.c (encode_ieee_extended): Back out previous patch.
+
+2003-10-30 Jan Hubicka <jh@suse.cz>
+
+ * real.c (encode_ieee_extended): Initialize whole array.
+ * reg-stack.c (move_for_stack_reg0: Use always XFmode.
+ * i386-modes.def: Change definitions of TFmode and XFmode.
+ * i386.c (classify_argument): Rename TFmodes to XFmodes; add new TFmode
+ code.
+ (construct_container): Allow constructing of TFmode integer containers.
+ (ix86_return_in_memory): XFmode is not returned in memory.
+ (init_ext_80387_constants): Always use XFmode.
+ (print_operand): Likewise.
+ (ix86_prepare_fp_compare_regs): Likewise.
+ (split_to_parts): Deal with TFmode.
+ (split_long_move): Simplify.
+ (ix86_init_mmx_sse_builtins): Add __float80, __float128.
+ (ix86_memory_move_cost): Do not confuse TFmode.
+ * i386.h (LONG_DOUBLE_TYPE_SIZE): Set to 96.
+ (IS_STACK_MODE): TFmode is not stack mode.
+ (HARD_REGNO_NREGS, CLASS_MAX_NREGS): Deal nicely with XFmode.
+ (VALID_SSE_REG_MODE): Allow TFmode.
+ (VALID_FP_MODE_P): Disallow TFmode.
+ (VALID_INT_MODE_P): Allow TFmode in 64bit mode.
+ * i386.md (TFmode patterns): Kill.
+ (movtf, motf_rex64): New patterns.
+
+2003-10-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (adddi3): Fix typo in mips16 stack pointer code.
+
+2003-10-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (mov_lwl): Use memory_operand where appropriate.
+ (mov_lwr, mov_swl, mov_swr): Likewise.
+ (mov_ldl, mov_ldr, mov_sdl, mov_sdr): Likewise.
+
+2003-10-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_global_pointer): Don't try to use $25.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * config/mips/mips.c (mips_build_builtin_va_list): Use runtime
+ test for irix6 rather than preprocessor test.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * cppcharset.c (one_utf8_to_utf16): Initialize 's' to silence warning.
+
+2003-10-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (struct machine_function): Use save_return_addr_p
+ as a general flag that the return address register needs to be saved,
+ not necessarily because of __builtin_return_addr (0).
+ (s390_split_branches): Remove TEMP_REG and TEMP_USED arguments,
+ remove special handling of zSeries machines.
+ (s390_optimize_prolog): Remove TEMP_USED argument, treat the return
+ register as a regular register on zSeries machines.
+ (s390_reorg): Adjust calls to s390_split_branches and
+ s390_optimize_prolog.
+ (s390_frame_info): On zSeries machines, do not assume the return
+ register is always used. Update regs_ever_live with current data
+ for the special registers.
+ (s390_emit_epilogue): Use save_return_addr_p to determine whether
+ the return register was saved.
+ * config/s390/s390.h (CONDITIONAL_REGISTER_USAGE): Do not mark
+ RETURN_REGNUM fixed on zSeries machines.
+ (REG_ALLOC_ORDER): Use RETURN_REGNUM last.
+ * config/s390/s390.md ("*doloop_si"): Handle branch overflow
+ via ahi-jgne pair on zSeries machines.
+ ("*doloop_di"): Likewise.
+ ("*doloop_di_long"): Remove.
+
+2003-10-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_override_options): Revert change of arm_constant_limit
+ when optimizing for size.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * fold-const.c (fold_single_bit_test): Convert the input to the
+ operational intermediate type.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (std_build_builtin_va_list): New.
+ * expr.h (std_build_builtin_va_list): Declare.
+ * defaults.h (BUILD_VA_LIST_TYPE): New.
+ * system.h (BUILD_VA_LIST_TYPE): Poison.
+ * target-def.h (TARGET_BUILD_BUILTIN_VA_LIST): New.
+ * target.h (struct gcc_target): Add build_builtin_va_list.
+ * tree.c (build_common_tree_nodes_2): Use it.
+
+ * config/alpha/alpha-protos.h, config/alpha/alpha.c,
+ config/alpha/alpha.h, config/alpha/unicosmk.h,
+ config/d30v/d30v-protos.h, config/d30v/d30v.c, config/d30v/d30v.h,
+ config/i386/i386-protos.h, config/i386/i386.c, config/i386/i386.h,
+ config/i860/i860-protos.h, config/i860/i860.c, config/i860/i860.h,
+ config/i960/i960-protos.h, config/i960/i960.c, config/i960/i960.h,
+ config/mips/iris6.h, config/mips/mips-protos.h, config/mips/mips.c,
+ config/mips/mips.h, config/rs6000/rs6000-protos.h,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.h,
+ config/s390/s390-protos.h, config/s390/s390.c, config/s390/s390.h,
+ config/sh/sh-protos.h, config/sh/sh.c, config/sh/sh.h,
+ config/xtensa/xtensa-protos.h, config/xtensa/xtensa.c,
+ config/xtensa/xtensa.h: Rename foo_build_va_list to
+ foo_build_builtin_va_list; make it static. Define
+ TARGET_BUILD_BUILTIN_VA_LIST. Remove BUILD_VA_LIST_TYPE.
+ Update protos.
+
+ * config/i386/i386.c (ix86_expand_carry_flag_compare): Make static.
+ * config/iq2000/iq2000.h (BUILD_VA_LIST_TYPE): Remove.
+
+2003-10-29 James E Wilson <wilson@specifixinc.com>
+
+ * recog.c (asm_operand_ok): Add missing break after case 'X'.
+ Change if statements to else if statements in default case.
+ (extract_constrain_insn_cached): Fix misspelling of constrain_operands
+ in comment.
+ (constrain_operands_cached): Likewise.
+ (constrain_operands): Change if statements to else if statements in
+ default case.
+ * reload.c (find_reloads): Likewise.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * config/m68k/m68k.c (notice_update_cc): Clear cc status for
+ shifts and rotates.
+
+2003-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: Remove duplicate pattern.
+
+2003-10-29 Hans-Peter Nilsson <hp@axis.com>
+
+ * real.c (do_divide): Initialize result with a 0.
+
+ * configure.in <enable-checking for valgrind>: Look for
+ <valgrind/memcheck.h> first. AC_DEFINE HAVE_VALGRIND_MEMCHECK_H
+ if it exists.
+ * configure, config.in: Regenerate.
+ * ggc-common.c [ENABLE_VALGRIND_CHECKING &&
+ HAVE_VALGRIND_MEMCHECK_H]: Include <valgrind/memcheck.h>. Use
+ #elif for other alternatives.
+ * ggc-page.c: Ditto.
+ * ggc-zone.c: Don't assume <valgrind/memcheck.h>; instead copy
+ include structure from ggc-common.c.
+
+2003-10-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-linux.h (ASM_OUTPUT_ADDR_VEC_ELT): Use label in big switch ELTs.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): Use label difference in big switch ELTs.
+ * pa.c (pa_adjust_insn_length): Check for btable branches using
+ attribute TYPE_BTABLE_BRANCH.
+ (pa_reorg): Simplify.
+ * pa.h (CASE_VECTOR_MODE): Change big switch mode to SImode.
+ (ASM_OUTPUT_ADDR_VEC_ELT): As above.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): As above.
+ * pa.md (btable_branch): New instruction type.
+ (in_branch_delay, in_nullified_branch_delay, in_call_delay): Disallow
+ btable branches.
+ (define_delay): Add btable branches to insn types that may have an
+ insn in the delay position.
+ (Z2, Z3): Add btable branch to list.
+ Simplify unamed pattern set copy pic_label_operand to register. Add
+ PA 2.0 variant.
+ (short_jump): New jump for use in branch tables.
+ (casesi, casesi0): Revise for new branch table formats.
+ (casesi32, casesi32p, casesi64p): New casesi patterns.
+ (indirect_jump): Move.
+
+2003-10-29 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (UNITS_PER_WORD): Revert to
+ !TARGET_POWERPC64.
+ (UNITS_PER_GPR_WORD): Delete.
+ (HARD_REGNO_NREGS): Revert to UNITS_PER_WORD.
+ (HARD_REGNO_MODE_OK): Same.
+ (CLASS_MAX_NREGS): Same.
+
+2003-10-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (ASM_COMMENT_START): Define.
+
+2003-10-29 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c (complete_mode): Record MODE_CC, MODE_INT,
+ MODE_FLOAT, and MODE_PARTIAL_INT modes as having one
+ component, not zero.
+
+2003-10-29 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/t-ia64 (LIB2ADDEH): Add $(srcdir)/gthr-gnat.c.
+
+2003-10-29 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_partial_nregs) [TARGET_ARCH64]:
+ Never return 1 for complex integral modes whose size is lesser or
+ equal to a word.
+ (function_arg_pass_by_reference) [TARGET_ARCH64]: Mention CTImode
+ in the comment.
+ (function_arg_advance) [TARGET_ARCH64]: Don't special-case complex
+ modes.
+ (sparc_va_arg) [TARGET_ARCH64]: Handle any types whose size is
+ greater than 16 bytes by reference.
+
+2003-10-29 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/ia64/ia64.c (ia64_assemble_integer): Test POINTER_SIZE,
+ not TARGET_ILP32.
+ (ia64_initialize_trampoline): Use globalize_label target call.
+
+2003-10-29 Andreas Schwab <schwab@suse.de>
+
+ * doc/install.texi (Building): Add a sentence about building Ada
+ for a canadian cross.
+
+2003-10-28 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.c (cmptf_libfunc): New static.
+ (ia64_expand_compare): Add logic to open-code calls to
+ _U_Qfcmp for TFmode comparisons.
+ (ia64_hpux_init_libfuncs): Initialize cmptf_libfunc.
+ Set libfuncs for TFmode eq/ne/gt/ge/lt/gt to 0; these should
+ never be generated anymore.
+ * config/ia64/ia64.md (cmptf): New expander.
+
+2003-10-28 Zack Weinberg <zack@codesourcery.com>
+
+ * ia64.md (UNSPEC_SETF_EXP,UNSPEC_FR_SQRT_RECIP_APPROX): New constants.
+ (*sqrt_approx): New instruction pattern for approximate square roots.
+ (*setf_exp_xf): New instruction pattern for exponentiation.
+ (*maddxf4_alts_truncsf): New instruction pattern for truncation.
+ (sqrtsf2_internal_thr): New define_and_split implementing
+ throughput-optimized inline calculation of SFmode square root.
+ (sqrtdf2_internal_thr): Likewise for DFmode.
+ (sqrtxf2_internal_thr): Likewise for XFmode.
+ (sqrtsf2, sqrtdf2, sqrtxf2): New expanders to choose between
+ latency- and throughput-optimized square root algorithms.
+ * ia64.h (MASK_INLINE_SQRT_LAT, MASK_INLINE_SQRT_THR,
+ TARGET_INLINE_SQRT_LAT, TARGET_INLINE_SQRT_THR, TARGET_INLINE_SQRT):
+ New macros.
+ (TARGET_SWITCHES): Add -minline-sqrt-min-latency and
+ -minline-sqrt-max-throughput.
+ * ia64.c (ia64_override_options): If both -minline-sqrt-min-latency
+ and -minline-sqrt-max-throughput are given, notify the user
+ that both options cannot be used simultaneously.
+ If -minline-sqrt-min-latency is given, notify the user that
+ this mode is not yet implemented.
+ (rtx_needs_barrier): Reformat initial comment to obey
+ 72-character width limit. Support UNSPEC_SETF_EXP and
+ UNSPEC_FR_SQRT_RECIP_APPROX.
+
+2003-10-29 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md (movdf_softfloat64): Allow dummy ctr,ctr
+ moves.
+
+2003-10-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR target/11598
+ PR libgcj/10610
+ * config/rs6000/sysv4.h (PREFERRED_STACK_BOUNDARY): New macro.
+
+2003-10-28 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_output_epilogue): When using a frame pointer, don't emit
+ an extra stack adjustment insn if the stack pointer is already
+ pointing at the right place.
+ (use_return_insn): Allow a return insn to be used when we have a
+ frame pointer if the stack pointer is in the right place.
+ (output_return_instruction): Handle it.
+
+2003-10-28 Andreas Jaeger <aj@suse.de>
+
+ * ggc-zone.c (check_cookies): Add missing variable.
+ Add void to prototypes.
+
+2003-10-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/irix6-libc-compat.c (inet_makeaddr): Prototype.
+ * crtstuff.c (__do_global_ctors_1): Move prototype.
+ * unwind-dw2.c (NO_SIZE_OF_ENCODED_VALUE): Define when
+ appropriate.
+ * unwind-sjlj.c (_Unwind_GetCFA, _Unwind_FindEnclosingFunction):
+ Mark parameter with __attribute__((unused)).
+
+2003-10-27 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (pushdecl): Clarify comment.
+
+2003-10-27 Arnaud Charlet <charlet@act-europe.fr>
+
+ * doc/install.texi: Update instructions for Ada cross builds
+
+ PR ada/5909:
+ * doc/sourcebuild.texi: Document Ada test suite.
+
+2003-10-27 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c: Convert to ISO C90.
+ * config/m68hc11/m68hc11-protos.h: Likewise.
+
+2003-10-27 Jan Hubicka <jh@suse.cz>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * toplev.c (enum dump_file_index, dump_file): Fix ordering of
+ webizer pass dump.
+
+2003-10-27 Jakub Jelinek <jakub@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ * reload1.c (struct elim_table): Change offset, initial_offset and
+ previous_offset fields to HOST_WIDE_INT.
+ (offsets_at): Change from int to HOST_WIDE_INT.
+ (reload): Adjust offsets_at initialization.
+ (eliminate_regs_in_insn): Change type of offset to HOST_WIDE_INT.
+ (verify_initial_elim_offsets): Change type of t to HOST_WIDE_INT.
+ * config/i386/i386.c (ix86_compute_frame_layout): Change offset type
+ to HOST_WIDE_INT. Don't save regs using mov for huge frame sizes
+ if TARGET_64BIT.
+ (pro_epilogue_adjust_stack): New function.
+ (ix86_expand_prologue, ix86_expand_epilogue): Use it.
+ * config/i386/i386.md (pro_epilogue_adjust_stack): Remove.
+ (pro_epilogue_adjust_stack_1): Remove * in front of name.
+ (pro_epilogue_adjust_stack_rex64): Handle -2147483648 properly.
+ (pro_epilogue_adjust_stack_rex64_2): New insn.
+
+ * config/i386/i386.c (ix86_expand_epilogue): Fix comment typo.
+
+ * config/i386/i386.c (ix86_expand_call): Replace 40 with
+ FIRST_REX_INT_REG + 3 /* R11 */.
+
+2003-10-26 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.md (attr cannot_copy): New.
+ (call_osf_2_er, call_value_osf_2_er, ldgp_er_1, ldgp_er_2,
+ prologue_ldgp_er_2, prologue_ldgp_1): Set it.
+ * config/alpha/alpha.c (alpha_cannot_copy_insn_p): Test it.
+
+2003-10-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * ggc-zone.c: New file, zone allocating collector.
+ * configure: Accept zone option for --with-gc
+ * configure.in: Ditto.
+ * ggc.h (ggc_pch_count_object): Pass bool indicating
+ stringiness. Update all callers.
+ (ggc_pch_alloc_object): Ditto.
+ (ggc_pch_write_object): Ditto.
+ (ggc_alloc_rtx): Use typed allocation, since all RTX's are of a single
+ type.
+ (ggc_alloc_rtvec): Ditto.
+ (ggc_alloc_tree): Use zone allocation, since some things using this macro
+ aren't a single typecode.
+ * ggc-none.c (ggc_alloc_typed): New function.
+ (ggc_alloc_zone): Ditto.
+ * ggc-page.c: Ditto on both functions.
+
+2003-10-26 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_compute_frame_layout): Ensure FPU related
+ frame information is always valid.
+ (m68k_output_function_prologue): Remove superfluous TARGET_68881
+ test; fix formatting.
+
+2003-10-26 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_compute_frame_layout): Swap reg_mask and
+ reg_rev_mask computation.
+ (m68k_output_function_prologue): Fix usage of current_frame (one typo
+ and one missing); use reg_rev_mask not reg_mask.
+ (m68k_output_function_epilogue): Fix usage of current_frame;
+ use fpu_rev_mask not fpu_mask.
+
+2003-10-26 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Eliminate
+ num_saved_regs, use current_frame.reg_no instead.
+
+2003-10-26 Bernardo Innocenti <bernie@develer.com>
+ Paul Dale <pauli@snapgear.com>
+
+ * doc/extend.texi (interrupt_handler): Add m68k to the
+ list of processors implementing it.
+ * doc/invoke.texi (-msep-data): Document new m68k option.
+ (-mno-sep-data): Likewise.
+ (-mid-shared-library): Likewise.
+ (-mno-id-shared-library): Likewise.
+ (-mshared-library-id): Likewise.
+
+2003-10-26 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2.c (_Unwind_GetGR): Avoid warning about unsigned
+ comparison.
+ (_Unwind_SetGR): Likewise.
+
+2003-10-26 Ottavio Campana <ottavio@campana.vi.it>
+
+ PR target/12690
+ * config/i386/mmintrin.h (_mm_set1_pi8): Fix comment.
+
+2003-10-26 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Move front
+ comment from here to...
+ (m68k_save_reg): ...here. Fix comment formatting.
+ (m68k_output_function_prologue): Fix comment formatting.
+ (m68k_output_function_epilogue): Likewise.
+ (const_method): Likewise.
+
+2003-10-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * toplev.c (default_get_pch_validity): Guard the use of
+ target_options with #ifdef TARGET_OPTIONS.
+ (default_pch_valid_p): Likewise.
+
+2003-10-26 Andreas Jaeger <aj@suse.de>
+ Zack Weinberg <zack@codesourcery.com>
+ Andreas Tobler <toa@pop.agri.ch>
+
+ * dwarf2out.c (output_cfi): Use HOST_WIDE_INT_PRINT.
+ (output_die): Likewise.
+ (print_die): Likewise.
+
+2003-10-26 Andreas Jaeger <aj@suse.de>
+
+ * tree.h (dwarf2out_def_cfa, dwarf2out_args_size,
+ dwarf2out_reg_save, new_loc_descr): Update prototypes for recent
+ dwarf2out.c change.
+
+ * toplev.c (default_pch_valid_p): Fix warning.
+
+2003-10-25 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_replace_rtx): Avoid allocating duplicate
+ RTL nodes. If an operator's operands are unchanged, return the
+ original argument unchanged.
+
+2003-10-26 Graham Stott <graham.stott@btinternet.com>
+
+ Fix bootstrap failure.
+ * expmed.c (store_bit_field): Don't compare bitsize against
+ modes with zero bit-size.
+
+ (extract_bit_field): Likewise
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * dwarf2out.c (dw_cfi_oprnd_struct): Offset is HOST_WIDE_INT.
+ (cfa_loc): Likewise.
+ (reg_save, stack_adjust_offset, queue_reg_save): Replace long by
+ HOST_WIDE_INT.
+ (args_size, old_args_size): change type to HOST_WIDE_INT.
+ (dwarf2out_def_cfa, dwarf2out_args_size,
+ dwarf2out_reg_save, new_loc_descr): offset is HOST_WIDE_INT.
+ (dw_val_struct): integers, unsigneds and offsets are HOST_WIDE_INT.
+ (add_AT_int, add_AT_unsigned, att_AT_offset, AT_int, AT_unsigned,
+ AT_offset): Use HOST_WIDE_INT.
+ (based_loc_descr): offset is HOST_WIDE_INT.
+ (add_data_member): Likewise.
+ (add_const_value_attribute): Simplify.
+
+2003-10-25 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_eax_live_at_start_p): New.
+ (ix86_expand_prologue): Save and restore eax around stack probe
+ if it's live.
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * cppcharset.c (one_utf8_to_utf32): Initialize 's' to silence warning.
+
+2003-10-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12712
+ * reg-stack.c (convert_regs_1): Create an arbitrary input stack
+ if the block has no predecessors.
+ (convert_regs_2): Document the problem with successors whose
+ only predecessor is the block to be processed.
+ (convert_regs): Don't create the arbitrary input stack here.
+
+2003-10-24 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c (struct mode_data): Add contained and next_cont
+ fields.
+ (complete_mode): Maintain linked list of modes that have a
+ given component.
+ (emit_mode_unit_size): Delete.
+ (emit_mode_nunits): New.
+ (emit_insn_modes_c): Update to match.
+ (emit_mode_adjustments): Propagate size and alignment
+ adjustments from component modes to their containers.
+ * machmode.h (mode_unit_size): Delete.
+ (mode_nunits): New.
+ (GET_MODE_NUNITS): Just return the value in the table.
+ (GET_MODE_UNIT_SIZE): Compute using GET_MODE_INNER and
+ GET_MODE_SIZE.
+ * expmed.c (store_bit_field, extract_bit_field): Can use a
+ plain move instruction if bitsize >= GET_MODE_BITSIZE of
+ destination/source mode, respectively.
+ * varasm.c (assemble_real): Write out the full size of the
+ constant, not just its bitsize.
+ (output_constant): Honor TYPE_MODE of TREE_REAL_CSTs.
+
+ * config/ia64/ia64-modes.def: Define XFmode as well as TFmode.
+ Use ADJUST_BYTESIZE and ADJUST_ALIGNMENT to set size and
+ alignment of XF and TF modes in compliance with ia64 ABIs.
+ Can now hardwire the format of both modes.
+ * config/ia64/ia64.c: Change TFmode to XFmode wherever appropriate.
+ (general_tfmode_operand, destination_tfmode_operand)
+ (tfreg_or_fp01_operand, spill_tfmode_operand): Rename to
+ general_xfmode_operand, destination_xfmode_operand,
+ xfreg_or_fp01_operand, spill_xfmode_operand respectively.
+ (ia64_init_builtins): Make TYPE_PRECISION of fpreg_type
+ and float80_type be 96 so they get XFmode. Use !TARGET_HPUX,
+ not INTEL_EXTENDED_IEEE_FORMAT, to decide how to define
+ __float128.
+ * config/ia64/ia64.h: Default TARGET_HPUX to 0.
+ Change TFmode to XFmode wherever appropriate. Remove all
+ references to INTEL_EXTENDED_IEEE_FORMAT.
+ (LONG_DOUBLE_TYPE_SIZE): Varies with TARGET_HPUX.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define (always 96).
+ (PREDICATE_CODES): Update to match function renames.
+ * config/ia64/ia64.md: Change TF to XF throughout; rename all
+ patterns to match. Remove all references to
+ INTEL_EXTENDED_IEEE_FORMAT. Update predicate calls to match
+ function renames.
+ * config/ia64/ia64-protos.c: Update all prototypes to match
+ renamed functions.
+ * config/ia64/hpux.h: Redefine TARGET_HPUX to 1.
+ Remove all references to INTEL_EXTENDED_IEEE_FORMAT.
+ * config/ia64/lib1funcs.asm: Add __divxf3 as new name for
+ __divtf3; keep old name for backward compatibility.
+ (L__compat): New section providing forwarding stubs for
+ __fixtfti, __fixunstfti, __floattitf.
+ * config/ia64/t-ia64: Add __compat to LIB1ASMFUNCS.
+
+2003-10-24 Geoffrey Keating <geoffk@apple.com>
+
+ PR 10757
+ * c-pch.c: Include target.h. Improve comments.
+ (struct c_pch_validity): Add target_data_length.
+ (pch_init): Add target's validity data.
+ (c_common_valid_pch): Check target's validity data.
+ * target-def.h (TARGET_GET_PCH_VALIDITY): New.
+ (TARGET_PCH_VALID_P): New.
+ (TARGET_INITIALIZER): Add new fields.
+ * target.h: Include tm.h.
+ (struct gcc_target): Add get_pch_validity, pch_valid_p.
+ * toplev.h (default_get_pch_validity): New prototype.
+ (default_pch_valid_p): New prototype.
+ * toplev.c (default_get_pch_validity): New routine.
+ (default_pch_valid_p): New routine.
+ * Makefile.in (TARGET_H): Add TM_H. Replace all users of
+ target.h with $(TARGET_H).
+ (c-pch.o): Add TARGET_H.
+ * doc/tm.texi (PCH Target): New node.
+ (TARGET_GET_PCH_VALIDITY): Document.
+ (TARGET_PCH_VALID_P): Document.
+
+2003-10-24 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Define a vpath for %.texi. Remove explicit $(docdir)
+ and $(docdir)/include from any *.texi dependencies.
+ ($(docobjdir)/%.dvi): Depend on stmp-docobjdir.
+ ($(docobjdir)/%.1): Depend on .pod instead of .texi.
+ ($(docobjdir)/%.7): Likewise.
+ (%.pod): New implicit rule.
+ (cpp.pod): New dependency only rule.
+ (gcc.pod): New intermediate rule with dependencies and commands.
+ (gfdl.pod): Likewise.
+ (fsf-funding.pod): Likewise.
+
+2003-10-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Remove special cases for svr4 and ptx, and
+ related code.
+ * fixinc/fixinc.ptx: Remove.
+ * fixinc/fixinc.svr4: Remove.
+
+2003-10-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (load_multiple_operation): Allow both SImode
+ and DImode if word_mode is DImode.
+ (store_multiple_operation): Likewise.
+ * config/s390/s390.md ("load_multiple", "store_multiple"): Likewise.
+ ("*load_multiple_di"): Allow only if word_mode == DImode.
+ ("movqi"): Use LLGC whenever TARGET_ZARCH.
+ ("fix_truncdfsi2"): Fix incorrect temporary size.
+ ("fix_truncsfsi2"): Likewise.
+ ("*bras_r", "*brasl_r", "*basr_r"): Remove predicate and constraint
+ string for function return value operand.
+ ("*bras_tls", "*brasl_tls", "*basr_tls"): Likewise.
+
+2003-10-24 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-parse.in (array_declarator): Use expr_no_commas.
+ Fixes PR c/11943.
+
+2003-10-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/linux.h: Wrap MD_FALLBACK_FRAME_STATE_FOR and
+ associated includes in #ifndef inhibit_libc.
+
+2003-10-24 Roger Sayle <roger@eyesopen.com>
+
+ * doc/libgcc.texi: Document some more of the libgcc API.
+
+2003-10-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_rtx_costs_1, case TARGET_THUMB): Adjust costs for
+ comparing a constant with small negative numbers and add costing
+ for constants in conjunction with AND.
+ (note_invalid_constants): Tidy previous change.
+ (thumb_cmp_operand): Tidy.
+ (thumb_cmpneg_operand): New function.
+ * arm.h (CONDITIONAL_REGISTER_USAGE): Don't use HI regs if optimizing
+ for size.
+ (FIRST_LO_REGNUM, FIRST_HI_REGNUM, LAST_HI_REGNUM): Define.
+ (PREDICATE_CODES): Add thumb_cmpneg_operand.
+ * arm.md (cbranchsi4): Convert to define_expand. Handle comparison
+ with a negative constant.
+ (cbranchsi4_insn): Matcher for cbranchsi4.
+ (cbranchsi4_scratch): Similar, but a scratch is available for
+ handling negative constants.
+ (movsi_cbranchsi4): New pattern.
+ (tstsi3_cbranch): Renamed from andsi3_cbranch_scratch, remove scratch
+ and use the TST instruction.
+ (andsi3_cbranch, orrsi3_cbranch, xorsi3_cbranch, cbranchne_decr1)
+ (addsi3_cbranch, subsi3_cbranch): Ensure that register preferencing
+ cannot see high regs or memory alternatives.
+ (bicsi3_cbranch_scratch, bicsi3_cbranch): New patterns.
+
+2003-10-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (note_invalid_constants): Try to extract the constant
+ pool value using avoid_constant_pool_reference; only use
+ get_pool_constant if that returns the original reference.
+
+2003-10-24 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12624
+ * varasm.c (notice_global_symbol): Disqualify global registers.
+
+2003-10-23 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11414
+ * loop.c (load_mems): Use redirect_jump to forward jumps from
+ the original loop end label to the new "loop sink" block's label.
+
+2003-10-23 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/12705
+ * optabs.c (expand_binop): When expanding complex operations
+ inline, always calculate result into a new temporary register.
+ Minor code clean-ups.
+
+2003-10-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * objc/lang-specs.h: Handle -print-objc-runtime-info.
+ * doc/invoke.texi (Objective-C Dialect Options): Document it.
+
+2003-10-24 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygwin.asm: Add copyright notice. Add comment
+ on why this code is needed.
+
+2003-10-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/clzhi2.c: Fix warnings.
+ * config/h8300/ctzhi2.c: Likewise.
+ * config/h8300/fixunssfsi.c: Likewise.
+ * config/h8300/parityhi2.c: Likewise.
+ * config/h8300/popcounthi2.c: Likewise.
+
+2003-10-23 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (option_map): Delete --target and --use-version.
+
+2003-10-23 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not
+ TARGET_POWREPC64.
+ (UNITS_PER_GPR_WORD): Define.
+ (HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD.
+ (HARD_REGNO_CALL_PART_CLOBBERED): Define.
+ (HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD.
+ (CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD.
+ * config/rs6000/rs6000.c (function_arg): Generate PARALLEL for
+ DFmode and DImode in 32-bit ABI / 64-bit computation mode.
+ (rs6000_emit_prologue): Select reg_mode and reg_size using
+ TARGET_32BIT, not TARGET_POWERPC64.
+ (rs6000_function_value): Generate PARALLEL for DImode in 32-bit
+ ABI / 64-bit computation mode
+
+2003-10-22 Andrew Haley <aph@redhat.com>
+
+ * toplev.c (output_file_directive): Allow for null input_name.
+
+2003-10-22 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * config/i386/i386.c (classify_argument): Handle SET_TYPE.
+
+2003-10-22 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in: In --enable-generated-files-in-srcdir option
+ handling, fix default case handling.
+ * configure: Regenerate.
+
+2003-10-22 Phil Edwards <phil@codesourcery.com>
+
+ * config.gcc: Update *-*-vxworks* generic hook and comments.
+ (arm-wrs-vxworks, i[4567]86-wrs-vxworks, mips-wrs-vxworks,
+ mips-wrs-windiss, sh-wrs-vxworks): New stanzas.
+ * genmultilib: Allow the MULTILIB_OSDIRNAMES to be mapped directly.
+ * config/svr4.h (SWITCH_TAKES_ARG): Undefine it before redefining it.
+ * config/windiss.h: New file.
+ * config/arm/t-vxworks: New file.
+ * config/arm/vxworks.h: New file.
+ * config/i386/t-vxworks: New file.
+ * config/i386/vxworks.h: New file.
+ * config/mips/t-vxworks: New file.
+ * config/mips/vxworks.h: New file.
+ * config/mips/windiss.h: New file.
+ * config/sh/t-vxworks: New file.
+ * config/sh/vxworks.h: New file.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_output_function_epilogue): Remove.
+ (h8300_saveall_function_p): New.
+ (h8300_insert_attributes): Insert the saveall attribute if
+ #pragma saveall is specified.
+ (h8300_attribute_table): Add saveall.
+ (TARGET_ASM_FUNCTION_EPILOGUE): Remove.
+ * doc/extend.texi: Mention the saveall attribute.
+
+2003-10-22 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (pedantic_lvalue_warning): Unconditionally warn of
+ deprecation of casts as lvalues.
+ * fixinc/inclhack.def (obstack_lvalue_cast): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/obstack.h: New test.
+
+2003-10-22 Andreas Schwab <schwab@suse.de>
+
+ PR target/12676
+ * config/m68k/m68k.c (output_addsi3): Fix range check to work on
+ LP64 platforms.
+
+2003-10-22 Jan Hubicka <jh@suse.cz>
+
+ * dwarf2out.c (dwarf2out_abstract_function): Use DW_AT to check
+ presence of DW_AT_inline.
+ (gen_subprogram_die): Likewise; do not abort instead of emitting
+ DW_AT_not_inline.
+
+2003-10-22 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_function_possibly_inlined_p): Be conservative when
+ global info is not ready.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/extend.texi: Mention H8S wherever H8/300H is mentioned.
+
+2003-10-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movstr_short_64", "movstr_short_31"): Merge ...
+ ("*movstr_short"): ... into this insn pattern.
+ ("movstr_short"): New expander.
+ ("*movstr_long_64"): Rename from "movstr_long_64", simplify.
+ ("*movstr_long_31"): Rename from "movstr_long_31", simplify.
+ ("movstr_long"): New expander.
+ ("clrstr_short_64", "clrstr_short_31"): Merge ...
+ ("*clrstr_short"): ... into this insn pattern.
+ ("clrstr_short"): New expander.
+ ("*clrstr_long_64"): Rename from "clrstr_long_64", simplify.
+ ("*clrstr_long_31"): Rename from "clrstr_long_31", simplify.
+ ("clrstr_long"): New expander.
+ ("cmpmem_short_64", "cmpmem_short_31"): Merge ...
+ ("*cmpmem_short"): ... into this insn pattern.
+ ("cmpmem_short"): New expander.
+ ("*cmpmem_long_64"): Rename from "cmpmem_long_64".
+ ("*cmpmem_long_31"): Rename from "cmpmem_long_31".
+ ("cmpmem_long"): New expander.
+ * config/s390/s390.c (s390_expand_movstr): Use new expanders.
+ (s390_expand_clrstr): Likewise.
+ (s390_expand_cmpmem): Likewise.
+
+2003-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ * c-pch.c (struct c_pch_validity): Add pch_init field.
+ (pch_init): Set it.
+ (c_common_valid_pch): Check it.
+
+2003-10-22 David Taylor <dtaylor@emc.com>
+
+ PR debug/12500
+ * dbxout.c (dbxout_typedefs): Use COMPLETE_OR_VOID_TYPE_P.
+
+2003-10-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/alpha/alpha.c (function_value [ENABLE_CHECKING]): Don't call
+ alpha_return_in_memory if no VALTYPE specified.
+
+2003-10-22 Jan Hubicka <jh@suse.cz>
+
+ PR debug/12389
+ * Makefile.in (dwarf2out.o): Depend on cgraph.h.
+ * cgraph.c (cgraph_function_possibly_inlined_p): New function.
+ * cgraph.h (cgraph_function_possibly_inlined_p): Declare.
+ (cgraph_global_info): Add flag inlined
+ * dwarf2out.c (gen_subprogram_die, gen_decl_die): Use
+ cgraph_function_possibly_inded_p
+ * cgraphunit.c (mark_inline): Set inlined flag.
+ * toplev.c (rest_of_decl_compilation): Call outlining_inline_function
+ only for possibly inlined functions.
+ * c-decl.c (duplicate_decls): Never output abstract DIE representing old
+ body of function.
+
+2003-10-22 Andrew Haley <aph@redhat.com>
+
+ * varasm.c (output_constructor): Make constructor annotation
+ conditional on ASM_COMMENT_START.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * tree.c (get_unwidened): Check TREE_UNSIGNED on the field's type.
+ (get_narrower): Likewise.
+
+ * stor-layout.c (layout_decl): Do packed field alignment for
+ bit-fields, too.
+
+2003-10-21 Eric Christopher <echristo@redhat.com>
+
+ * expr.c (convert_move): Use FLOAT_EXTEND for extensions.
+
+2003-10-21 Geoffrey Keating <geoffk@apple.com>
+
+ * c-pch.c: Add comments in various places.
+ (struct c_pch_validity): Add the lengths of various strings.
+ (host_machine): New static.
+ (target_machine): New static.
+ (get_ident): Bump version number.
+ (pch_init): Write out version, host, target validity data.
+ (c_common_valid_pch): Check version, host, target.
+ * Makefile.in (c-pch.o): Add version.h; define HOST_MACHINE and
+ TARGET_MACHINE.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * tree.h (IS_EXPR_CODE_CLASS): Use strchr.
+ (EXPR_P): New macro.
+
+2003-10-21 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.md (cmpxchg_acq_si): Mark operand 3 as DImode.
+ * config/ia64/ia64.c (ia64_expand_fetch_and_op,
+ ia64_expand_op_and_fetch): Make sure the REG for ar.ccv is
+ DImode. Use convert_move to load ar.ccv.
+ (ia64_expand_compare_and_swap): Likewise.
+ If expand_expr doesn't put 'old' and 'new' in the proper
+ modes, run them through convert_to_mode.
+
+2003-10-21 Eric Christopher <echristo@redhat.com>
+
+ * config/frv/frv.c (frv_adjust_field_align): Check DECL_ARTIFICIAL
+ for too large bitfields.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(docobjdir)/%.info): Honor BUILD_INFO.
+
+2003-10-21 Andrew Haley <aph@redhat.com>
+
+ * varasm.c (output_constructor): Annotate constructor.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(DESTDIR)$(infodir)/%.info): Conditionalize chmod
+ on existence of destination file.
+
+2003-10-21 Jan Hubicka <jh@suse.cz>
+
+ * haifa-sched.c (choose_ready): Initialize index.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build1): Fix off-by-one error.
+
+2003-10-21 Robert Millan <robertmh@gnu.org>
+
+ * config/i386/kfreebsdgnu.h: New. i386-*-kfreebsd-gnu definitions.
+ * config/kfreebsdgnu.h: New. *-*-kfreebsd-gnu definitions.
+ * config/t-kfreebsd-gnu: New. *-*-kfreebsd-gnu tmake_file.
+ * config.gcc: Add *-*-kfreebsd*-gnu and i[34567]86-*-kfreebsd*-gnu.
+
+2003-10-21 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * web.c: Fix various comments.
+
+2003-10-20 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/arm.c (arm_override_options): Set arm_constant_limit
+ to 2 instead of 1 when optimize_size is true. Gather code based on
+ optimize_size together. Add comment about XScale load latency.
+
+2003-10-21 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Remove
+ obsolete comments.
+
+2003-10-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Get parsedir and docobjdir from configure.
+ * configure.in: Recogonize --enable-generated-files-in-srcdir.
+ Pass along parsedir and docobjdir.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-generated-files-in-srcdir.
+
+2003-10-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Define $(docdir) before the Make-lang.in fragments are
+ included.
+
+2003-10-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-common.c (expand_tree_builtin): Ensure creal and cimag
+ functions do not return lvalues.
+
+2003-10-20 Jason Merrill <jason@redhat.com>
+
+ PR c/12553
+ * tree.c (build1) <ADDR_EXPR>: Set TREE_SIDE_EFFECTS
+ appropriately.
+
+ PR c/11446
+ * stor-layout.c (layout_decl): Fix alignment handling.
+
+2003-10-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/extend.texi: Deprecate casts as lvalues.
+
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Fix webizer pass ordering.
+
+ * cgraphunit.c (decide_is_function_needed): Fix test dealing
+ with functions implicitly made inline.
+
+ * cgraphunit.c (cgraph_decide_inlining_incrementally): New function.
+ (cgraph_finalize_function): Use it.
+ (cgraph_mark_inline): Allow incrmental decisions
+ * invoke.texi (max-inline-slope, min-inline-insns): Kill.
+ * params.def (PARAM_MAX_INLINE_SLOPE, PARAM_MIN_INLINE_INSNS): Kill.
+ * tree-inline.c (limits_allow_inlining): Kill.
+ (expand_call_inline): Always use unit-at-a-time path.
+
+2003-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * fixinc/inclhack.def (hpux11_snprintf): New edit.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/stdio.h: Add test for hpux11_snprintf.
+
+2003-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (install-info): Simplify.
+ ($(DESTDIR)$(infodir)/%.info): New rule.
+ * configure.in (target_list): Remove install-info.
+ * doc/.cvsignore (gcc.info*): Remove.
+ (gccint.info*): Likewise.
+ (gccinstall.info*): Likewise.
+ (cpp.info*): Likewise.
+ (cppinternals.info*): Likewise.
+ (*.info*): Add it.
+ * doc/sourcebuild.texi: Update description of install-info.
+ * objc/Make-lang.in (objc.install-info): Remove.
+
+2003-10-20 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/linux.h (TARGET_OS_CPP_BUILTINS): Define _ABIO32.
+ Use it in _MIPS_SIM definition.
+ * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Likewise.
+
+2003-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * config/i386/i386.c (print_reg): Abort if REGNO (x) is a
+ virtual register, but only if file == asm_out_file.
+ * config/i386/i386.h (HI_REGISTER_NAMES): Use "argp", not "",
+ for ARG_POINTER_REGNUM.
+
+2003-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.c (registered_builtin_types): New static.
+ (c_common_type_for_mode): Consult registered_builtin_types.
+ (c_register_builtin_type): Add type to registered_builtin_types.
+ * optabs.c (init_floating_libfuncs): Initialize libfuncs for
+ all MODE_FLOAT modes, not just the ones corresponding to
+ float_type_node, double_type_node, and long_double_type_node.
+
+2003-10-20 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.h (PREDICATE_CODES): Add normal_memory_operand.
+ * config/alpha/alpha-protos.h: Remove PREDICATE_CODES prototypes.
+
+2003-10-20 Dorit Naishlos <dorit@il.ibm.com>
+
+ * config/rs6000/rs6000.h: (rs6000_sched_insert_nops):
+ support new flag -minsert-sched-nops.
+ (DEFAULT_SCHED_FINISH_NOP_INSERTION_SCHEME): Define.
+ * config/rs6000/rs6000.c: (rs6000_sched_insert_nops):
+ support new flag -minsert-sched-nops.
+ (is_cracked_insn, is_microcoded_insn): New functions.
+ (rs6000_sched_finish): New function.
+ (rs6000_issue_rate): Return 5 for power4.
+ (get_next_active_insn, insn_terminates_group_p): New
+ functions.
+ (is_costly_group, force_new_group): New functions.
+ (redefine_groups, pad_groups): New functions.
+ (rs6000_variable_issue): Use new functions.
+ * doc/invoke.texi (-minsert-sched-nops): Document new
+ option.
+
+2003-10-20 David S. Miller <davem@redhat.com>
+
+ * config/sparc/sparc.md (type attribute): Add new insn types
+ fpa, fpm_pack, fgm_mul, fgm_pdist, and fgm_cmp for VIS.
+ (patterns emitting VIS insns): Use them.
+ * config/sparc/ultra1_2.md: Add VIS scheduling rules.
+ * config/sparc/ultra3.md: Likewise.
+
+2003-10-20 Falk Hueffner <falk@debian.org>
+
+ PR target/12654
+ * config/alpha/alpha.c (alpha_emit_conditional_branch): Don't do
+ comparison against constant by adjusting the argument except for
+ EQ and NE.
+
+2003-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ * config.gcc: Add support for arm926ejs, arm1026ejs, arm1136js,
+ arm1136jfs, and armv6j.
+ * config/arm/arm.c (FL_ARCH6J): New macro.
+ (FL_VFPV2): Likewise.
+ (all_cores): Add entries for arm926ejs, arm1026ejs, arm1136js,
+ and arm1136jfs.
+ (all_architectures): Add entry for armv6j.
+ (arm_override_options): Add entries for arm926ejs, arm1026ejs,
+ arm1136js, and arm1136jfs.
+ * config/arm/arm.h (TARGET_CPU_arm926ej_s): New macro.
+ (TARGET_CPU_arm1026ej_s): Likewise.
+ (TARGET_CPU_arm1136j_s): Likewise.
+ (TARGET_CPU_arm1136jf_s): Likewise.
+ * doc/invoke.texi: Document new ARM cores and architecture
+ variants.
+
+2003-10-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (toplev.o): Add value-prof.h dependency.
+ (value-prof.o): Add REGS_H dependency.
+ * common.opt (fprofile-values, fvpt): New.
+ * flags.h (flag_value_profile_transformations): Declare.
+ * opts.c (common_handle_option): Handle -fprofile_values and
+ -fvpt.
+ * profile.c (branch_prob): Don't remove death notes here.
+ * timevar.def (TV_VPT): New.
+ * value-prof.c: Include regs.h.
+ (insn_divmod_values_to_profile, gen_divmod_fixed_value, gen_mod_pow2,
+ gen_mod_subtract, divmod_fixed_value_transform,mod_pow2_value_transform,
+ mod_subtract_transform, value_profile_transformations): New.
+ (insn_values_to_profile): Call insn_divmod_values_to_profile.
+ (find_values_to_profile): Add dumps.
+ * value-prof.h (value_profile_transformations): Declare.
+ * toplev.c: Include value-prof.h.
+ (rest_of_handle_value_profile_transformations): New.
+ (enum dump_file_index): Add DFI_vpt.
+ (dump_file): Add vpt dump.
+ (flag_value_profile_transformations): New.
+ (lang_independent_options): Add flag_profile_values and
+ flag_value_profile_transformations.
+ (rest_of_compilation): Call
+ rest_of_handle_value_profile_transformations.
+ (process_options): Let -fvpt imply -fprofile-values.
+ * doc/invoke.texi (-fvpt): Document.
+
+2003-10-19 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (print_reg): Do not abort on certain registers.
+
+ PR optimization/12612
+ * reg-stack.c (subst_stack_regs_pat): Use st(1) for clobbers.
+ * i386.md (fpatan, fyl2x, fscale patterns and expanders): Use
+ match_scratch; avoid bogus paralles.
+
+ PR target/12674
+ * i386.c (ix86_function_regparm): Disable implicit register passing
+ conventions when profiling.
+
+2003-10-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/8178
+ * config/i386/i386.md (*movsi_zero): Delete.
+ (*ffs_no_cmove): Use ix86_expand_clear to zero the third operand.
+
+2003-10-19 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (fix_operator): New.
+ (divmod_operator): Tidy.
+ (alpha_emit_xfloating_cvt): Handle UNSIGNED_FIX.
+ * config/alpha/alpha.h (FIXUNS_TRUNC_LIKE_FIX_TRUNC): Remove.
+ (PREDICATE_CODES): Update.
+ * config/alpha/alpha.md (fix_truncdfsi_ieee): Use match_operator.
+ (fix_truncdfsi_internal, fix_truncdfdi_ieee): Likewise.
+ (fix_truncsfsi_ieee, fix_truncsfsi_internal): Likewise.
+ (fix_truncsfdi_ieee): Likewise.
+ (fix_truncdfdi2, fix_truncsfdi2): Turn into define_expand.
+ (fixuns_truncdfdi2, fixuns_truncsfdi2, fixuns_trunctfdi2): New.
+ * config/alpha/alpha-protos.h: Update.
+
+2003-10-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (INITIALIZE_TRAMPOLINE): Simplify.
+ * config/mips/mips.c (mips_load_got): Assume Pmode == ptr_mode.
+ * config/mips/mips.md (extendsidi2, *extendsidi2): Merge. Don't accept
+ constant operands.
+
+2003-10-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/extend.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+
+2003-10-18 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/arm.c (arm_override_options): Use arm_tune_xscale for
+ XScale optimizations not arm_arch_xscale.
+ * config/arm/arm.h (CONSTANT_ALIGNMENT_FACTOR, MOVE_RATIO): Likewise.
+
+2003-10-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (shift_count_operand): Add prototype.
+ * config/s390/s390.c (shift_count_operand): New function.
+ (s390_extra_constraint): Use it to implement 'Y' constraint.
+ (print_shift_count_operand): New function.
+ (print_operand): Use it to implement '%Y'.
+ * config/s390/s390.h (EXTRA_ADDRESS_CONSTRAINT): Add 'Y' constraint.
+ (PREDICATE_CODES): Add shift_count_operand.
+ * config/s390/s390.md ("rotldi3"): Merge alternatives,
+ using "shift_count_operand" predicate and "Y" constraint,
+ and "%Y" to output the combined shift count.
+ ("rotlsi3"): Likewise.
+ ("ashldi3", "*ashldi3_31", "*ashldi3_64"): Likewise.
+ ("ashrdi3", "*ashrdi3_31", "*ashrdi3_64", "*ashrdi3_cc_31",
+ "*ashrdi3_cc_64", "*ashrdi3_cconly_31", "*ashrdi3_cconly_64"): Likewise.
+ ("ashlsi3", "ashrsi3", "*ashrsi3_cc", "*ashrsi3_cconly"): Likewise.
+ ("lshrdi3", "*lshrdi3_31", "*lshrdi3_64"): Likewise.
+ ("lshrsi3"): Likewise.
+
+2003-10-18 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_epilogue): Add missing
+ argument to asm_fprintf statement.
+
+2003-10-18 Fariborz Jahanian <fjahanian@apple.com>
+
+ * rs6000.md: Separate TARGET_POWERPC64 patterns for TARGET_64BIT or TARGET_32BIT.
+ (ashrdisi3_noppc64) Generate more efficient code for 32-bit right-shift of
+ a "long long" argument.
+
+2003-10-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * final.c (final_scan_insn): Run FINAL_PRESCAN_INSNS on asm insns
+ as well.
+
+2003-10-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * rtl.h (rtl_size): Declare.
+ (rtunion): Remove rtwint.
+ (rtx_def): Replace 'fld' with a union of an rtunion or a HOST_WIDE_INT.
+ (RTX_HDR_SIZE, RTX_SIZE): New macros.
+ (RTL_CHECK1): Adjust for new rtx_def layout.
+ (RTL_CHECK2, RTL_CHECKC1, RTL_CHECKC2): Likewise.
+ (XWINT, XCWINT): Likewise. Access the rtx structure directly.
+ (X0WINT): Remove.
+ (X0ANY): New macro.
+ * rtl.def: Adjust comments for new rtx_def layout.
+ * ggc.h (ggc_alloc_rtx): Take the rtx code as argument, not the
+ number of slots.
+ * rtl.c (rtx_size): New array.
+ (rtx_alloc): Adjust call to ggc_alloc_rtx. Use RTX_HDR_SIZE.
+ (copy_rtx): Use RTX_HDR_SIZE. Adjust for new rtx_def layout.
+ (shallow_copy_rtx): Adjust call to ggc_alloc_rtx. Use RTX_SIZE.
+ * integrate.c (copy_rtx_and_substitute): Use X0ANY to copy '0' fields.
+ * emit-rtl.c (copy_most_rtx): Likewise.
+ (copy_rtx_if_shared): Use RTX_SIZE.
+ (copy_insn_1): Use RTX_HDR_SIZE. Adjust for new rtx_def layout.
+ * gengenrtl.c (gendef): Adjust ggc_alloc_rtx call. Use RTX_HDR_SIZE.
+ * gengtype.c (write_rtx_next): Use RTX_HDR_SIZE.
+ (adjust_field_rtx_def): Expect "rtx_def" to be a union rather than
+ an array. Adjust output for new rtx_def layout.
+ * ggc-page.c (RTL_SIZE): Use RTX_HDR_SIZE.
+ * reload1.c (eliminate_regs): Use RTX_SIZE.
+ * rtlanal.c (loc_mentioned_in_p): Adjust for new rtx_def layout.
+ * gdbinit.in (pi): Likewise.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * integrate.c (copy_decl_for_inlining): Revert previous patch.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * integrate.c (copy_decl_for_inlining): Fix copying of copies.
+
+2003-10-18 Roger Sayle <roger@eyesopen.com>
+
+ * libgcc.texi: Group multi-word types, such as "long double" and
+ "unsigned int", using braces in @deftypefn and @deftypefnx nodes.
+ Document __unord?f2 as returning a non-zero value, not just one.
+
+2003-10-18 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/t-mmix (CRTSTUFF_T_CFLAGS): Define.
+ ($(T)crti.o, $(T)crtn.o): Pass CRTSTUFF_T_CFLAGS here too.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/i386/k6.md (k6_alux): Use the 'mode' attribute instead of
+ match_operand.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_record_value_1): New fourth
+ parameter packed_p. Search for a DECL_PACKED field only if
+ packed_p is false. Pass packed_p recursively.
+ (function_arg_record_value_2): Likewise.
+ (function_arg_record_value): Update calls to
+ function_arg_record_value_1 and function_arg_record_value_2.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * cse.c (cse_insn) [src_folded]: Check that the tentative replacement
+ was successfully forced to memory before using the result.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/8178
+ * config/i386/i386.md (*movsi_zero): New insn to set
+ a register to zero on TARGET_USE_MOV0 targets.
+
+2003-10-18 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (Makefile): Depend on the all Make-lang.in fragments.
+ (POSTSTAGE1_FLAGS_TO_PASS): Pass down MAKEINFO and MAKEINFOFLAGS.
+
+2003-10-17 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/invoke.texi (gcse-las): Fix typo.
+
+2003-10-17 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * doc/install.texi: Remove first part of the sentence for
+ zsh not working. Change gcc to GCC.
+
+ PR bootstrap/12546
+ * doc/install.texi: Document that zsh does not work when
+ configuring gcc.
+
+2003-10-17 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/ptx4.h: Switch to DWARF 2; update comments.
+
+2003-10-17 Segher Boessenkool <boessen@de.ibm.com>
+ Hartmut Penner <hpenner@de.ibm.com>
+
+ PR 10404, partial 11591, partial 11601
+ * config/rs6000/altivec.md ("altivec_dst", "altivec_dstt",
+ "altivec_dstst", "altivec_dststt", "altivec_lvsl", "altivec_lvsr",
+ "altivec_lvebx", "altivec_lvehx", "altivec_lvewx", "altivec_lvxl",
+ "altivec_lvx", "altivec_stvx", "altivec_stvxl", "altivec_stvebx",
+ "altivec_stvehx", "altivec_stvewx"): Use a memory_operand.
+ * config/rs6000/rs6000.c (altivec_expand_lv_builtin): New function.
+ (altivec_expand_stv_builtin): Adjust for the memory_operand.
+ (altivec_expand_builtin): Call altivec_expand_lv_builtin.
+ (altivec_init_builtins): Use `long int' for memory offsets.
+
+2003-10-17 Jan Hubicka <jh@suse.cz>
+
+ * opts.c (common_handle_option): Handle OPT_fweb
+ * invoke.texi (-fweb): Add missing parts of documentation.
+
+2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/linux.h (FUNCTION_NAME_ALREADY_DECLARED): Undef
+ before redefinition.
+
+2003-10-17 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * common.opt: Add description of the new -fgcse-las flag.
+ * flags.h (flag_gcse_las): Declaration of global flag_gcse_las.
+ * gcse.c (hash_scan_set): Handle the case of store expression and
+ insert the memory expression to the hash table, this way we make it
+ possible to discover redundant loads after stores and remove them.
+ (pre_insert_copy_insn): moved the call to update_ld_motion_stores,
+ to pre_insert_copies, it is not the correct place to call it after
+ adding stores to be in the available expression hash table.
+ (pre_insert_copies): Added the call to update_ld_motion_stores when
+ one or more copies were inserted.
+ * opts.c (common_handle_option): Handle the -fgcse-las flag.
+ * toplev.c (flag_gcse_las): Initialization of flag_gcse_las.
+
+ * doc/invoke.tex: Document new -fgcse-las flag.
+
+2003-10-18 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/crtsavres.asm: Correct alignment of powerpc64 code
+ for posterity, then remove it.
+
+2003-10-17 Richard Earnshaw <rearnsha@arm.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/arm/arm.c (use_return_insn): Not a single instruction, if
+ there's a frame pointer.
+ (arm_output_epilogue): Protect stack pointer from being corrupted
+ on interrupt.
+
+2003-10-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * ifcvt.c (noce_try_addcc): Handle ifs with 'else' case.
+
+2003-10-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (simplify_set): Do not clear out undobuf.other_insn
+ already set elsewhere.
+
+2003-10-17 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/i386/i386.c (ix86_expand_prologue): Use
+ gen_allocate_stack_worker.
+
+2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (mips-sgi-irix6*o32): Only enable use_collect2
+ without gas.
+ (mips-sgi-irix6*): Likewise.
+
+ * config/mips/iris6gas.h: New file.
+ * gcc/config.gcc (mips-sgi-irix6*): Use it.
+
+ * config/mips/mips.h (TARGET_IRIX): Provide default.
+ (TARGET_IRIX5): Likewise.
+ (TARGET_SGI_O32_AS): Likewise.
+ * config/mips/iris5.h (TARGET_IRIX): Redefine as 1.
+ (TARGET_IRIX5): Likewise.
+ * config/mips/iris6.h (TARGET_IRIX6): Remove.
+ (TARGET_IRIX5): Redefine as 0.
+
+ * config/mips/mips.c (mips_output_external): Test for IRIX 6 O32
+ linker workaround with TARGET_IRIX and mips_abi instead of
+ ASM_OUTPUT_UNDEF_FUNCTION.
+ (mips_file_end): Inline old ASM_OUTPUT_UNDEF_FUNCTION definition,
+ testing TARGET_IRIX and mips_abi explicitly.
+ * config/mips/iris5.h (ASM_OUTPUT_UNDEF_FUNCTION): Remove.
+ * config/mips/iris6.h (ASM_OUTPUT_UNDEF_FUNCTION): Remove undef.
+
+ * config/mips/mips.c (irix_output_external_libcall): Renamed from
+ mips_output_external_libcall.
+ Use new TARGET_IRIX in guard.
+ * config/mips/mips-protos.h (irix_output_external_libcall): Match
+ this.
+ * config/mips/iris5.h (TARGET_ASM_EXTERNAL_LIBCALL): Likewise.
+
+ * config/mips/iris5gas.h (HAVE_GAS_SHF_MERGE): Update comment.
+ Define as 0.
+
+ * config/mips/iris6.h (FUNCTION_NAME_ALREADY_DECLARED): Define
+ depending on mips_abi.
+ * config/mips/linux.h (FUNCTION_NAME_ALREADY_DECLARED): Define as 1.
+ * config/mips/mips.c (mips_output_function_prologue): Test
+ FUNCTION_NAME_ALREADY_DECLARED at runtime.
+ (mips_output_function_epilogue): Likewise.
+ (build_mips16_function_stub): Likewise.
+ (build_mips16_call_stub): Likewise.
+ * config/mips/mips.h (FUNCTION_NAME_ALREADY_DECLARED): Provide
+ default.
+
+ * config/mips/iris6.h (DWARF2_UNWIND_INFO): Don't define for native
+ IRIX 6 O32 assembler.
+ (SUBTARGET_CC1_SPEC): Enforce mips2 ISA with O32 ABI.
+ (TARGET_OS_CPP_BUILTINS): Define _ABIO32, use it to define
+ _MIPS_SIM for O32 ABI.
+ (DWARF2_FRAME_INFO): Don't define for native IRIX 6 O32 assembler.
+ (ASM_DECLARE_FUNCTION_NAME): Integrate mips.h version.
+ (ASM_DECLARE_FUNCTION_SIZE): Move undef before redefinition.
+ Integrate O32 version.
+ (SUBTARGET_ASM_SPEC): Handle -mabi=32.
+ (SUBTARGET_ASM_DEBUGGING_SPEC): Add mdebug_asm_spec for gas with
+ O32 ABI.
+ (BSS_SECTION_ASM_OP_32): Define.
+ (BSS_SECTION_ASM_OP_64): Likewise.
+ (BSS_SECTION_ASM_OP): Define differently for O32 and N32/N64 ABIs
+ using them.
+ (TARGET_ASM_NAMED_SECTION): Reflect renaming.
+ Move up to allow override for O32 ABI without GNU as.
+ (EH_FRAME_SECTION_NAME): Define explicitly.
+ (MUST_USE_SJLJ_EXCEPTIONS): Define.
+ [_MIPS_SIM == _ABIO32 && !GAS] (CTORS_SECTION_ASM_OP,
+ DTORS_SECTION_ASM_OP): Dummy definitions.
+ (TARGET_ASM_NAMED_SECTION): Undef statically.
+ (EH_FRAME_SECTION_NAME): Likewise.
+ (ASM_OUTPUT_FILENAME): Integrate mips.h version.
+ (LINK_SPEC): Only use default options -call_shared -no_unresolved
+ without -r.
+ Don't pass -init, -fini with -mabi=32.
+ (COLLECT_PARSE_FLAG): Define.
+
+ * config/mips/mips.c (iris6_asm_named_section_1): Changed guard to
+ TARGET_IRIX.
+ Renamed to use irix_ prefix.
+ (iris6_asm_named_section): Likewise.
+ (iris_section_align_entry_eq): Likewise.
+ (iris_section_align_entry_hash): Likewise.
+ (iris6_file_start): Likewise.
+ (iris6_section_align_1): Likewise.
+ (iris6_file_end): Likewise.
+ (iris6_section_type_flags): Likewise.
+ (iris_section_align_htab): Likewise.
+ (iris_orig_asm_out_file): Likewise.
+ [TARGET_IRIX] (TARGET_ASM_FILE_START): Reflect rename.
+ (TARGET_ASM_FILE_END): Likewise.
+ (TARGET_SECTION_TYPE_FLAGS): Likewise.
+
+ * config/mips/mips.c [TARGET_IRIX5 && !TARGET_IRIX6]
+ (TARGET_ASM_UNALIGNED_HI_OP): Use runtime initialization in
+ override_options instead.
+ (TARGET_ASM_UNALIGNED_SI_OP): Likewise.
+ (TARGET_ASM_UNALIGNED_DI_OP): Likewise.
+ * config/mips/mips.c (override_options) [USE_COLLECT2]: Restore
+ flag_gnu_linker to defaults without USE_COLLECT2 for non-IRIX O32
+ assemblers.
+ Likewise for constructor/destructor handling.
+ (override_options): Handle IRIX O32 assembler quirks.
+ [TARGET_IRIX] (irix_asm_named_section): Handle O32 ABI with and
+ without gas.
+ (mips_file_start): Use new TARGET_IRIX.
+ (mips_declare_object_name): No special processing for IRIX O32
+ assembler.
+ (mips_finish_declare_object): Likewise.
+ (irix_asm_output_align): Renamed from iris6_asm_output_align.
+ Don't record alignment for O32 ABI.
+ (irix_file_start): Renamed from iris6_file_start.
+ Return early for O32 ABI.
+ (irix_file_end): Renamed from iris6_file_end.
+ Don't emit .section directives for O32 ABI.
+ * config/mips/iris6.h (ASM_OUTPUT_ALIGN): Reflect renaming.
+ * config/mips/mips-protos.h (irix_asm_output_align): Likewise.
+
+ * config/mips/t-iris6 (MULTILIB_OPTIONS): Add mabi=32.
+ (MULTILIB_OSDIRNAMES): Likewise.
+
+2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * collect2.c (COLLECT_PARSE_FLAG): Provide default.
+ (main): Use it.
+ * doc/tm.texi (COLLECT_PARSE_FLAG): Document it.
+
+2003-10-17 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm-modes.def (CC_Nmode): New condition code mode.
+ * arm.c (thumb_condition_code): Delete.
+ (arm_select_cc_mode): Handle single-bit test for Thumb.
+ (arm_print_operand, cases 'd' and 'D'): Don't special case the
+ condition code logic for Thumb.
+ (get_arm_condition_code): Handle CC_Nmode.
+ (thumb_cbrch_target_operand): New function.
+ * arm.h (PREDICATE_CODES): Add thumb_cbrch_target_operand.
+ * arm-protos.h (thumb_cbrch_target_operand): Add prototype.
+ * arm.md: Add Thumb split patterns for zero_extract and
+ sign_extract.
+ (tbit_cbranch, andsi3_cbranch_scratch, andsi3_cbranch)
+ (orrsi3_cbranch_scratch, orrsi3_cbranch, xorsi3_cbranch_scratch)
+ (xorsi3_cbranch, addsi3_cbranch, addsi3_cbranch_scratch)
+ (subsi3_cbranch, subsi3_cbranch_scratch): New Thumb patterns.
+ (cbranchne_decr1): Re-work to use CC_Nmode.
+
+ * arm.c (thumb_expand_epilogue): Add clobbers of registers restored
+ by the return instruction. Add a use of the link register if it
+ wasn't stored.
+
+2003-10-17 Richard Earnshaw <rearnsha@arm.com>
+
+ * flow.c (init_propagate_block_info): Don't abort if a conditional
+ jump is not a comparison of a register. Instead, just don't record
+ conditional life information.
+
+2003-10-16 Jan Hubicka <jh@suse.cz>
+
+ PR optimization/12630
+ * pa.md (movstrsi, movstrsi_internal): Use match_scratch in clobbers
+ for operands 7 and 8.
+
+2003-10-16 Kelley Cook <kcook@gcc.gnu.org>
+
+ * objc/Make-lang.in (objc-parse.o): Honor $(parsedir) for objc-parse.c.
+
+2003-10-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (ASM_OUTPUT_DEF_FROM_DECLS): Define.
+
+ * config/i386/winnt.c (gen_stdcall_suffix): Make static
+ (gen_fastcall_suffix): Likewise.
+ (i386_pe_dllexport_p): Likewise.
+ (i386_pe_dllimport_p): Likewise.
+ (i386_pe_mark_dllexport): Likewise.
+ (i386_pe_mark_dllimport): Likewise.
+ (i386_pe_asm_named_section): Fix formatting.
+
+2003-10-16 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Add snprintf to gcc_AC_CHECK_DECLS list.
+ * system.h: Declare snprintf if necessary.
+ * configure, config.in: Regenerate.
+
+2003-10-15 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_va_arg): Only align vector
+ arguments if TARGET_ALTIVEC_ABI.
+
+2003-10-15 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_memcpy, fold_builtin_mempcpy,
+ fold_builtin_memmove, fold_builtin_strcpy, fold_builtin_strncpy,
+ fold_builtin_memcmp, fold_builtin_strcmp, fold_builtin_strncmp):
+ New functions.
+ (expand_builtin_memcpy): Use integer_zerop instead of testing
+ host_integerp and tree_low_cst directly. Move misapplied hunk
+ for optimization wher SRC and DEST point to the same location.
+ (expand_builtin_mempcpy): From here.
+ (expand_builtin_memmove): Use integer_zerop instead of testing
+ host_integerp and tree_low_cst_directly.
+ (expand_builtin_memset): Likewise.
+ (expand_builtin_memcmp): Likewise (and for integer_onep).
+ (expand_builtin_strncmp): Likewise.
+ (fold_builtin): Call the appropriate fold_builtin_foo functions
+ to optimize memcpy, mempcpy, memmove, strcpy, strncpy, memcmp,
+ strcmp and strncmp.
+
+2003-10-15 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin-protos.h (machopic_non_lazy_ptr_name): Delete
+ prototype. Clean up some whitespace.
+ * config/darwin.c: Use gen_rtx_FOO (...) rather than
+ gen_rtx (FOO, ...).
+ (machopic_non_lazy_ptr_name): Make static.
+ (name_needs_quotes): Allow '.' and '$' unquoted.
+ (machopic_legitimize_pic_address): Improve codegen in dynamic-no-pic
+ case.
+
+2003-10-15 Gábor Lóki <alga@rgai.hu>
+
+ * fold-const.c (tree_swap_operands_p): Disable some features
+ when optimizing for size.
+
+2003-10-15 David Daney <ddaney@avtrex.com>
+
+ * config/mips/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New
+ * config/mips/mips.h (DWARF_FRAME_REGNUM): Fixed to allow unwind
+ from leaf functions.
+ (DWARF_FRAME_RETURN_COLUMN): Ditto.
+ (SIGNAL_UNWIND_RETURN_COLUMN): New, used
+ by MD_FALLBACK_FRAME_STATE_FOR.
+ * testsuite/gcc.dg/cleanup-9.c: Added mips*-*-linux* target.
+
+2003-10-15 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c: Include hashtab.h.
+ (modes_by_name, hash_mode, eq_mode, struct mode_adjust)
+ (adj_bytesize, adj_alignment, adj_format, new_adjust)
+ (_ADD_ADJUST, ADJUST_BYTESIZE, ADJUST_ALIGNMENT, ADJUST_FORMAT)
+ (print_maybe_const_decl, emit_mode_adjustments): New.
+ (known_modes): Rename to modes.
+ (find_mode): Kill class argument; look up in hash table.
+ (new_mode): Insert into hash table also.
+ (new_adjust): New.
+ (reset_float_format, make_partial_integer_mode)
+ (make_vector_mode): Tweak error reporting.
+ (reset_float_format): Correct type of fourth argument.
+ (emit_insn_modes_h): Add #defines to help make mode_size,
+ mode_base_align, and real_format_for_mode conditionally const.
+ (emit_mode_size, emit_mode_base_align): Use print_maybe_const_decl.
+ (emit_real_format_for_mode): Likewise, but temporarily disabled.
+ (emit_insn_modes_c): Call emit_mode_adjustments.
+ (main): Initialize modes_by_name.
+ * Makefile.in: Update dependencies.
+ * machmode.def: Document EXPR arguments and new ADJUST_* statements.
+ * machmode.h: Use CONST_MODE_SIZE and CONST_MODE_BASE_ALIGN in
+ declarations of mode_size and mode_base_align. Declare
+ init_adjust_machine_modes.
+ * toplev.c (backend_init): Call init_adjust_machine_modes.
+
+2003-10-15 Olivier Hainque <hainque@act-europe.fr>
+
+ * genmodes.c (calc_wider_mode): Allocate enough room for all the
+ entries we'll possibly assign in the sort buffer.
+
+2003-10-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.gcc (s390x-ibm-tpf*): New target.
+ * doc/install.texi: Document it.
+ * config/s390/t-tpf: New file.
+ * config/s390/tpf.h: New file.
+
+2003-10-15 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/12598
+ * config/cris/cris.md (define_split "*mov_sidesi_biap_mem"+1)
+ (define_splits "*mov_sidesi_mem"+1, "casesi"+9, +10, +11, +12):
+ Use cris_mem_op and replace_equiv_address, not gen_rtx_MEM.
+ ("call", "call_value", define_split "*mov_sidesi_mem"+19, +20)
+ (define_split "*mov_sidesi_mem"+21, +22, +23, +24, +25, +26, +27)
+ (define_split "*mov_sidesi_mem"+28, +29, +30): Use
+ replace_equiv_address, not gen_rtx_MEM.
+ * config/cris/cris.c (cris_mem_op): New match_operator function.
+ (cris_notice_update_cc): Use replace_equiv_address, not
+ gen_rtx_MEM.
+ * config/cris/cris.h (PREDICATE_CODES): Add cris_mem_op.
+
+2003-10-15 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (MASK_SEP_DATA, TARGET_SEP_DATA,
+ MASK_ID_SHARED_LIBRARY, TARGET_ID_SHARED_LIBRARY): Move
+ definitions after the other flags.
+
+2003-10-14 Ziemowit Laski <zlaski@apple.com>
+
+ * c-parse.in (methoddef, methodproto): Call objc_add_method()
+ instead of add_method().
+ * objc/objc-act.c (objc_check_decl): Do not check for
+ constant_string_type.
+ (add_method): Rename to objc_add_method().
+ (really_start_method): Call objc_add_method() instead of
+ add_method().
+ * objc/objc-act.h (add_method): Rename to objc_add_method().
+
+2003-10-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_alc_comparison): Add prototype.
+ (s390_slb_comparison): Likewise.
+ * config/s390/s390.c (s390_alc_comparison, s390_slb_comparison):
+ New functions.
+ * config/s390/s390.h (PREDICATE_CODES): Add s390_alc_comparison
+ and s390_slb_comparison.
+ * config/s390/s390.md ("*adddi3_31", "*subdi3_31"): Do not use on
+ zSeries machines.
+ ("*adddi3_31z", "*subdi3_31z"): New insns.
+ ("*adddi3_alc_cc", "*adddi3_alc", "*subdi3_slb_cc", "*subdi3_slb",
+ "*addsi3_alc_cc", "*addsi3_alc", "*subsi3_slb_cc", "*subsi3_slb"):
+ New insns.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Clean up some feedback echoes.
+ * configure: Regenerate.
+
+ * aclocal.m4: Properly quote names of macros being defined.
+
+ * config.gcc (am33_2.0-*-linux*): Use t-slibgcc-elf-ver.
+
+2003-10-14 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.c (ia64_expand_call): Force function address
+ to DImode.
+ * config/ia64/ia64.md (call_gp): Put DImode on operand 0.
+
+2003-10-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("muldf3", "*muldf3", "*muldf3_ibm",
+ "mulsf3", "*mulsf3", "*mulsf3_ibm"): Do not clobber CC.
+ ("divdf3", "*divdf3", "*divdf3_ibm", "divsf3", "*divsf3",
+ "*divsf3_ibm"): Likewise.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc, config/m68hc11/t-m68hc11-gas: Replace uses of
+ target_alias with target_noncanonical.
+
+2003-10-14 Geoffrey Keating <geoffk@apple.com>
+
+ * expr.c (block_move_libcall_safe_for_call_parm): Clean up,
+ and add case for machines where outgoing register parameters
+ get stack space.
+
+ * config/darwin.c (machopic_indirect_data_reference): Use a scratch
+ register when generating indirect address.
+
+2003-10-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_addimm_operand): MODE arguemnt is unused.
+ * arm.md (cbranchne_decr1): Fix bootstrap warning.
+
+2003-10-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (alpha_pthread_gcc): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/pthread.h [ALPHA_PTHREAD_GCC_CHECK]: New
+ testcase.
+ Fixes PR bootstrap/9330.
+
+2003-10-13 Eric Christopher <echristo@redhat.com>
+
+ * config/frv/frv.c (frv_adjust_field_align): Redo check for
+ too wide bitfields.
+ (frv_hard_regno_mode_ok): Add SPR_P and AP_FIRST.
+ * config/frv/frv.h (FUNCTION_PROFILER): Remove abort call.
+ (SBSS_SECTION_ASM_OP): Remove.
+ (EXTRA_SECTIONS): Remove in_sbss.
+ (EXTRA_SECTION_FUNCTIONS): Remove SBSS_SECTION_FUNCTION.
+ (SBSS_SECTION_FUNCTION, sbss_section): Remove.
+ (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Change sbss_section to
+ named_section.
+
+2003-10-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in, configure.in, config.host, mkheaders.in: Replace
+ uses of ${target_alias} for directory names (and other places which
+ won't like the empty string) with ${target_noncanonical}. Introduce
+ call early in configure.in to _GCC_TOPLEV_NONCANONICAL_TARGET so it's
+ available.
+ * configure: Regenerate.
+
+2003-10-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/iwmmxt.md (cond_iwmmxt_movsi_insn): New pattern.
+ * config/arm/arm.md: For splits which rely on conditional moves,
+ remove ! TARGET_IWMMXT condition.
+
+2003-10-13 David S. Miller <davem@redhat.com>
+
+ * ifcvt.c (num_removed_blocks): Rename to num_true_changes.
+ (find_cond_trap): Always increment if we emit a conditional
+ trap insn.
+
+2003-10-13 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (BUILD_RTL): Replace $(BUILD_PREFIX)insn-modes.o
+ with min-insn-modes.o.
+ (STAGESTUFF): Add min-insn-modes.c.
+ (genobjs): Add genmodes.o.
+ (print-rtl.o, print-rtl1.o): Depend on $(TM_P_H).
+ (insn-modes.o): Depend on $(TM_H) not $(GTM_H); also real.h.
+ (min-insn-modes.c, min-insn-modes.o): New rules.
+ (s-modes): Also generate min-insn-modes.c.
+ ($(BUILD_PREFIX_1)insn-modes.o): Kill.
+ * genmodes.c (struct mode_data): Add format field.
+ (blank_mode, validate_mode, complete_mode): Update to match.
+ (make_scalar_mode): Separate into make_int_mode and make_float_mode.
+ (_SCALAR_MODE): Kill.
+ (FLOAT_MODE, FRACTIONAL_FLOAT_MODE): Add format argument.
+ (emit_insn_modes_c_header): Adjust.
+ (emit_min_insn_modes_c_header, emit_real_format_for_mode)
+ (emit_min_insn_modes_c): New functions.
+ (emit_insn_modes_c): Call emit_real_format_for_mode.
+ (main): Add -m option to generate min-insn-modes.c.
+ * machmode.h: Update documentation. Add format argument to
+ all uses of FLOAT_MODE.
+ * real.c: Don't define real_format_for_mode here.
+
+ * dwarfout.c: Move default definition of PRINT_REG...
+ * defaults.h: ...here.
+ * print-rtl.c: Include tm_p.h.
+ (DEBUG_PRINT_REG, DEBUG_REGISTER_NAMES, debug_reg_names, reg_names):
+ Kill.
+ (print_rtx): Use PRINT_REG, not DEBUG_PRINT_REG. But surround
+ this entire block with #ifndef GENERATOR_FILE.
+ * regclass.c: Unconditionally define reg_names.
+ * config/mips/mips.h, config/rs6000/rs6000.h, config/sh/sh.h
+ Don't define DEBUG_REGISTER_NAMES.
+ * config/rs6000/darwin.h: Don't use DEBUG_REGISTER_NAMES in
+ redefinition of REGISTER_NAMES.
+ * config/i386/i386.h: Don't define DEBUG_PRINT_REG.
+
+ * combine.c: Change all preprocessor conditionals on
+ EXTRA_CC_MODES to use SELECT_CC_MODE instead; rearrange a bit
+ for clarity.
+ * genopinit.c: Remove mention of EXTRA_CC_MODES in comment.
+ * configure.in: Don't define EXTRA_CC_MODES.
+ * configure, config.in: Regenerate.
+ * doc/tm.texi: Remove documentation of EXTRA_CC_MODES.
+
+ * config/arc/arc.c, config/m32r/m32r.c, config/sparc/sparc.c:
+ May assume that GET_MODE_CLASS is accurate for extra CC modes
+ at all times.
+
+ * config/i860/i860.h (INIT_CUMULATIVE_ARGS): Pass correct
+ number of arguments to aggregate_value_p.
+
+ * genmodes.c (RESET_FLOAT_FORMAT, reset_float_format): New.
+ * machmode.def: Explain ARCH-modes.def. Document
+ RESET_FLOAT_FORMAT. Improve commentary on various mode
+ clusters. Do not define OI, PQI, PHI, PSI, PDI, QF, HF, TQF,
+ XF, or TF modes here. Remove backward-compatibility
+ definition of CC.
+
+ * config/alpha/alpha-modes.def: New file; define TF mode.
+ * config/arc/arm-modes.def: Define XF mode.
+ * config/c4x/c4x-modes.def: Define QF and HF modes. Unset
+ float format for SF and DF modes.
+ * config/dsp16xx/dsp16xx-modes.def: New file; define HF mode.
+ * config/i386/i386-modes.def: Define XF and TF modes.
+ * config/i960/i960-modes.def: Define TF mode.
+ * config/ia64/ia64-modes.def: Define TF and OI modes.
+ * config/m68k/m68k-modes.def: New file; define XF mode.
+ * config/mips/mips-modes.def: New file; define TF mode, reset
+ formats for SF and DF modes.
+ * config/pa/pa-modes.def: Define TF mode.
+ * config/rs6000/rs6000.c: Define TF and PSI modes.
+ * config/s390/s390-modes.def: Define OI mode.
+ * config/sh/sh-modes.def: New file; define PSI mode.
+ * config/sparc/sparc-modes.def: Define TF mode.
+ * config/vax/vax-modes.def: New file; reset formats for SF and
+ DF modes.
+
+ * config/c4x/c4x.c (c4x_override_options): No need to mess
+ with real_format_for_mode or set REAL_MODE_FORMATs.
+ (c4x_immed_int_constant): Don't apply GET_MODE_CLASS to rtx
+ variable.
+ * config/i386/i386.c (override_options): No need to set
+ REAL_MODE_FORMATs here.
+ * config/i960/i960.c (i960_initialize): Likewise.
+ * config/m68k/m68k.c (m68k_override_options): Likewise.
+ * config/ia64/ia64.c (ia64_override_options): Set REAL_MODE_FORMAT
+ for TFmode only if not the default.
+ * config/mips/mips.c (override_options): Likewise.
+ * config/vax/vax.c (override_optionms): Set REAL_MODE_FORMAT for
+ DFmode only if not the default.
+
+ * config/i370/i370.h (RET_REG): Don't consider TFmode.
+ * config/m68hc11/m68hc11.c (print_operand): Don't consider XFmode.
+ * config/dsp16xx/dsp16xx.c (hard_regno_mode_ok): #if 0 out use
+ of modes that don't appear anywhere in the machine description.
+
+ * config/arc/arc-modes.def, config/arm/arm-modes.def
+ * config/c4x/c4x-modes.def, config/frv/frv-modes.def
+ * config/i386/i386-modes.def, config/i960/i960-modes.def
+ * config/ia64/ia64-modes.def, config/mmix/mmix-modes.def
+ * config/pa/pa-modes.def, config/pdp11/pdp11-modes.def
+ * config/rs6000/rs6000-modes.def, config/s390/s390-modes.def
+ * config/sparc/sparc-modes.def: Convert to new style for
+ declaring extra CC modes.
+
+2003-10-13 Zack Weinberg <zack@codesourcery.com>
+
+ * cpplex.c (_cpp_clean_line): In the common case of a line
+ with no trigraphs and no \-newline, avoid writing to memory.
+ (_cpp_skip_block_comment): Use a local 'cur' pointer instead
+ of the buffer member. Make c an uchar to avoid unnecessary
+ sign extensions.
+
+2003-10-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove unnecessary test.
+ * configure: Regenerate.
+
+ * configure.in: Fix grammatical error. Move UWIN host error to...
+ * config.host: Here.
+ * configure: Regenerate.
+
+2003-10-13 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*fmadddf4", "*fmsubdf4", "*fmaddsf4",
+ "*fmsubsf4"): Insns are now dependent on TARGET_FUSED_MADD instead
+ of flag_unsafe_math_optimizations.
+ * config/s390/s390.h ("MASK_NO_FUSED_MADD", "TARGET_NO_FUSED_MADD",
+ "TARGET_FUSED_MADD", "TARGET_SWITCHES"): Introduced new target flags
+ fused-madd and no-fused-madd.
+ * doc/invoke.texi: Documented the new options fused-madd and
+ no-fused-madd for S/390.
+
+2003-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Choose
+ MASK_ALIGN_NATURAL if rs6000_alignment_string not given. Don't
+ assign DEFAULT_ABI.
+ (ADJUST_FIELD_ALIGN, ROUND_TYPE_ALIGN): Update comment.
+ * config/rs6000/rs6000.c: Formatting.
+ (rs6000_parse_alignment_option): Only set rs6000_alignment_flags
+ when rs6000_alignment_string given.
+
+2003-10-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12538
+ * config/sparc/sparc.c (MUST_SAVE_REGISTER): Delete.
+ (sparc_flat_must_save_register_p): New function to decide whether
+ a register must be saved/restored in the function prologue/epilogue.
+ (sparc_flat_compute_frame_size): Use it instead of MUST_SAVE_REGISTER.
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/avr/avr.c, config/avr/avr-protos.h: Convert to
+ ISO C90 function declarations and definitions.
+ * config/sh/sh.c, config/sh/sh-protos.h: Likewise.
+
+2003-10-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (*-*-freebsd*): Use tm_defines instead of tiny
+ config files which do the same thing.
+ * config/freebsd3.h, config/freebsd4.h, config/freebsd5.h,
+ config/freebsd6.h: Remove now unnecessary files.
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * c-common.c (c_common_truthvalue_conversion): Warn if the
+ address of a non-weak function is used as a truth value.
+
+2003-10-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (WORD_REG_USED): Use SP_REG instead of
+ a literal.
+ * config/h8300/h8300.h (REGNO_OK_FOR_BASE_P): Use MAC_REG
+ instead of a literal.
+
+2003-10-12 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/extend.texi (Function Attributes): Mention the exceptional
+ path for noreturn-marked functions.
+
+2003-10-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_decide_inlining): Fix uninitialized variable
+ warning.
+
+2003-10-12 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/i386.c (x86_this_parameter): Fix typo.
+
+203-10-11 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (web.o): New.
+ * web.c: New file.
+ * rtl.h (web_main): Declare.
+ * timervar.def (TV_WEB): New.
+ * toplev.c (dump_file_index, dump_file_info): Add DFI_web.
+ (rest_of_hanle_web): New.
+ (flag_web): New static variable.
+ (lang_independent_options): Add "web".
+ (rest_of_compilation): Call rest_of_handle_web.
+ * invoke.texi (-fweb): Document.
+ * common.opt (fweb): New.
+ * flags.h (flag_web): New.
+ * opts.c (decode_options): Set flag_web at -O3.
+
+ * passes.texi (web construction): Document.
+ * invoke.texi (-O3): Document that -fweb is enabled.
+
+ * regrename.c (regrename_optimize): Deal better with situation when
+ replacement failed.
+
+ * sched-ebb.c: Include params.h and profile.h
+ (schedule_ebbs): Use tracer parameters to discover superblocks
+ * Makefile.in (sched-ebb.o): Add dependencies.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_mathfn_p): New function to determine whether
+ a built-in mathematical function is sign preserving, f(-x) == -f(x).
+ Add support for BUILT_IN_ASIN, BUILT_IN_ASINF and BUILT_IN_ASINL.
+ (tree_swap_operands_p): Change API to take an additional argument
+ indicating that the swapped operands evaluate in reverse order.
+ Canonicalize VAR_DECLs and PARM_DECLs last if we can, i.e. neither
+ operand side-effects or we don't care about flag_evaluation_order.
+ (reorder_operands_p): New function to check whether its safe to
+ evaluate the given operands in reverse order.
+ (negate_expr_p): We can always negate integer constants unless
+ we honor -ftrapv and the signed type would overflow. Only allow
+ -(A-B) into B-A if reorder_operands_p says that its OK. Allow
+ negation of COMPLEX_CST if both real and imaginary parts can be
+ negated. Allow negation through floating point extensions and
+ sign-preserving built-in functions.
+ (negate_expr): Move the code to negate integers from "fold" to
+ here. Always negate integer constants unless we honor -ftrapv
+ and the signed type would overflow. Always negate real constants
+ unless we honor -ftrapping-math. Only convert -(A-B) into B-A
+ if allowed by reorder_operands_p. Add support for COMPLEX_CST.
+ Optimize negation through floating point extensions and
+ sign-preserving built-in functions (as defined by negate_mathfn_p).
+ (fold): Adjust calls to tree_swap_operands_p.
+ (fold <NEGATE_EXPR>): Move the remaining negation optimizations
+ to negate_expr_p/negate_expr.
+ (fold <MINUS_EXPR>): Use reorder_operands_p to check whether we're
+ allowed to convert (-A) - B into (-B) - A.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_strcmp): Defend against the possibility
+ that gen_cmpstrsi may fail: Stabilize the argument list against
+ re-evaluation and expand the library call directly using this saved
+ argument list if a cmpstrsi sequence can't be generated.
+ (expand_builtin_strncmp): Likewise.
+
+ * config/i386/i386.md (cmpstrsi, movstrsi): Disable with -Os.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12260
+ * simplify-rtx.c (simplify_unary_operation): Simplify all unary
+ operations through CONST nodes. Optimize (neg (plus X C)) as
+ (minus -C X) for constant values C.
+ (simplify_binary_operation): Optimize (minus (neg X) C) as
+ (minus -C X) for constant values C.
+ (simplify_plus_minus): Avoid creating (neg (const (plus X C)),
+ instead create (minus -C X).
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr <PLUS_EXPR>): Let expand_operands call
+ safe_from_p for us, once it chooses an evaluation order.
+ (expand_expr <MULT_EXPR>): Likewise.
+ (expand_expr <MIN_EXPR> <MAX_EXPR>): Likewise. If expand_operands
+ places the second operand in "target", swap the operands.
+ (do_store_flag): Let expand_operands call safe_from_p for us.
+
+2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12544
+ * function.c (put_var_into_stack): Don't generate ADDRESSOFs
+ for DECL_NONLOCAL decls.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c: Follow spelling conventions.
+ * final.c: Likewise.
+ * optabs.c: Likewise.
+ * sched-deps.c: Likewise.
+ * sdbout.c: Likewise.
+
+Sat Oct 11 12:24:23 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (notice_global_symbol): Fix handling of variables; avoid
+ re-computing of variable.
+
+2003-10-11 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_return_in_memory): Rename from
+ return_in_memory, make static, change signature to match target hook.
+ (alpha_setup_incoming_varargs): Make static, change signature to
+ match target hook, add code for vms and unicos.
+ (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN,
+ TARGET_PROMOTE_PROTOTYPES, TARGET_STRUCT_VALUE_RTX,
+ TARGET_RETURN_IN_MEMORY, TARGET_SETUP_INCOMING_VARARGS,
+ TARGET_STRICT_ARGUMENT_NAMING,
+ TARGET_PRETEND_OUTGOING_VARARGS_NAMED): New.
+ * config/alpha/alpha-protos.h: Update.
+ * config/alpha/alpha.h (PROMOTE_FUNCTION_ARGS,
+ PROMOTE_FUNCTION_RETURN, RETURN_IN_MEMORY,
+ SETUP_INCOMING_VARARGS): Remove.
+ * config/alpha/unicosmk.h (SETUP_INCOMING_VARARGS): Remove.
+ * config/alpha/vms.h (SETUP_INCOMING_VARARGS): Remove.
+
+2003-10-11 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/arm.c (arm_regno_class): Handle IWMMXT_GR_REGS.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/lb1sf68.asm: Follow spelling conventions.
+ * config/m68k/m68k.c: Likewise.
+ * config/m68k/m68k.h: Likewise.
+ * config/m68k/m68k.md: Likewise.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_memcpy): Optimize case when the two
+ pointer arguments are the equal, non-volatile and side-effect free.
+ (expand_builtin_mempcpy): Likewise.
+ (expand_builtin_memmove): Likewise.
+ (expand_builtin_strcpy): Likewise.
+ (expand_builtin_memcmp): Likewise.
+ (expand_builtin_strcmp): Likewise.
+ (expand_builtin_strncmp): Likewise.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (apply_distributive_law): Enable "distributive" floating
+ point optimizations with -funsafe-math-optimizations.
+
+2003-10-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * genmodes.c (emit_mode_mask) Change MASK to MODE_MASK.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/m68k-protos.h: Remove the prototype for
+ finalize_pic.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/m68k.c: Fix comment typos.
+
+2003-10-11 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k-protos.h (use_return_insn): Change return type from
+ int to bool.
+ * config/m68k/m68k.c (struct m68k_frame): Add funcdef_no member.
+ (current_frame): New global var.
+ (m68k_compute_frame_layout): Cache computations in current_frame.
+ (m68k_initial_elimination_offset): Use values from current_frame
+ instead of recomputing them.
+ (use_return_insn): Likewise.
+ (m68k_output_function_prologue): Likewise.
+ (m68k_output_function_epilogue): Likewise.
+ * config/m68k/m68k.h (TARGET_CPU_CPP_PREDEFINES): Fold __PIC__ handling
+ inside the block for __pic__.
+
+2003-10-11 Peter Barada <peter@baradas.org>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_frame): Move before protos referencing it.
+ (m68k_save_reg): Add boolean parameter `interrupt_handler'.
+ (m68k_interrupt_function_p): New function.
+ (m68k_handle_fndecl_attribute): Ditto.
+ (m68k_compute_frame_layout): Ditto.
+ (m68k_attribute_table): Define back-end specific attributes.
+ (m68k_output_function_epilogue): Emit RTE instruction for interrupt
+ functions.
+
+2003-10-11 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/t-uclinux: New target Makefile fragment.
+ * config/m68k/uclinux.h: New target macro file.
+ * config.gcc (m68k-*-uclinux): New target definition.
+
+2003-10-10 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (builtin_mathfn_code): Generalize to check whether
+ the call is to any built-in function by comparing the call's
+ argument list against the builtin decl's function type.
+
+2003-10-10 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (constant_pool_entries_regcost): New global variable to
+ hold the register cost component of constant_pool_entries_cost.
+ (fold_rtx): Calculate constant_pool_entries_regcost at the same
+ time as constant_pool_entries_cost.
+ (cse_insn): Set both src_folded_cost and src_folded_regcost from
+ constant_pool_entries_cost and constant_pool_entries_regcost.
+ (cse_main): Initialize constant_pool_entries_regcost to zero.
+
+ * optabs.c (expand_unop): Attach a REG_EQUAL note describing
+ the semantics of the sequence of bit operations used to negate
+ a floating-point value.
+ (expand_abs_nojump): Likewise attach a REG_EQUAL note describing
+ the semantics of the bit operations used to abs a floating point
+ value.
+
+2003-10-11 Bernardo Innocenti <bernie@develer.com>
+ Paul Dale <pauli@snapgear.com>
+
+ * config/m68k/lb1sf68.asm: Add __PIC__ and __ID_SHARED_LIBRARY__
+ support.
+ * config/m68k/m68k-none.h (ASM_SPEC): Pass --pcrel to assembler on
+ -fpic, -fPIC, -msep-data and -mid-shared-library.
+ * config/m68k/m68k.c (m68k_library_id_string): New global variable.
+ (override_options): Add -msep-data and -mshared-library-id support.
+ (m68k_output_function_prologue): Generate code to load A5 for
+ TARGET_ID_SHARED_LIBRARY and TARGET_SEP_DATA.
+ (m68k_output_mi_thunk): Emit indirect jump on TARGET_ID_SHARED_LIBRARY.
+ (m68k_output_pic_call): New function.
+ * gcc/config/m68k/m68k.h (TARGET_SEP_DATA): New target flag.
+ (TARGET_ID_SHARED_LIBRARY): Ditto.
+ (TARGET_SWITCHES): Add switches for -mid-shared-library and -msep-data.
+ * gcc/config/m68k/m68k.md (call): Call m68k_output_pic_call().
+ (call_value): Likewise.
+
+2003-10-10 Zack Weinberg <zack@codesourcery.com>
+
+ * gengenrtl.c (find_formats, genheader): Make i an unsigned
+ int, remove cast of NUM_RTX_CODE.
+ * machmode.h: Make the HAVE_MACHINE_MODES #ifdef encompass the
+ entire file. Remove the #ifs on GET_MODE_MASK etc and
+ GET_MODE_WIDER_MODE etc.
+
+2003-10-10 Eric Christopher <echristo@redhat.com>
+
+ * lcm.c (optimize_mode_switching): Change NORMAL_MODE
+ to MODE_ENTRY and MODE_EXIT. Add MODE_AFTER for insns
+ that set mode.
+ * config/sh/sh.h (MODE_ENTRY): New macro.
+ (MODE_EXIT): Ditto.
+ (MODE_AFTER): Ditto.
+ * config/sh/sh.md: Change for MODE_AFTER. Add
+ fp_set attribute.
+ * doc/tm.texi: Document MODE_AFTER, MODE_ENTRY, and MODE_EXIT.
+
+2003-10-10 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c, mode-classes.def: New files.
+ * machmode.def: Rewritten to genmodes.c interface.
+ * Makefile.in (extra_modes_file): New substitution variable.
+ (MACHMODE_H): No longer includes machmode.def or
+ @extra_modes_file@; instead, mode-classes.def and insn-modes.h.
+ (BUILD_RTL): Add $(BUILD_PREFIX)insn-modes.o.
+ (OBJS-common): Add insn-modes.o.
+ (STAGESTUFF): Add insn-modes.c, insn-modes.h, s-modes, and
+ genmodes$(build_exeext).
+ (insn-modes.o, insn-modes.c, insn-modes.h, s-modes, genmodes.o,
+ genmodes$(build_exeext), $(BUILD_PREFIX_1)insn-modes.o): New targets.
+ (s-genrtl): Don't depend on $(RTL_BASE_H).
+ (gengenrtl.o): Don't depend on coretypes.h, $(GTM_H), real.h,
+ or $(RTL_BASE_H); just rtl.def.
+ * gengenrtl.c: Don't include coretypes.h, tm.h, rtl.h, or
+ real.h. Give fake definition of CONST_DOUBLE_FORMAT and
+ substitute definition of NUM_RTX_CODE. Add casts to avoid
+ warnings.
+ * machmode.h: Include insn-modes.h, not machmode.def. Include
+ mode-classes.def to define enum mode_class. Tweak definitions
+ of GET_MODE_CLASS, GET_MODE_SIZE, GET_MODE_BITSIZE, GET_MODE_MASK,
+ GET_MODE_INNER, GET_MODE_WIDER_MODE, GET_CLASS_NARROWEST_MODE.
+ (inner_mode_array): Renamed mode_inner.
+ (mode_base_align): New.
+ * rtl.c (mode_name, mode_class, mode_bitsize, mode_size,
+ mode_unit_size, mode_wider_mode, mode_mask_array,
+ inner_mode_array, class_narrowest_mode): Delete definitions.
+ * stor-layout.c (get_mode_alignment): Use mode_base_align.
+ * real.h: Use MIN_MODE_FLOAT and MAX_MODE_FLOAT, not QFmode
+ and TFmode, in real_format_for_mode and REAL_MODE_FORMAT.
+
+ * config/ip2k/ip2k.h, config/iq2000/iq2000.h:
+ No need to define BITS_PER_UNIT.
+
+2003-10-10 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/ia64/ia64.c (ia64_vms_init_libfuncs): New function.
+ (ia64_output_function_prologue): Only write .prologue if --with-gnu-as.
+ (ia64_initialize_trampoline): If not using GAS, declare trampoline
+ as global.
+ * config/ia64/ia64.h (ASM_APP_ON, ASM_APP_OFF): Add vers for not GAS.
+ (ASM_OUTPUT_DEBUG_LABEL): Likewise.
+
+ * stor-layout.c (compute_record_mode): Don't force BLKmode if
+ field is zero-length BLKmode.
+ * expr.c (expand_expr, case COMPONENT_REF): Handle case of BLKmode
+ zero-size references.
+
+ * combine.c (distribute_links): Properly test for REG being set.
+
+ * config/alpha/alpha.c (alpha_expand_block_mode): Don't use
+ gen_lowpart and company except for REG.
+
+2003-10-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa64-hpux.h (LINK_SPEC): Use `-z' option with HP ld.
+
+2003-10-10 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (mips*-*-netbsd*): Remove content-free line.
+
+2003-10-10 Herman A.J. ten Brugge <hermantenbrugge@home.nl>
+
+ * gcov-io.h: Check BITS_PER_UNIT when defining gcov_unsigned_t,
+ gcov_position_t and gcov_type.
+
+2003-10-09 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * configure.in (HAVE_AS_TLS): Add sh-*-* and sh[34]*-*-* cases.
+ * configure: Regenerate.
+
+2003-10-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (define_asm_attributes): Specify
+ the length of an asm insn more precisely.
+
+2003-10-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris6.h (SUBTARGET_CPP_SPEC): Define.
+
+2003-10-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_dbx_register_number): Change first
+ FP register number to 48 and MAC16 accumulator to 0x210.
+
+2003-10-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove redundant thread_file setting clauses for
+ various *-*-linux* targets.
+
+2003-10-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (define_asm_attributes): New.
+
+2003-10-09 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.c (prepare_float_lib_cmp): Always attach a REG_EQUAL note
+ to the comparison, as emit_libcall_block calls copy_rtx on equiv.
+
+2003-10-09 Dorit Naishlos <dorit@il.ibm.com>
+
+ * haifa-sched.c (ok_for_early_schedule): New function.
+ (early_queue_to_ready): New function.
+ (schedule_block): Allow early removal of insns from Q.
+ (schedule_insn): Update INSN_TICK in case of premature
+ issue.
+ * common.opt (sched_stalled_insns): New flag.
+ (sched_stalled_insns_dep): New flag.
+ * flags.h: Same above flags.
+ * opts.c: Same as above.
+ * toplev.c: Same as above.
+ * target.h (targetm.sched.is_costly_dependence): New
+ hook.
+ * target-def.h: Same as above.
+ * config/rs6000/rs6000.h: (rs6000_sched_costly_dep):
+ Support new flag -msched-costly-dep.
+ (DEFAULT_SCHED_COSTLY_DEP): Define.
+ * config/rs6000/rs6000.c:
+ (rs6000_is_costly_dependence): New function.
+ (is_load_insn, is_store_insn): New functions.
+ (is_load_insn1, is_store_insn1, is_mem_ref): New
+ functions.
+ * doc/invoke.texi (-fsched-stalled-insns-dep)
+ (-fsched-stalled-insns, -msched-costly-dep): Document
+ options.
+ * doc/tm.texi (is_costly_dependence): Define new
+ scheduler target hook.
+
+2003-10-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/6392
+ * c-common.c (c_build_qualified_type): Look through arrays first.
+ (c_apply_type_quals_to_decl): Look through arrays.
+
+ * c-common.c (c_apply_type_quals_to_decl): Unset TREE_READONLY for
+ types with constructors.
+
+ * coverage.c (build_ctr_info_value): Use build_decl to make a
+ VAR_DECL.
+ (create_coverage): Likewise.
+
+ * stmt.c (resolve_asm_operand_names): Call check_unique_operand_names
+ here.
+ (expand_asm_operands): Not here.
+ (parse_input_constraint): No longer static.
+ * tree.h: Declare it.
+
+2003-10-08 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/t-linux (SHLIB_LINK): Override to use a linker script
+ libgcc_s.so.
+ (SHLIB_INSTALL): Likewise.
+
+2003-10-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Remove reference to removed 'pthreads' thread
+ option.
+
+2003-10-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md ("abssi2_isel"): Add early clobber to
+ operand 2.
+
+2003-10-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Don't accept --enable-threads=pthreads. Clean
+ up related case statements.
+ * configure.in: Don't accept --enable-threads=pthreads,
+ decosf1, mach, or os2 (none of which work anyway). Alphabetize
+ supported thread files in case clause.
+ * configure: Regenerate.
+
+2003-10-08 Geoffrey Keating <geoffk@apple.com>
+
+ * function.c (pad_to_arg_alignment): Move 'boundary_in_bytes'
+ definition to above SPARC_STACK_BOUNDARY_HACK.
+
+2003-10-08 Jason Merrill <jason@redhat.com>
+
+ * c-pretty-print.c (pp_c_postfix_expression)
+ <COMPOUND_LITERAL_EXPR>: Fix thinko.
+
+2003-10-08 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * mklibgcc.in: Don't hide undefined or typeless symbols.
+
+2003-10-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12142
+ * cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
+ uses of the register in the SET_SRC. Remove unnecessary argument.
+ * pa.c (legitimize_pic_address): Before reload, use a scratch register
+ for the intermediate result in loading the address of a SYMBOL_REF.
+ Set the MEM_NOTRAP_P flag for the MEM. Add a REG_EQUAL to the insn
+ which loads the SYMBOL_REF address.
+
+2003-10-08 Timo Kokkonen <tjko@iki.fi>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR bootstrap/12490
+ * scan-decls.c (MAX_EXTERN_C_BRACES): New preprocessor constant
+ to define the size of the extern_C_braces array. Set it to 200.
+ (scan_decls): Abort when extern_C_braces_length is out-of-bounds.
+
+2003-10-08 Carlo Wood <carlo@alinoe.com>
+
+ * Makefile.in (gengtype-lex.c): flex 2.5.4[a] doesn't understand
+ a space after the -o option. flex 2.5.31 understands both, with
+ and without the space. Removed that space.
+
+2003-10-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_frame_info): Add cprestore_size field.
+ (compute_frame_size): Initialize it. Remove the .cprestore slot
+ from args_size.
+ (mips_output_function_prologue): Simplify accordingly.
+ (mips_debugger_offset): Change the mips16 frame pointer offset from
+ current_function_outgoing_args to cfun->machine->frame.args_size.
+ (mips_initial_elimination_offset): Likewise.
+ (mips_expand_prologue): Likewise.
+ (mips_expand_epilogue): Likewise.
+
+2003-10-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (EXTRA_CONSTRAINT): Add 'W' constraint.
+ (EXTRA_MEMORY_CONSTRAINT): Define.
+ (CAN_ELIMINATE): Remove lwu workaround.
+ * config/mips/mips.md (*zero_extendsidi2_mem): Enable for mips16 too.
+ Use a 'W' constraint for the source operand.
+
+2003-10-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genopinit.c (main): Output code to declare undefined
+ variables.
+
+2003-10-07 Kelley Cook <kcook@gcc.gnu.org>
+
+ * gengtype-lex.l: Remove -Wtraditional cruft.
+ * Makefile.in (gengtype-lex.c): Likewise.
+
+2003-10-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (fix_irreducible_loops): Initialize e correctly.
+
+2003-10-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/12519
+ * c-semantics.c (genrtl_cleanup_stmt): Ignore the CLEANUP_DECL if
+ it isn't a decl.
+
+2003-10-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.c (cpp_options): Only pass -fworking-directory for -g* if
+ not overridden.
+ Fixes PR bootstrap/12173.
+
+2003-10-07 Zack Weinberg <zack@codesourcery.com>
+
+ * errors.c: Don't include coretypes.h or tm.h.
+ (trim_filename): Use IS_DIR_SEPARATOR.
+ * Makefile.in: Update dependencies of errors.o and
+ $(BUILD_PREFIX_1)errors.o.
+
+2003-10-07 Geoffrey Keating <geoffk@apple.com>
+
+ * function.c (pad_to_arg_alignment): Take STACK_POINTER_OFFSET into
+ account when aligning arguments.
+ * calls.c (STACK_POINTER_OFFSET): Move default from here ...
+ * defaults.h (STACK_POINTER_OFFSET): ... to here.
+ * config/sparc/sparc.h (STACK_BOUNDARY): Add comment about how
+ it's wrong when TARGET_ARCH64 && TARGET_STACK_BIAS.
+ (SPARC_STACK_BOUNDARY_HACK): Define.
+ * config/rs6000/rs6000.c (function_arg): On non-SVR4 systems,
+ arrange for vector parameters to varargs functions to be passed
+ in both memory and GPRs when appropriate.
+ (rs6000_va_arg): Vector arguments passed in memory are 16-byte
+ aligned.
+
+ * hooks.c (hook_bool_tree_true): New.
+ (hook_rtx_tree_int_null): New.
+ (hook_rtx_rtx_null): Use NULL, not 0.
+ * hooks.h: Add 'extern' to everything.
+ (hook_bool_tree_true): New.
+ (hook_rtx_tree_int_null): New.
+ * targhooks.c (hook_bool_CUMULATIVE_ARGS_true): New.
+ * targhooks.h (hook_bool_CUMULATIVE_ARGS_true): New.
+ * config/rs6000/rs6000-protos.h (setup_incoming_varargs): Remove
+ prototype.
+ * config/rs6000/rs6000.c (rs6000_return_in_memory): New.
+ (setup_incoming_varargs): Prototype.
+ (TARGET_PROMOTE_FUNCTION_ARGS): Define.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Define.
+ (TARGET_STRUCT_VALUE_RTX): Define.
+ (TARGET_RETURN_IN_MEMORY): Define.
+ (TARGET_SETUP_INCOMING_VARARGS): Define.
+ (TARGET_STRICT_ARGUMENT_NAMING): Define.
+ (TARGET_PRETEND_OUTGOING_VARARGS_NAMED): Define.
+ (init_cumulative_args): Use rs6000_return_in_memory.
+ (setup_incoming_varargs): Make 'static'.
+ * config/rs6000/rs6000.h (PROMOTE_FUNCTION_ARGS): Delete.
+ (PROMOTE_FUNCTION_RETURN): Delete.
+ (STRUCT_VALUE): Delete.
+ (RETURN_IN_MEMORY): Delete.
+ (SETUP_INCOMING_VARARGS): Delete.
+
+2003-10-07 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/invoke.texi (Warning Options): Simplify and clarify the
+ descriptions of -Wnonnull and -Winit-self.
+
+2003-10-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * optabs.c (init_intraclass_conv_libfuncs): Fix order of array
+ indicees for floating-point conversersion libcalls.
+
+2003-10-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Add more comments separating large conceptually
+ separate sections.
+
+ * configure.in: Clean up thread file logic.
+ * configure: Regenerate.
+
+2003-10-07 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (READONLY_DATA_SECTION_ASM_OP): Define.
+ (switch_to_section): Handle in_readonly_data.
+ * config/i386/winnt.c (i386_pe_asm_named_section): Handle
+ readonly data.
+
+2003-10-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (cmpsi2_addneg): New ARM pattern. Add peephole2 to generate
+ it.
+ (cbranchne_decr1): New Thumb pattern.
+ * arm.c (arm_addimm_operand): New insn predicate.
+ * arm-protos.h: Add a prototype for it.
+ * arm.h (PREDICATE_CODES): Add it.
+
+2003-10-07 Dorit Naishlos <dorit@il.ibm.com>
+
+ * sched-int.h (sched_info): New field
+ sched_max_insns_priority.
+ * sched-rgn.c (init_ready_list): Add invocations to
+ targetm.sched.adjust_priority.
+ (sched_max_insns_priority): Init new field.
+ * sched-ebb.c (sched_max_insns_priority): Init new field.
+ * haifa-sched.c (set_priorities): Set
+ sched_info->sched_max_insns_priority.
+ * config/rs6000/rs6000.h:
+ (rs6000_sched_restricted_insns_priority_str): Support new
+ flag -mprioritize-restricted-insns.
+ (DEFAULT_RESTRICTED_INSNS_PRIORITY): Define.
+ * config/rs6000/rs6000.c (is_dispatch_slot_restricted): New
+ function.
+ (rs6000_adjust_priority): Change priority of restricted
+ insns, using above new function and new flag.
+ * doc/invoke.texi (-mprioritize-restricted-insns): Document
+ new option.
+
+2003-10-07 Zack Weinberg <zack@codesourcery.com>
+
+ * expr.c (cmpstr_optab, cmpmem_optab): New.
+ * genopinit.c: Initialize them.
+ * optabs.h: Declare them.
+ * optabs.c (init_optabs): Clear them.
+ (prepare_cmp_insn): Use cmpstr_optab and cmpmem_optab to find
+ block memory compare insns, not conditional chains. Restructure
+ the fallback generation of a call to memcmp/bcmp for better
+ readability.
+
+2003-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (MIPS_MAX_FIRST_STACK_STEP): New macro.
+ (mips_save_restore_fn): New typedef.
+ (mips_add_large_offset_to_sp, mips_emit_frame_related_store): Remove.
+ (mips_set_frame_expr, mips_frame_set): Move above prologue code.
+ (save_restore_insns): Remove, replacing with...
+ (mips_save_restore_reg, mips_for_each_saved_reg): ...these new fns.
+ (mips_save_reg, mips_restore_reg): New function.
+ (mips_expand_prologue, mips_expand_epilogue): Rework.
+ * config/mips/mips.h (MIPS_TEMP1_REGNUM, MIPS_TEMP2_REGNUM): Remove.
+ (MIPS_PROLOGUE_TEMP_REGNUM, MIPS_EPILOGUE_TEMP_REGNUM): New macros.
+ (MIPS_PROLOGUE_TEMP, MIPS_EPILOGUE_TEMP): New macros.
+
+2003-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_prologue): Remove unused
+ traversal of function arguments.
+
+2003-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Remove documentation of -mentry.
+ * config/mips/mips.c (mips_entry_string, mips_entry): Remove.
+ (override_options, mips_save_reg_p): Remove handling.
+ (compute_frame_size, mips_output_function_prologue): Likewise.
+ (mips_expand_prologue, mips_expand_epilogue): Likewise.
+ * config/mips/mips.h (mips_entry_string): Remove declaration.
+ (TARGET_OPTIONS): Remove -mentry.
+ * config/mips/mips16.S: Remove mention of -mentry.
+
+2003-10-06 Zack Weinberg <zack@codesourcery.com>
+
+ * libfuncs.h (LTI_extendsfdf2, LTI_extendsfxf2, LTI_extendsftf2)
+ (LTI_extenddfxf2, LTI_extenddftf2, LTI_truncdfsf2, LTI_truncxfsf2)
+ (LTI_trunctfsf2, LTI_truncxfdf2, LTI_trunctfdf2, LTI_floatsisf)
+ (LTI_floatdisf, LTI_floattisf, LTI_floatsidf, LTI_floatdidf)
+ (LTI_floattidf, LTI_floatsixf, LTI_floatdixf, LTI_floattixf)
+ (LTI_floatsitf, LTI_floatditf, LTI_floattitf, LTI_fixsfsi, LTI_fixsfdi)
+ (LTI_fixsfti, LTI_fixdfsi, LTI_fixdfdi, LTI_fixdfti, LTI_fixxfsi)
+ (LTI_fixxfdi, LTI_fixxfti, LTI_fixtfsi, LTI_fixtfdi, LTI_fixtfti)
+ (LTI_fixunssfsi, LTI_fixunssfdi, LTI_fixunssfti, LTI_fixunsdfsi)
+ (LTI_fixunsdfdi, LTI_fixunsdfti, LTI_fixunsxfsi, LTI_fixunsxfdi)
+ (LTI_fixunsxfti, LTI_fixunstfsi, LTI_fixunstfdi, LTI_fixunstfti)
+ (extendsfdf2_libfunc, extendsfxf2_libfunc, extendsftf2_libfunc)
+ (extenddfxf2_libfunc, extenddftf2_libfunc, truncdfsf2_libfunc)
+ (truncxfsf2_libfunc, trunctfsf2_libfunc, truncxfdf2_libfunc)
+ (trunctfdf2_libfunc, floatsisf_libfunc, floatdisf_libfunc)
+ (floattisf_libfunc, floatsidf_libfunc, floatdidf_libfunc)
+ (floattidf_libfunc, floatsixf_libfunc, floatdixf_libfunc)
+ (floattixf_libfunc, floatsitf_libfunc, floatditf_libfunc)
+ (floattitf_libfunc, fixsfsi_libfunc, fixsfdi_libfunc, fixsfti_libfunc)
+ (fixdfsi_libfunc, fixdfdi_libfunc, fixdfti_libfunc, fixxfsi_libfunc)
+ (fixxfdi_libfunc, fixxfti_libfunc, fixtfsi_libfunc, fixtfdi_libfunc)
+ (fixtfti_libfunc, fixunssfsi_libfunc, fixunssfdi_libfunc)
+ (fixunssfti_libfunc, fixunsdfsi_libfunc, fixunsdfdi_libfunc)
+ (fixunsdfti_libfunc, fixunsxfsi_libfunc, fixunsxfdi_libfunc)
+ (fixunsxfti_libfunc, fixunstfsi_libfunc, fixunstfdi_libfunc)
+ (fixunstfti_libfunc): Delete.
+ * optabs.h (struct optab_handlers): Break out of struct optab.
+ (struct convert_optab, convert_optab, enum convert_optab_index,
+ convert_optab_table, sext_optab, zext_optab, trunc_optab,
+ sfix_optab, ufix_optab, sfixtrunc_optab, ufixtrunc_optab,
+ sfloat_optab, ufloat_optab): New.
+ (set_conv_libfunc): Prototype.
+ (GEN_FCN): Use C90 indirect call syntax, remove unnecessary cast.
+ (trunc_optab): Renamed btrunc_optab.
+ * builtins.c (expand_builtin_mathfn): Update to match.
+ * optabs.c (extendtab, fixtab, fixtrunctab, floattab): Delete.
+ (convert_optab_table, new_convert_optab, init_convert_optab)
+ (init_interclass_conv_libfuncs, init_intraclass_conv_libfuncs)
+ (set_conv_libfunc): New.
+ (can_extend_p, gen_extend_insn, can_fix_p, can_float_p)
+ (expand_float, expand_fix): Use new conversion optabs,
+ not old insn code tables or long chains of ifs.
+ (init_optabs): No need to clear old insn code tables.
+ Initialize the new optabs, not the old libfunc array entries.
+ Don't handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
+ * genopinit.c: Initialize conversion optabs, not the
+ former insn code tables. Remove unnecessary casts.
+ Handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
+ * expr.c (convert_move): Remove redundant check that
+ to_real==from_real. Use the conversion optabs instead
+ of long chains of tests of modes. Move partial-integer-mode
+ interconversion above all integer conversion. Do not recurse
+ on a value forced into a register in the original mode.
+
+ * config/gofast.h, config/frv/frv.c, config/ia64/ia64.c
+ * config/mips/mips.c, config/pa/pa.c, config/rs6000/rs6000.c
+ * config/sparc/sparc.c: Use set_conv_libfunc to adjust entries
+ in new conversion optabs; do not reference the old libfunc
+ array entries. No need to include libfuncs.h.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (ix86_expand_setcc): Annotate the floating
+ point comparison sequence with a REG_EQUAL note that describes
+ the comparison's semantics.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr <COND_EXPR>): Handle the void type semantics
+ of COND_EXPR when expanding the "A op 0 ? FOO : A" optimizations.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * optabs.c (prepare_float_lib_cmp): Avoid searching for REG_RETVAL
+ instruction by using LCT_CONST and then calling emit_libcall_block
+ ourselves.
+
+2003-10-06 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR optimization/11974
+ * optabs.c (expand_unop): Promote libcall outmode according to
+ hard_libcall_value.
+
+2003-10-06 Zack Weinberg <zack@codesourcery.com>
+
+ * real.h (REAL_MODE_FORMAT): New macro.
+ * c-cppbuiltin.c, optabs.c, real.c, config/alpha/alpha.c
+ * config/c4x/c4x.c, config/i370/i370.c, config/i386/freebsd.h
+ * config/i386/i386.c, config/i960/i960.c, config/ia64/ia64.c
+ * config/m68k/m68k.c, config/mips/mips.c, config/rs6000/rs6000.c
+ * config/vax/vax.c: Use REAL_MODE_FORMAT instead of referring
+ directly to real_format_for_mode array, wherever possible.
+
+2003-10-06 Devang Patel <dpatel@apple.com>
+
+ * dwarf2out.c (is_main_source): Remove variable.
+ (dwarf2out_start_source_file): Do not check is_main_source.
+ Do not reset is_main_source.
+ (dwarf2out_init): Do not initialize is_main_source.
+
+2003-10-06 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (stdio_va_list): Removed _ap fix.
+ (irix_stdio_va_list): Don't require leading printf, IRIX 6.5.21
+ introduced some multi-line prototypes.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PREDICATE_CODES): Add stack_operand.
+ * config/mips/mips.c (stack_operand): New predicate.
+ * config/mips/mips.md: Use it for the destination of mips16 insns
+ that store $31.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (*lowsi): Renamed from lowsi.
+ (*lowdi): Likewise lowdi.
+ (*lowsi_mips16, *lowdi_mips16): New patterns.
+ * config/mips/mips.c (mips_const_insns, mips_output_move): Remove
+ mips16 CONSTANT_RELOC handling.
+ (mips_delegitimize_address): Adjust for new sdata representation.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_arg_info): If MUST_PASS_IN_STACK,
+ skip any remaining register arguments.
+
+2003-10-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads_subreg_address): Use correct offset for
+ paradoxical MEM subregs on big-endian targets.
+
+2003-10-06 Andrew Haley <aph@redhat.com>
+
+ * tree.c (get_callee_fndecl): Call
+ lang_hooks.lang_get_callee_fndecl.
+ * langhooks-def.h (LANG_HOOKS_GET_CALLEE_FNDECL): New.
+ (lhd_get_callee_fndecl): New.
+
+2003-10-06 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_non_lazy_ptr_name): Fix off by one
+ error in calculating the length of the string.
+ (machopic_stub_name): Likewise.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.c (prepare_float_lib_cmp): Attach a REG_EQUAL note
+ describing the return value of the comparison libcall to the
+ REG_RETVAL instruction of the emitted sequence.
+
+2003-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12215
+ * cse.c (cse_set_around_loop): Emit the move at the beginning
+ of the next basic block for trapping sets.
+
+2003-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11637
+ * combine.c (adjust_for_new_dest): New function to adjust the
+ notes and LOG_LINKS when the dest of an insn has changed.
+ (try_combine): Use it when deleting the first insn of a two-insn
+ parallel or splitting a two-load parallel.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_classify_constant): Only allow UNSPECs
+ if TARGET_EXPLICIT_RELOCS.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR bootstrap/12512
+ * Makefile.in (info): Use double-colon rules.
+ (dvi): Likewise.
+ (generated-manpages): Likewise.
+ * configure.in: Do not create lang.info, lang.dvi, or
+ lang.generated-manpages hooks.
+ * configure: Regenerated.
+ * objc/Make-lang.in (objc.info): Remove.
+ (objc.dvi): Remove.
+ (objc.generated-manpages): Remove.
+ * doc/sourcebuild.texi: Update description of info, dvi, and
+ generated-manpages hooks.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Merge mips16 lw/srl pattern with its splitter.
+
+2003-10-05 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_non_lazy_ptr_name): Fix off by one
+ errors in memcpy destinations.
+ (machopic_stub_name): Likewise.
+
+2003-10-05 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_non_lazy_ptr_name):
+ Change strcat to memcpy and add length together.
+ (machopic_stub_name): Likewise.
+
+2003-10-05 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Handle new
+ signal trampoline codes.
+
+2003-10-05 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (*divsf3): Move description of
+ SB-1 F2 erratum from here to...
+ (divsf3): Here. Disable if TARGET_FIX_SB1 is set and
+ flag_unsafe_math_optimizations is not.
+
+2003-10-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/linuxspe.h: Define TARGET_SPE_ABI, TARGET_SPE,
+ TARGET_E500, TARGET_ISEL, and TARGET_FPRS.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-pretty-print.c: Fix comment typos.
+ * c-pretty-print.h: Likewise.
+ * calls.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cppfiles.c: Likewise.
+ * final.c: Likewise.
+ * function.c: Likewise.
+ * gcov-io.h: Likewise.
+ * gcse.c: Likewise.
+ * genoutput.c: Likewise.
+ * loop.c: Likewise.
+ * postreload.c: Likewise.
+ * reg-stack.c: Likewise.
+ * regmove.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-rgn.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * tree-inline.c: Likewise.
+ * config/m68hc11/m68hc11.h: Likewise.
+ * config/mmix/mmix.c: Likewise.
+ * config/mn10300/mn10300.md: Likewise.
+ * config/sh/sh.h: Likewise.
+
+2003-10-05 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (remap_type): New.
+ (remap_decl): Use it. Remap DECL_SIZE*.
+ (copy_body_r): Use it.
+ (walk_tree): Walk TREE_TYPE too.
+ (copy_tree_r): Don't walk subtrees of types.
+ * tree.c (variably_modified_type_p): Restructure. Consider integer
+ types with non-const bounds variably modified.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Fix typos.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c: Follow spelling conventions.
+ * function.c: Likewise.
+ * config/c4x/c4x.h: Likewise.
+ * config/c4x/c4x.md: Likewise.
+ * config/frv/frv.md: Likewise.
+ * config/rs6000/aix.h: Likewise.
+ * config/rs6000/linux64.h: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-pretty-print.c: Fix comment formatting.
+ * cfglayout.c: Likewise.
+ * cfgloopanal.c: Likewise.
+ * cppcharset.c: Likewise.
+ * dbxout.c: Likewise.
+ * ggc-page.c: Likewise.
+ * ggc.h: Likewise.
+ * target.h: Likewise.
+
+2003-10-04 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * gengtype-lex.l: Recognize typedef of functions without PARAMS macro.
+
+2003-10-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/v850/v850-c.c, config/v850/v850-protos.h, config/v850/v850.c:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-10-04 Zack Weinberg <zack@codesourcery.com>
+
+ * libfuncs.h
+ (LTI_eqhf2, LTI_nehf2, LTI_gthf2, LTI_gehf2, LTI_lthf2)
+ (LTI_lehf2, LTI_unordhf2, LTI_eqsf2, LTI_nesf2, LTI_gtsf2)
+ (LTI_gesf2, LTI_ltsf2, LTI_lesf2, LTI_unordsf2, LTI_eqdf2)
+ (LTI_nedf2, LTI_gtdf2, LTI_gedf2, LTI_ltdf2, LTI_ledf2)
+ (LTI_unorddf2, LTI_eqxf2, LTI_nexf2, LTI_gtxf2, LTI_gexf2)
+ (LTI_ltxf2, LTI_lexf2, LTI_unordxf2, LTI_eqtf2, LTI_netf2)
+ (LTI_gttf2, LTI_getf2, LTI_lttf2, LTI_letf2, LTI_unordtf2)
+ (eqhf2_libfunc, nehf2_libfunc, gthf2_libfunc, gehf2_libfunc)
+ (lthf2_libfunc, lehf2_libfunc, unordhf2_libfunc, eqsf2_libfunc)
+ (nesf2_libfunc, gtsf2_libfunc, gesf2_libfunc, ltsf2_libfunc)
+ (lesf2_libfunc, unordsf2_libfunc eqdf2_libfunc, nedf2_libfunc)
+ (gtdf2_libfunc, gedf2_libfunc, ltdf2_libfunc, ledf2_libfunc)
+ (unorddf2_libfunc eqxf2_libfunc, nexf2_libfunc, gtxf2_libfunc)
+ (gexf2_libfunc, ltxf2_libfunc, lexf2_libfunc, unordxf2_libfunc
+ (eqtf2_libfunc, netf2_libfunc, gttf2_libfunc, getf2_libfunc)
+ (lttf2_libfunc, letf2_libfunc, unordtf2_libfunc):
+ Delete.
+ * optabs.h (OTI_eq, OTI_ne, OTI_gt, OTI_ge, OTI_lt, OTI_le)
+ (OTI_unord, eq_optab, ne_optab, gt_optab, ge_optab, lt_optab)
+ (le_optab, unord_optab): New.
+
+ * optabs.c (prepare_float_lib_cmp): Rewrite. Get the libfuncs
+ from the code_to_optab table, not a giant switch; use
+ swap_condition; do widening only if a comparison function that
+ we can call exists in a wider mode, not if a cmp_optab insn or
+ libfunc exists in a wider mode; call protect_from_queue
+ exactly once on each operand.
+ (init_optabs): Initialize the new optabs, not the deleted libfuncs.
+
+ * config/gofast.h, config/ia64/ia64.c, config/mips/mips.c
+ * config/pa/pa.c, config/rs6000/rs6000.c, config/sparc/sparc.c:
+ Set floating point comparison libfuncs using set_optab_libfunc
+ on the appropriate optab.
+
+ * config/ia64/ia64.c (ia64_hpux_init_libfuncs): Fix typo.
+ * config/rs6000/rs6000.c (rs6000_init_libfuncs): Correct ABI
+ selector conditionals.
+
+2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/t-m68hc11-gas (MULTILIB_MATCHES): m68hcs12 is
+ identical to m68hc12 as far as libraries are concerned.
+
+2003-10-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/12446
+ * c-typeck.c (convert_for_assignment): Issue an error for
+ array to pointer assignment after default conversion.
+ (digest_init): Likewise.
+
+2003-10-04 Fariborz Jahanian <fjahanian@apple.com>
+
+ * c-decl.c (duplicate_decls): retain DECL_COMMON of old declaration
+
+2003-10-03 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/extend.texi (Function Attributes): Fix title of GNU C
+ Preprocessor manual.
+ (C++ Extensions): Fix reference to "Predefined Macros" in the
+ GNU C Preprocessor manual.
+
+2003-10-04 Richard Earnshaw <reanrsha@arm.com>
+
+ * doc/extend.texi: Document how GCC estimates and relies on the size
+ of an asm.
+
+2003-10-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_pad_arg_upward): Pad floating-point
+ arguments downward for big-endian o64.
+
+2003-10-03 Robert Bowdidge <bowdidge@apple.com>
+
+ * ggc-page.c (ggc_pch_write_object): Replace fseek() with fwrite() in
+ PCH generation, avoiding too-frequent flushes when writing to NFS
+ file system.
+
+2003-10-03 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (lookup_category): Mark as 'inline'.
+
+2003-10-03 Alexander Malmberg <alexander@malmberg.org>
+ Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (add_method_to_hash_list, lookup_category):
+ New functions.
+ (lookup_method_in_hash_lists): New parameter indicating whether
+ we are messaging 'Class' or 'id'.
+ (check_duplicates): Likewise; do not assume all methods will
+ be either class or instance methods.
+ (generate_category, finish_class): Use lookup_category().
+ (add_method): Use add_method_to_hash_list(); insert instance
+ methods of root classes into the global class method hash table.
+ (add_category): Use lookup_category(); avoid constructing
+ duplicate categories.
+ (really_start_method): Add method to corresponding @interface,
+ if not already there (and if the @interface exists).
+ (finish_message_expr, finish_objc): Adjust calls to
+ check_duplicates().
+
+2003-10-03 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/9325, PR java/6391
+ * fold-const.c (fold_convert): For floating point to integer
+ conversions, return the maximum/minimum representable integer
+ value if the real constant overflows the destination type.
+ * tree.c (real_value_from_int_cst): Allow the type to be NULL,
+ meaning don't truncate the result to a floating point mode.
+ Simplify the logic by calling real_from_integer directly.
+ * simplify-rtx.c (simplify_unary_operation): Implement the
+ same semantics for folding floating point to integer conversions
+ in RTL.
+
+2003-10-03 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (mips_emit_prefetch): Restructure
+ to avoid use of arrays, handle indexed prefetch.
+ * config/mips/mips.h (ISA_HAS_FP4, ISA_HAS_PREFETCH): Update comments.
+ (ISA_HAS_PREFETCHX): New deffine.
+ * config/mips/mips.md ("type" attr): Add new "prefetchx" value,
+ update comments.
+ (prefetch_indexed_di, prefetch_indexed_si): New insns.
+
+2003-10-03 Jeff Sturm <jsturm@one-point.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12289
+ * calls.c (emit_call_1): Pretend to have popped the arguments
+ to noreturn and longjmp functions instead of ignoring them.
+ (expand_call): Don't adjust stack_pointer_dela while
+ inhibit_defer_pop is set.
+
+2003-10-03 Andreas Schwab <schwab@suse.de>
+
+ PR bootstrap/12276
+ * configure.in: Check for libunwind on the host only if building
+ a native compiler.
+ * configure: Regenerated.
+
+2003-10-03 Paolo Carlini <pcarlini@unitus.it>
+
+ * unwind-pe.h (read_encoded_value_with_base): Constify u and
+ its inizialization cast.
+
+2003-10-03 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12485
+ * config/mips/mips.c (mips_load_got): GOT accesses can't trap.
+
+2003-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR optimization/12180
+ * tree-inline.c (inline_forbidden_p_1): Do not permit inlining of
+ functions containing calls to __builtin_next_arg.
+
+2003-10-02 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (mips_emit_prefetch): Use operand 3
+ in instructions being output.
+ * config/mips/mips.md (prefetch_si_address): Change third
+ operand's constraint letter to 'I'.
+ (prefetch_di_address): Likewise.
+ (prefetch_si, prefetch_di): Set third operand to const0_rtx.
+
+2003-10-02 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h: Poison macros obsoleted by earlier patch.
+ * config/cris/cris.c: C90-ify a function definition.
+
+2003-10-02 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/12292
+ * combine.c (make_field_assignment): Check whether rtx's code
+ is CONST_INT before using INTVAL.
+
+2003-10-02 Josef Zlomek <zlomekj@suse.cz>
+
+ * cgraph.c (cgraph_node): Use INSERT instead of 1 in
+ htab_find_slot_with_hash.
+ (cgraph_node_for_identifier): Use NO_INSERT.
+ (cgraph_remove_node): Use NO_INSERT.
+ (cgraph_varpool_node): Use INSERT.
+ (cgraph_varpool_node_for_identifier): Use NO_INSERT.
+
+2003-10-02 Josef Zlomek <zlomekj@suse.cz>
+
+ Waldek Hebisch <hebisch@math.uni.wroc.pl>
+ PR/12072
+ * varasm.c (compare_constant): Fix thinko.
+
+2003-10-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_issue_rate): New function.
+ (frv_pack_insns): Use it.
+ (TARGET_SCHED_ISSUE_RATE): Define.
+
+2003-10-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * config/mcore/mcore.c: Convert to ISO C90 function declarations
+ and definitions.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore-protos.h: Likewise.
+
+2003-10-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_use_dfa_pipeline_interface): New function.
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE): Define.
+
+2003-10-01 Per Bothner <pbothner@apple.com>
+
+ * c-lex.c (src_line): Remove unneeded static variable.
+ (cb_line_change): Set input_line directly, instead of src_line.
+ (get_non_padding_token): We no longer need to compensate for the
+ "horrible things" the C++ front-end does with the current line number,
+
+ * cpplib.c (_cpp_pop_buffer): Do generate a _cpp_do_file_change
+ callback even when popping the main file.
+ * c-lex.c (fe_file_change): Handle a NULL new_map.
+ * fix-header.c (cb_file_change): Likewise.
+ * c-ppoutput.c (pp_file_change): Likewise.
+
+ * cppinit.c (cpp_read_main_file): Split into two functions:
+ Distribute _cpp_stack_file call over the two functions.
+ (cpp_find_main_file): New function.
+ Don't call _cpp_do_file_change even if working_directory flag set.
+ (cpp_push_main_file): New function.
+ * cppfiles.c (_cpp_find_failed): New helper function.
+ (find_file): Made non-static and renamed to _cpp_find_file.
+ (_cpp_stack_file): No longer needed. But note the following.
+ (stack_file): Made non-static and renamed to _cpp_stack_file.
+ * fix-header.c (cpp_read_main_file): Replace cpp_read_main_file
+ call with calls to cpp_find_main_file and cpp_push_main_file.
+ (search_path_head): If there is no current buffer, use main_file.
+ * cpphash.h: Update function declarations.
+ * cpplib.h: Update function declarations.
+
+ * c-opts.c (c_common_post_options): Don't call cpp_find_main_file yet.
+ (c_common_parse_file): No longer need to call cpp_read_main_file
+ when file_index > 0 (as in multi-file or server compiation).
+ (finish_options): Change to <built-in> is an LC_ENTER, not LC_RENAME
+ as this now happens before cpp_push_main_file.
+ (push_command_line_include): When done with options, pass LC_LEAVE
+ instead of LC_RENAME to cpp_change_file and finally cpp_push_main_file.
+ (fe_file_change): Handle NULL new_map, and simplify.
+ * cpplex.c (_cpp_get_fresh_line): Revert my no-longer-needed
+ 08-28 change, since we're never called with a NULL buffer.
+ (_cpp_lex_direct): Likewise.
+ * cpptrad.c (_cpp_read_logical_line_trad): Likewise.
+ Return false if buffer is NULL at end.
+
+ * cpplex.c (_cpp_get_fresh_line): Return value now just depends on
+ whether pfile->buffer is NULL after pop, ignoring return_at_eof.
+ * cpphash.h (struct cpp_buffer): Remove unused return_at_eof field.
+ * cpplib.c (cpp_push_buffer): Since we no longer set return_at_eof,
+ remove the unused return_at_eof parameter.
+ * cppfiles.c, cpplib.c, cppmacro.c, cpppch.c, fix-header.c:
+ Update callers of cpp_push_buffer.
+
+2003-10-01 Zack Weinberg <zack@codesourcery.com>
+
+ * target.h (init_libfuncs): New hook.
+ * target-def.h: Default TARGET_INIT_BUILTINS and
+ TARGET_INIT_LIBFUNCS to hook_void_void. Add
+ TARGET_INIT_LIBFUNCS to TARGET_INITIALIZER.
+ * builtins.c (default_init_builtins): Delete.
+ * expr.h (default_init_builtins): Delete prototype.
+ * doc/tm.texi: Document TARGET_INIT_LIBFUNCS and US_SOFTWARE_GOFAST.
+ Tweak documentation of TARGET_FLOAT_LIB_COMPARE_RETURNS_BOOL.
+ Remove documentation of INIT_TARGET_OPTABS, MULSI3_LIBCALL,
+ DIVSI3_LIBCALL, UDIVSI3_LIBCALL, MODSI3_LIBCALL, UMODSI3_LIBCALL,
+ MULDI3_LIBCALL, DIVDI3_LIBCALL, UDIVDI3_LIBCALL, MODDI3_LIBCALL,
+ and UMODDI3_LIBCALL,
+
+ * Makefile.in (optabs.o): Depends on target.h.
+ * defaults.h: Provide default for FLOAT_LIB_COMPARE_RETURNS_BOOL.
+ * optabs.c: Include target.h.
+ (prepare_float_lib_cmp): No need for #ifdef around use of
+ FLOAT_LIB_COMPARE_RETURNS_BOOL.
+ (set_optab_libfunc): New function.
+ (init_optabs): Delete use of all *_LIBCALL defines.
+ Call targetm.init_libfuncs not INIT_TARGET_OPTABS.
+ * optabs.h: Prototype set_optab_libfunc.
+
+ * config.gcc: Remove all references to pa/long_double.h,
+ ia64/hpux_longdouble.h, and gofast.h.
+ (mips-*-*): When --enable-gofast, just add US_SOFTWARE_GOFAST
+ to tm_defines; don't set INIT_SUBTARGET_OPTABS or change tm_file.
+
+ * config/alpha/alpha.c, config/c4x/c4x.c, config/cris/cris.c
+ * config/frv/frv.c, config/h8300/h8300.c, config/i860/i860.c
+ * config/ia64/ia64.c, config/ip2k/ip2k.c, config/m68hc11/m68hc11.c
+ * config/mips/mips.c, config/pa/pa.c, config/rs6000/rs6000.c
+ * config/sparc/sparc.c, config/vax/vax.c:
+ Provide a definition for TARGET_INIT_LIBFUNCS. Where
+ necessary, include optabs.h, libfuncs.h, and/or config/gofast.h.
+
+ * config/alpha/unicosmk.h, config/alpha/vms.h, config/c4x/c4x.h
+ * config/avr/avr.h, config/cris/cris.h, config/frv/frv.h
+ * config/h8300/h8300.h, config/i860/i860.h, config/ip2k/ip2k.h
+ * config/iq2000/iq2000.h, config/m68hc11/m68hc11.h, config/mips/mips.h
+ * config/rs6000/aix.h, config/rs6000/sysv4.h, config/sparc/elf.h
+ * config/sparc/lite.h, config/sparc/netbsd-elf.h, config/sparc/sol2.h
+ * config/sparc/sparc.h, config/v850/v850.h, config/vax/vax.h
+ * config/vax/elf.h: Don't define or use INIT_TARGET_OPTABS,
+ INIT_SUBTARGET_OPTABS, or any *_LIBCALL macros.
+
+ * config/ia64/hpux.h: Redefine INTEL_EXTENDED_IEEE_FORMAT to 0.
+ Set TARGET_INIT_LIBFUNCS and FLOAT_LIB_COMPARE_RETURNS_BOOL here.
+ * config/pa/pa-hpux.h: Define LONG_DOUBLE_TYPE_SIZE,
+ HPUX_LONG_DOUBLE_LIBRARY, and FLOAT_LIB_COMPARE_RETURNS_BOOL here.
+ * config/ia64/hpux_longdouble.h, config/pa/long_double.h: Delete.
+
+ * config/rs6000/xcoff.h: Don't define RS6000_ITRUNC nor RS6000_UITRUNC.
+ * config/sparc/sparc.h: Default SUN_CONVERSION_LIBFUNCS and
+ SUN_INTEGER_MULTIPLY_64 to 0.
+ * config/sparc/sol2.h: Redefine SUN_CONVERSION_LIBFUNCS and
+ SUN_INTEGER_MULTIPLY_64 to 1.
+ * config/sparc/elf.h: Redefine SUN_CONVERSION_LIBFUNCS and
+ SUN_INTEGER_MULTIPLY_64 to 0.
+ * config/sparc/lite.h, config/sparc/liteelf.h, config/sparc/sp86x-elf.h:
+ Define US_SOFTWARE_GOFAST.
+ * config/vax/vax.h: Default TARGET_ELF to 0.
+ * config/vax/elf.h: Redefine TARGET_ELF to 1.
+
+ * config/gofast.h: Don't define any macros here. Provide one
+ static function, gofast_maybe_init_libfuncs, which does what
+ INIT_GOFAST_LIBFUNCS used to do but only if US_SOFTWARE_GOFAST
+ is already defined. Do not clear negation libfuncs. Do
+ not mess with HFmode, XFmode, or TFmode libfuncs.
+
+ * config/avr/avr.c (avr_init_once): #if 0 out; mark FIXME.
+
+2003-10-01 Kelley Cook <kelleycook@wideopenwest.com>
+
+ PR C/12466
+ * c-parse.in (parmlist_2): Mark declaration with an ellipsis as ISO C.
+
+2003-10-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/xm-iris5.h: Remove, unnecessary.
+ * config.build (mips-sgi-irix5*): Remove.
+ (mips-sgi-irix6*o32): Likewise.
+ * config.gcc (mips-sgi-irix6*o32): Remove xm_file.
+ (mips-sgi-irix5cross64): Likewise.
+ (mips-sgi-irix5*): Likewise.
+ * config.host (mips-sgi-irix5*): Remove.
+ (mips-sgi-irix6*o32): Likewise.
+
+2003-10-01 Zack Weinberg <zack@codesourcery.com>
+
+ * dbxout.c (dbxout_fptype_value): Delete.
+ (dbxout_type): Emit R3 for all COMPLEX_TYPEs.
+
+2003-10-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * output.h (compute_reloc_for_constant): Declare.
+ * varasm.c (compute_reloc_for_constant): Extract from...
+ (output_addressed_constants): ... here. Adjust all callers.
+
+2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * aclocal.m4: Add hpux10* and hpux11.00 to /dev/zero blacklist.
+ * configure: Rebuilt.
+
+2003-10-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * fold-const.c (make_range): When handling unsigned, don't reverse
+ range if high bound is zero.
+
+2003-09-30 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.h (PREDICATE_CODES): Added
+ condexec_si_media_operator, condexec_sf_add_operator and
+ condexec_sf_conv_operator. Removed condexec_sf_binary_operator
+ and condexec_sf_unary_operator.
+
+2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * aclocal.m4: Add ultrix* to /dev/zero blacklist.
+ * configure: Rebuilt.
+
+2003-10-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * except.h (MUST_USE_SJLJ_EXCEPTIONS): Revert 2003-09-23 change.
+ Allow override.
+ * doc/tm.texi (MUST_USE_SJLJ_EXCEPTIONS): Document.
+
+2003-09-23 David S. Miller <davem@redhat.com>
+
+ * config/sparc/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Undefine
+ before redefining.
+ * config/sparc/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Likewise.
+
+2003-10-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/cris/cris-protos.h, config/cris/cris.c: Convert to ISO
+ C90 function declarations and definitions.
+
+2003-10-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (cris-*-linux*): Revert mistaken commit.
+
+2003-10-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11753
+ * config/sparc/sparc.md (length attribute) [fcc branch]: Add 1 to
+ the length in the non-V9 case.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor
+ DWARF_ALT_FRAME_RETURN_COLUMN.
+ * unwind-dw2.c (dwarf_reg_size_table): Expand by one.
+ (_Unwind_GetGR, _Unwind_SetGR): Validate lookup column.
+ (uw_frame_state_for): Return end-of-stack for null return address.
+ * doc/tm.texi (DWARF_ALT_FRAME_RETURN_COLUMN): Add.
+
+ * config/alpha/alpha.c (alpha_sa_mask): Add r31 for eh_return.
+ (alpha_expand_prologue): Store a zero for it.
+ (alpha_expand_epilogue): Don't reload it.
+ * config/alpha/alpha.h (DWARF_ALT_FRAME_RETURN_COLUMN): New.
+ * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Use column 64
+ for the sigframe return address.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * sdbout.c: Convert to ISO C90 prototypes.
+ * objc/objc-act.c: Likewise.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * config/i386/cygwin1.c: Convert to ISO C90 prototypes.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/cygming.h: Likewise.
+
+2003-09-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Fold (A & ~B) - (A & B) into
+ (A ^ B) - B for any B.
+
+2003-09-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (arm*-*-kaos*, i[34567]86-*-kaos*, powerpc-*-kaos*,
+ powerpcle-*-kaos*, strongarm-*-kaos*): Disable fixproto.
+
+2003-09-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/ieee754-sf.S: Tidy formatting.
+
+2003-09-30 Nicolas Pitre <nico@cam.org>
+
+ * arm/lib1funcs.asm (ARM_DIV_MOD_BODY): Split into ARM_DIV_BODY
+ and ARM_MOD_BODY.
+ (ARM_MOD_BODY): Rewritten. added clz insns for __ARM_ARCH__ >= 5.
+ (ARM_DIV_BODY): Added clz insns for __ARM_ARCH__ >= 5,
+ added better divisor alignment in the other case.
+ (ARM_DIV2_ORDER): Added, finds the order of a single bit divisor.
+ (__divsi3, __udivsi3, __modsi3, __umodsi3): rewritten using the
+ macros above, add fast exits for divisor >= dividend, etc.
+
+2003-09-30 Nicolas Pitre <nico@cam.org>
+
+ * arm/ieee754-df.S: Split compilation of fixunsdfsi from
+ L_fixdfsi target.
+ * arm/t-arm-elf (LIB1ASMFUNCS): Add _fixunsdfsi.
+
+2003-09-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Default use_fixproto to 'no'.
+
+2003-09-30 Richard Sandiford <rsandifo@redhat.com>
+
+ PR optimization/12345
+ * config/mips/mips-protos.h (mips_restore_gp): Remove.
+ (mips_gp_save_slot): Declare.
+ * config/mips/mips.c (mips_restore_gp): Remove in favor of...
+ (mips_gp_save_slot): ...this new function.
+ * config/mips/mips.md (exception_receiver): Use mips_gp_save_slot
+ and mips_output_move to generate the output template.
+ (call_internal): Force splitting if TARGET_SPLIT_CALLS. Don't emit
+ a gp load after a noreturn call. Load the gp using a move rather
+ than an exception_receiver pattern.
+ (call_value_internal, call_value_multiple_internal): Likewise.
+ (call_split, call_value_split, call_value_multiple_split): Clobber $28.
+
+2003-09-30 Carlo Wood <carlo@alinoe.com>
+
+ PR debug/12319
+ * cfglayout.c (insn_scope): Use prologue_locator and
+ epilogue_locator; return the outer function scope for
+ pro- and epilogue insns.
+
+2003-09-29 Zack Weinberg <zack@codesourcery.com>
+
+ * objc/objc-act.c (encode_type): Encode INTEGER_TYPEs and
+ REAL_TYPEs based on the bitsize of the type's mode, not the
+ mode directly.
+
+2003-09-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * dwarf2out.c (default_eh_frame_section): Split into ...
+ (named_section_eh_frame_section, collect2_eh_frame_section): ... new
+ functions.
+ * output.h (named_section_eh_frame_section): Declare.
+ (collect2_eh_frame_section): Likewise.
+
+2003-09-29 Zack Weinberg <zack@codesourcery.com>
+
+ * real.c (real_sqrt): Use get_canonical_qnan directly.
+
+ * dwarf2out.c (add_const_value_attribute): Use real_to_target.
+
+ * varasm.c (assemble_real): Use real_to_target directly,
+ calculate the number of significant elements of the result
+ array and write them out in a loop, instead of using a giant
+ switch statement to pick the correct REAL_VALUE_TO_TARGET_*
+ macro.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12175
+ * varasm.c (notice_global_symbol): Discard external symbols.
+
+ PR optimization/12286
+ * gcov-io.c (gcov_read_words): Fix memmove call.
+ * profile.c (compute_branch_probabilities): Add extra sanity checks.
+
+2003-09-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (sparc-*-solaris2*): Handle Solaris 10 and up like
+ Solaris 7-9.
+
+ * fixinc/inclhack.def (solaris_widec): Replace solaris2.[0-5]* by
+ wildcards which explicitly match micro versions.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Fold (A & ~B) - (A & B) into
+ (A ^ B) - B, where B is any power of 2 minus 1.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ * libgcov.c (gcov_exit): Fix two pastos.
+
+2003-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tst_extzv_1_n): Combine with the
+ define_split immediately below to form define_insn_and_split.
+
+2003-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tstsi_variable_bit): New.
+ (*tstsi_variable_bit_qi): Likewise.
+
+2003-09-28 Phil Edwards <phil@codesourcery.com>
+
+ * doc/cppopts.texi: Use 'dashMP' instead of '-MP' as a cross-
+ reference name.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (duplicate_decls): Copy DECL_SOURCE_LOCATION, not
+ file and line separately.
+
+2003-09-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*adddi3_carry1_cc", "*adddi3_carry1_cconly",
+ "*adddi3_carry2_cc", "*adddi3_carry2_cconly", "*subdi3_borrow_cc",
+ "*subdi3_borrow_cconly"): New insns.
+ ("*addsi3_sub", "*subsi3_sub"): Remove.
+ ("*subdi3_cc", *subdi3_cconly"): Use only if TARGET_64BIT.
+ ("*subsi3_cc"): Fix op_type attribute.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * stmt.c (expand_asm_operands): Take a location_t, instead of
+ individual file and line.
+ * c-typeck.c (c_expand_asm_operands): Likewise.
+ * tree.h (expand_asm_operands): Update decl.
+ * c-common.h (c_expand_asm_operands): Likewise.
+ * c-semantics (genrtl_asm_stmt): Update call.
+
+2003-09-28 Philip Blundell <philb@gnu.org>
+
+ * config/arm/arm.c (legitimize_pic_address): Check
+ SYMBOL_REF_LOCAL_P, not ENCODED_SHORT_CALL_ATTR_P.
+ (arm_assemble_integer): Likewise.
+
+2003-09-28 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/pdp11/pdp11-protos.h, config/pdp11/pdp11.c,
+ config/c4x/c4x-c.c, config/c4x/c4x-protos.h, config/c4x/c4x.c,
+ config/c4x/c4x.h:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-09-28 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/stormy16/stormy16.c, config/stormy16/stormy16-protos.h:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-09-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_constant_info): Add reloc field.
+ (mips_classify_constant): Initialize it. Always set SYMBOL to the
+ underlying symbol, not to an unspec.
+ (mips_delegitimize_address, print_operand): Clean up accordingly.
+
+2003-09-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips16_gp_pseudo_reg): Remove.
+ * config/mips/mips.h (LEGITIMATE_CONSTANT_P): Remove orphaned comment.
+ * config/mips/mips.c (mips_reloc_offset_ok_p): New function.
+ (mips_classify_constant): Use it.
+ (mips_splittable_symbol_p): Add an offset argument.
+ (mips_classify_address): Adjust call accordingly.
+ (mips_legitimize_symbol): Handle sdata references with LO_SUM rather
+ than a relocation unspec. Update call to mips_splittable_symbol_p.
+ Generalize the code that copes with symbols + invalid offsets.
+ (print_operand): Allow '%R' to be applied to small data addresses.
+ (mips_reloc_string): Remove RELOC_GPREL16.
+ (mips_sdata_pointer): Renamed from mips16_gp_pseudo_reg. Return $gp
+ for TARGET_EXPLICIT_RELOCS. Return null if we can't use gp-relative
+ relocation operators.
+ * config/mips/mips.md (RELOC_GPREL16): Remove. Shuffle other reloc
+ constants accordingly.
+
+2003-09-27 Roger Sayle <roger@eyesopen.com>
+
+ * toplev.c (flag_evaluation_order): New global variable.
+ * flags.h (flag_evaluation_order): Prototype here.
+ * expr.c (expand_operands): If we need to preserve observable
+ evaluation order, protect exp1 from clobbering exp0's result.
+
+2003-09-28 Andreas Jaeger <aj@suse.de>
+
+ * c-decl.c (finish_function): Convert definition to ISO C90.
+ * ifcvt.c (mark_loop_exit_edges): Likewise.
+ * ra-rewrite.c (emit_colors): Likewise.
+
+2003-09-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (alpha*-dec-osf[45]*): Disable fixproto.
+ * config.gcc (arm*-*-uclinux*): Disable fixproto.
+ * config.gcc (powerpc-*-eabispe*, powerpc-*-eabisimaltivec*,
+ powerpc-*-eabialtivec*): Disable fixproto.
+
+2003-09-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12340
+ * loop.h (struct induction): Document the new semantics
+ of the 'same' field for bivs.
+ * unroll.c (biv_total_increment): Don't count the same
+ biv increment several times.
+ (loop_iterations) [GENERAL_INDUCT]: Likewise.
+
+2003-09-27 Graham Stott <graham.stott@btinternet.com>
+
+ * unroll.c (loop_interations)[GT]: Add missing break.
+
+2003-09-27 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/chorus.h, config/darwin-c.c, config/darwin-protos.h,
+ config/darwin.c, config/darwin.h, config/dbx.h, config/dbxcoff.h,
+ config/dbxelf.h, config/elfos.h, config/fp-bit.h,
+ config/freebsd-nthr.h, config/freebsd-spec.h, config/freebsd.h,
+ config/freebsd3.h, config/freebsd4.h, config/freebsd5.h,
+ config/freebsd6.h, config/netbsd-aout.h, config/netbsd-elf.h,
+ config/netbsd.h, config/netware.h, config/openbsd-oldgas.h,
+ config/openbsd.h, config/ptx4.h, config/alpha/alpha-protos.h,
+ config/alpha/alpha.c, config/alpha/alpha.h, config/alpha/alpha.md,
+ config/alpha/elf.h, config/alpha/ev4.md, config/alpha/ev5.md,
+ config/alpha/ev6.md, config/alpha/freebsd.h, config/alpha/linux-elf.h,
+ config/alpha/linux.h, config/alpha/netbsd.h, config/alpha/openbsd.h,
+ config/alpha/osf.h, config/alpha/osf5.h, config/alpha/unicosmk.h,
+ config/alpha/vms-cc.c, config/alpha/vms-crt0-64.c,
+ config/alpha/vms-crt0.c, config/alpha/vms-dwarf2.asm,
+ config/alpha/vms-dwarf2eh.asm, config/alpha/vms-ld.c,
+ config/alpha/vms-psxcrt0-64.c, config/alpha/vms-psxcrt0.c,
+ config/alpha/vms.h, config/alpha/vms64.h, config/alpha/vms_tramp.asm,
+ config/alpha/xm-vms.h, config/arc/arc-modes.def,
+ config/arc/arc-protos.h, config/arc/arc.c, config/arc/arc.h,
+ config/arc/arc.md, config/arc/initfini.c, config/arc/lib1funcs.asm,
+ config/avr/avr-protos.h, config/avr/avr.c, config/avr/avr.h,
+ config/avr/avr.md, config/d30v/d30v-protos.h, config/d30v/d30v.h,
+ config/d30v/d30v.md, config/fr30/fr30-protos.h, config/fr30/fr30.c,
+ config/fr30/fr30.h, config/fr30/fr30.md, config/fr30/lib1funcs.asm,
+ config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c,
+ config/frv/frv-abi.h, config/frv/frv-asm.h, config/frv/frv-modes.def,
+ config/frv/frv-protos.h, config/frv/frv.c, config/frv/frv.h,
+ config/frv/frv.md, config/frv/frvbegin.c, config/frv/frvend.c,
+ config/frv/lib1funcs.asm, config/h8300/clzhi2.c, config/h8300/ctzhi2.c,
+ config/h8300/parityhi2.c, config/h8300/popcounthi2.c,
+ config/i370/i370-c.c, config/i370/i370-protos.h, config/i370/i370.c,
+ config/i370/i370.h, config/i370/i370.md, config/i370/linux.h,
+ config/i370/mvs.h, config/i370/oe.h, config/i386/darwin.h,
+ config/i960/i960-c.c, config/i960/i960-coff.h,
+ config/i960/i960-modes.def, config/i960/i960-protos.h,
+ config/i960/i960.c, config/i960/i960.h, config/i960/i960.md,
+ config/i960/rtems.h, config/ia64/elf.h, config/ia64/ia64.h,
+ config/m32r/initfini.c, config/m32r/m32r-protos.h, config/m32r/m32r.c,
+ config/m32r/m32r.h, config/m32r/m32r.md, config/m68hc11/larith.asm,
+ config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c,
+ config/m68hc11/m68hc11.h, config/m68hc11/m68hc11.md,
+ config/m68hc11/m68hc12.h, config/m68k/coff.h, config/m68k/crti.s,
+ config/m68k/crtn.s, config/m68k/hp320.h, config/m68k/hp320base.h,
+ config/m68k/lb1sf68.asm, config/m68k/linux.h, config/m68k/m68020-elf.h,
+ config/m68k/m68k-aout.h, config/m68k/m68k-none.h,
+ config/m68k/m68k-protos.h, config/m68k/m68k.c, config/m68k/m68k.h,
+ config/m68k/m68k.md, config/m68k/m68kelf.h, config/m68k/m68kv4.h,
+ config/m68k/netbsd-elf.h, config/m68k/openbsd.h,
+ config/m68k/rtemself.h, config/m68k/sgs.h, config/mcore/lib1.asm,
+ config/mcore/mcore-elf.h, config/mcore/mcore-pe.h,
+ config/mcore/mcore-protos.h, config/mcore/mcore.c,
+ config/mcore/mcore.md, config/mips/elf.h, config/mips/elf64.h,
+ config/mips/elforion.h, config/mips/iris5.h, config/mips/iris6.h,
+ config/mips/iris6gld.h, config/mips/irix6-libc-compat.c,
+ config/mips/linux.h, config/mips/mips-protos.h, config/mips/mips.c,
+ config/mips/mips.h, config/mips/mips.md, config/mips/netbsd.h,
+ config/mips/openbsd.h, config/mips/r3900.h, config/mips/rtems.h,
+ config/mips/vr.h, config/mn10300/linux.h,
+ config/mn10300/mn10300-protos.h, config/mn10300/mn10300.c,
+ config/mn10300/mn10300.h, config/mn10300/mn10300.md,
+ config/ns32k/__unorddf2.c, config/ns32k/__unordsf2.c,
+ config/ns32k/netbsd.h, config/ns32k/ns32k-protos.h,
+ config/ns32k/ns32k.c, config/ns32k/ns32k.h, config/ns32k/ns32k.md,
+ config/pdp11/2bsd.h, config/pdp11/pdp11-modes.def,
+ config/pdp11/pdp11-protos.h, config/pdp11/pdp11.c,
+ config/pdp11/pdp11.h, config/pdp11/pdp11.md, config/rs6000/biarch64.h,
+ config/rs6000/default64.h, config/sh/coff.h, config/sh/crt1.asm,
+ config/sh/crti.asm, config/sh/crtn.asm, config/sh/elf.h,
+ config/sh/embed-elf.h, config/sh/linux.h, config/sh/little.h,
+ config/sh/netbsd-elf.h, config/sh/rtems.h, config/sh/rtemself.h,
+ config/sh/sh-protos.h, config/sh/sh.c, config/sh/sh.h,
+ config/sh/sh.md, config/sh/sh64.h, config/sh/shmedia.h,
+ config/sh/sshmedia.h, config/sh/ushmedia.h, config/sparc/pbd.h,
+ config/sparc/sparc.h, doc/install-old.texi, fixinc/fixinc.ptx,
+ fixinc/fixinc.svr4: GNU CC -> GCC.
+
+2003-09-26 Loren James Rittle <ljrittle@acm.org>
+
+ * objc/objc-act.c (tm_p.h): Tweak order.
+ * objc/Make-lang.in (objc/objc-act.o): Add $(TM_P_H).
+
+2003-09-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (hppa*64*-*-linux* | parisc*64*-*-linux*):
+ Include t-slibgcc-elf-ver and t-linux in tmake_file.
+ * config.gcc (hppa*64*-*-linux* | parisc*64-*-linux*):
+ Disable fixproto.
+ * config.gcc (i960-*-coff*, m68k-*-aout*, sparclite-*-coff*):
+ Disable fixproto.
+ * config.gcc (i[34567]86-*-solaris2*, sparc64-*-solaris2*,
+ sparcv9-*-solaris2*, sparc-*-solaris2*): Disable fixproto.
+
+ * config/i386/unix.h: Remove (unused) DEFAULT_ASSEMBLER_DIALECT.
+
+2003-09-26 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/i386.h (ix86_return_in_memory): Revert my last patch.
+ * objc/objc-act.c (tm_p.h): Include.
+
+2003-09-26 Per Bothner <pbothner@apple.com>
+
+ * dbxout.c (dbxout_typedefs): Output typedefs in forward order.
+ No longer any need to reverse by recursion.
+
+2003-09-26 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/11741
+ * gcse.c (pre_insert_copy_insn): Tweak the logic for finding the
+ appropriate set to match that in hash_scan_insn. Fall back to
+ the original copy method, if we can't validate changing insn.
+ (pre_delete): Only delete instructions that have a single_set,
+ instead of aborting when we encounter an PARALLEL insn with more
+ then one SET.
+
+2003-09-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("builtin_setjmp_setup"): Insn deleted.
+ ("builtin_longjmp"): Insn deleted.
+ ("save_stack_nonlocal"): Save literal pool base pointer behind
+ backchain and stack pointer.
+ ("restore_stack_nonlocal"): Restore literal pool base pointer.
+ * config/s390/s390.h (STACK_SAVEAREA_MODE): Double size of
+ the stack save area for the nonlocal goto case.
+
+2003-09-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR bootstrap/12358
+ * pa.c (output_bvb): Fix typo.
+
+2003-09-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * expmed.c (store_bit_field): Don't search for an integer mode
+ unless we need the result.
+
+2003-09-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * expr.c (emit_move_insn_1): If there is no move pattern for the
+ original mode, try using a pattern for the corresponding integer mode.
+
+2003-09-26 Richard Sandiford <rsandifo@redhat.com>
+
+ PR middle-end/9200
+ * combine.c (if_then_else_cond): Tighten mode check.
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cppcharset.c, cpphash.h: Rename 'struct strbuf' to
+ 'struct _cpp_strbuf'.
+
+ * config/i386/netbsd-elf.h, config/i386/netbsd64.h,
+ config/i386/netware.h, config/i386/nto.h, config/i386/openbsd.h,
+ config/i386/pentium.md, config/i386/pmmintrin.h, config/i386/ppro.md,
+ config/i386/ptx4-i.h, config/i386/rtemself.h, config/i386/sco5.h,
+ config/i386/sol2.h, config/i386/svr3gas.h, config/i386/sysv3.h,
+ config/i386/sysv4-cpp.h, config/i386/sysv4.h, config/i386/sysv5.h,
+ config/i386/unix.h, config/i386/uwin.h, config/i386/vsta.h,
+ config/i386/xm-cygwin.h, config/i386/xm-djgpp.h,
+ config/i386/xm-mingw32.h, config/i386/xmmintrin.h: Replace
+ "GNU CC", "GNU compiler", and "GNU C-compiler" with "GCC".
+ * config/i386/i386-aout.h, config/i386/i386-coff.h,
+ config/i386/i386-interix.h, config/i386/i386-interix3.h,
+ config/i386/i386-modes.def, config/i386/i386-protos.h,
+ config/i386/i386.c, config/i386/i386.h, config/i386/i386.md,
+ config/i386/i386elf.h, config/i386/k6.md, config/i386/kaos-i386.h,
+ config/i386/linux-aout.h, config/i386/linux.h, config/i386/linux64.h,
+ config/i386/lynx-ng.h, config/i386/lynx.h, config/i386/mingw32.h,
+ config/i386/mmintrin.h, config/i386/moss.h: GNU CC -> GCC.
+ "GNU compiler" -> GCC.
+ * config/i386/att.h, config/i386/beos-elf.h, config/i386/biarch64.h,
+ config/i386/bsd.h, config/i386/crtdll.h, config/i386/cygming.h,
+ config/i386/cygwin.h, config/i386/cygwin1.c, config/i386/cygwin2.c,
+ config/i386/darwin.h, config/i386/djgpp.h, config/i386/emmintrin.h,
+ config/i386/freebsd-aout.h, config/i386/freebsd.h,
+ config/i386/freebsd64.h, config/i386/gas.h: GNU CC -> GCC.
+
+2003-09-25 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * cgraph.c (dump_cgraph): Don't output newline before dump. Add in
+ "local" to the callgraph dump. Output "after inlining" earlier.
+ * cgraphunit.c: Fix dumpfile whitespace and commonize headers of the
+ callgraph dumps. Correct misspellings.
+ (cgraph_decide_inlining): Output number of insns before inlining.
+ Output the calling function into which a function is inlined.
+ (cgraph_decide_small_functions): Format dump file like always_inline.
+
+2003-09-25 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/i386.h (ix86_return_in_memory): Add prototype.
+
+2003-09-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_emit_prologue): Simplify accesses to
+ FPR slots in the save area.
+ (s390_emit_epilogue): Likewise.
+
+2003-09-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * cgraph.h (cgraph_remove_edge): Declare.
+ * cgraph.c (cgraph_remove_edge): Make extern.
+ * cgraphunit.c (cgraph_finalize_function): Call cgraph_remove_edge
+ instead of cgraph_remove_call.
+
+2003-09-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * objc/objc-act.c (gen_declaration_1): Fix printf format.
+
+2003-09-25 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (all_cores): arm710t, arm720t and arm740t are all based on the
+ arm7tdmi core.
+
+2003-09-25 Ziemowit Laski <zlaski@apple.com>
+
+ * config/darwin-protos.h (objc_image_info_section):
+ New prototype.
+
+2003-09-25 Ziemowit Laski <zlaski@apple.com>
+
+ * Makefile.in (stub-objc.o): Depend on $(GGC_H).
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Get rid of more gratuitious 'x'es. Actually allow
+ tsc701 as a --with-cpu, --with-tune setting for sparc.
+
+2003-09-25 Ziemowit Laski <zlaski@apple.com>
+
+ * c-parse.in (objc_try_stmt): Do not specify a %type.
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: New 'widely ported system' clause for rtems.
+ Set thread file there, not in individual clauses.
+
+2003-09-25 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/6222
+ * config/mips/mips.c (mips_va_arg): Handle arguments that must be
+ passed on the stack.
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (widely ported systems section): Mostly alphabetize
+ by system. Comment the case where we can't.
+ * config.gcc (widely ported systems section): Reindent and clean up.
+
+ * config.gcc: Remove some unnecessary uses of 'x' in case statements.
+ Actually allow ep9312 as an arm --with-arch setting.
+
+ * config.gcc (*-hpux11): Disable fixproto.
+
+2003-09-24 Phil Edwards <phil@codesourcery.com>
+
+ PR pch/12112
+ * gcc/cppfiles.c (pch_open_file): Return based on combined
+ result of all files.
+ (validate_pch): Return validate flag for current file.
+
+2003-09-24 Roger Sayle <roger@eyesopen.com>
+
+ PR bootstrap/12358
+ * fold-const.c (tree_swap_operands_p): Only reorder operands when
+ one of the operands is constant.
+
+2003-09-24 Ziemowit Laski <zlaski@apple.com>
+
+ MERGE OF objc-improvements-branch into MAINLINE:
+ * Makefile.in (C_OBJS): Add in stub-objc.o.
+ (c-parse.y): Change sed demarcations to begin with '@@'.
+ (stub-objc.o): New rule.
+ * c-common.c (flag_nil_receivers, flag_objc_exceptions, flag_zero_link,
+ flag_replace_objc_classes): New flags.
+ * c-common.h (RID_AT_THROW, RID_AT_TRY, RID_AT_CATCH, RID_AT_FINALLY,
+ RID_AT_SYNCHRONIZED): New keywords.
+ (flag_nil_receivers, flag_objc_exceptions, flag_zero_link,
+ flag_replace_objc_classes): New flags.
+ (lookup_interface, is_class_name, objc_is_object_ptr, objc_check_decl,
+ objc_comptypes, objc_message_selector, lookup_objc_ivar,
+ get_current_scope, objc_mark_locals_volatile): New prototypes,
+ some moved from c-tree.h.
+ * c-decl.c (get_current_scope, objc_mark_locals_volatile): New functions.
+ (finish_decl): Adjust where objc_check_decl() gets called.
+ * c-lang.c (lookup_interface, is_class_name, objc_is_id, objc_check_decl,
+ objc_comptypes, objc_message_selector, lookup_objc_ivar): Remove stubs.
+ * c-opts.c (c_common_handle_option): Add handling for flag_nil_receivers,
+ flag_objc_exceptions, flag_replace_objc_classes and flag_zero_link.
+ * c-parse.in: Replace 'ifc' and 'end ifc' sed markers with '@@ifc' and
+ '@@end_ifc', respectively.
+ (AT_THROW, AT_TRY, AT_CATCH, AT_FINALLY, AT_SYNCHRONIZED): New %tokens.
+ (objc_try_stmt, superclass, class_ivars, objc_try_catch-stmt,
+ objc_finally_block): New rules.
+ (component_decl_list2): Clean up semantic action for @defs construct.
+ (component_decl, c99_block_start): Remove call to add_objc_decls().
+ (poplevel): Add call to objc_clear_super_receiver().
+ (stmt): Add rules for @throw, @try..@catch..@finally and @synchronized
+ constructs.
+ (classdef, methodprotolist): Clean up/simplify.
+ (methodprotolist2): Eliminate.
+ (methodproto): Call add_method() instead of add_class_method() and
+ add_instance_method().
+ (receiver): Add TYPENAME production.
+ (reswords): Add "throw", "try", "catch", "finally" and "synchronized".
+ (rid_to_yy): Add AT_THROW, AT_TRY, AT_CATCH, AT_FINALLY and
+ AT_SYNCHRONIZED.
+ * c-tree.h (lookup_interface, is_class_name, objc_is_id, objc_check_decl,
+ objc_comptypes, objc_message_selector)
+ * c-typeck.c (comptypes): In ObjC mode, call objc_comptypes() for
+ struct and pointer types.
+ (build_c_cast): Do not discard ObjC protocol qualifiers.
+ (convert_for_assignment): Cache result of comp_target_types() instead
+ of calling it more than once.
+ * c.opt (fnext-runtime): Update description string.
+ (fnil-receivers, fobjc-exceptions, freplace-objc-classes, fzero-link):
+ New ObjC/ObjC++-specific flags.
+ * function.h (GCC_FUNCTION_H): Header guard.
+ * gengtype-lex.l: Teach lexer about new @@... sed demarcations.
+ * stub-objc.c: New file, to be used to satisfy references to ObjC
+ functions by the C and C++ front-ends.
+ * config/darwin.c (_OBJC_IMAGE_INFO): New global metadata.
+ * config/darwin.h (FUNCTION): Add in_objc_image_info.
+ (SECTION_FUNCTION): Add objc_image_info_section.
+ * doc/invoke.texi: Link to GCC web site for Objective-C information.
+ (-fconstant-string-class): Update documentation.
+ (-fno-nil-receivers, -fobjc-exceptions, -freplace-objc-classes,
+ -fzero-link): New documentation.
+ * objc/Make-lang.in (objc-parse.y): Change sed demarcations to begin
+ with '@@'.
+ * objc/lang-specs.h (@objective-c-header): Fix -E spec.
+ * objc/objc/objc-act.c: Replace TYPE_NAME with OBJC_TYPE_NAME
+ throughout; provide casts for return values from memory allocation
+ functions (xmalloc, alloca, ggc_alloc, etc.).
+ (OBJC_VOID_AT_END): New macro.
+ (rtl.h): Do not #include any more.
+ (STRING_OBJECT_GLOBAL_NAME): Replaced with STRING_OBJECT_GLOBAL_FORMAT.
+ (TAG_MSGSEND_STRET, TAG_MSGSENDSUPER_STRET, TAG_MSGSEND_NONNIL,
+ TAG_MSGSEND_NONNIL_STRET, TAG_EXCEPTIONEXTRACT, TAG_EXCEPTIONTRYENTER,
+ TAG_EXCEPTIONTRYEXIT, TAG_EXCEPTIONMATCH, TAG_EXCEPTIONTHROW,
+ TAG_SYNCENTER, TAG_SYNCEXIT): New NeXT runtime entry points.
+ (struct val_stack, catch_count_stack, exc_binding_stack, val_stack_push,
+ val_stack_pop): New.
+ (objc_check_decl): Fix precondition for error message, along with
+ the message itself.
+ (lookup_and_install_protocols): Remove nonexistent protocols from
+ protocol list instead of returning error_mark_node.
+ (create_builtin_decl): Use DECL_ARTIFICIAL only for VAR_DECLs.
+ (setup_string_decl): Generalize to use STRING_OBJECT_GLOBAL_FORMAT.
+ (synth_module_prologue): General clean-up; construct NeXT-specific
+ runtime API prototypes if needed.
+ (build_string_class_template): Remove.
+ (check_string_class_template, string_layout_checked): New.
+ (build_objc_string_object): Generalize to work with
+ -fconstant-string-class.
+ (build_objc_symtab_template): Fix layout for the NeXT runtime.
+ (build_metadata_decl): New.
+ (forward_declare_categories): Call build_metadata_decl() instead of
+ create_builtin_decl() et al.
+ (build_module_descriptor): Use OBJC_VOID_AT_END instead of
+ void_list_node_1.
+ (build_selector_reference_decl, build_class_reference_decl,
+ build_objc_string_decl): Do not set TREE_READONLY.
+ (get_proto_encoding): Do not call hack_method_prototype().
+ (get_class_reference): Add failure mode for invalid class names;
+ support -fzero-link; defer if in an ObjC++ template declaration.
+ (objc_declare_alias, objc_declare_class): Fix up duplicate name
+ lookup; check for global scope if in ObjC++.
+ (is_class_name): Generalize to work with various tree nodes (TYPE_DECL,
+ RECORD_TYPE, IDENTIFIER_NODE, etc.)
+ (objc_is_id): Removed.
+ (objc_is_object_ptr): New function.
+ (get_class_ivars_from_name): New function, used for @defs construct.
+ (get_class_ivars): Add option to return raw ivars; create a
+ ClASS_OWN_IVARS list for each class as needed.
+ (objc_enter_block, objc_exit_block, objc_declare_variable,
+ objc_build_throw_stmt, val_stack_push, val_stack_pop,
+ objc_build_try_enter_fragment, objc_build_extract_expr,
+ objc_build_try_exit_fragment, objc_build_extract_fragment,
+ objc_build_try_prologue, objc_build_try_epilogue,
+ objc_build_catch_stmt, objc_build_catch_epilogue,
+ objc_build_finally_prologue, objc_build_finally_epilogue,
+ objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
+ objc_build_synchronized_epilogue, build_objc_exception_stuff):
+ New functions.
+ (_JBLEN): _setjmp jmpbuf size (needs to be made a target hook in
+ the future).
+ (build_private_template): Fix up calls to get_class_ivars().
+ (offset_is_register, forwarding_offset): Remove.
+ (objc_method_parm_type, objc_encoded_type_size): New functions.
+ (encode_method_prototype): Simplify to no longer depend on
+ back-end information.
+ (build_tmp_function_decl_xxx, build_tmp_function_decl,
+ hack_method_prototype): Removed.
+ (generate_protocol_references): Remove calls to
+ build_tmp_function_decl().
+ (generate_protocols): Adjust calls to encode_method_prototype().
+ (build_class_template): Generate sel_id' and 'gc_object_type' fields
+ for the NeXT runtime.
+ (synth_forward_declarations): Call build_metadata_decl().
+ (check_ivars): Check that the number of ivars matches also.
+ (build_super_template): Modify super_type directly; disable debugging
+ output while generating decl.
+ (build_ivar_list_initializer): Skip list elements that are not
+ FIELD_DECLs.
+ (ivar_list_length): New function.
+ (generate_ivar_lists): Call ivar_list_length() instead of list_length()
+ and encode_method_prototype() instead of encode_method_def().
+ (build_shared_structure_initializer): Generate 'sel_id' field for
+ the NeXT runtime.
+ (generate_category): Do not set TREE_USED.
+ (build_keyword_selector): Ditto; transform into a function argument
+ chain.
+ (get_arg_type_list): If there are no user-specified arguments, use
+ '...'; use OBJC_VOID_AT_END.
+ (check_duplicates): Add a parameter indicating whether methods or
+ selectors are being checked.
+ (receiver_is_class_object): Add parameters indicating whether
+ receiver is 'self' or 'super'; robustify.
+ (build_message_expr): Defer call to finish_message_expr() if
+ inside an ObjC++ template.
+ (lookup_method_in_hash_lists): New function.
+ (finish_message_expr): Complete rewrite/fix.
+ (build_objc_method_call): Ditto; factor out commonalities between
+ the GNU and NeXT runtimes; acccommodate ..._stret and ...NonNil
+ messenger variants on the NeXT.
+ (lookup_instance_method_static, lookup_class_method_static):
+ Fold into a single lookup_method_static() function with an
+ additional parameter.
+ (add_class_method, add_instance_method): Fold into a single
+ add_method() function with an additional parameter.
+ (add_category): Make duplicate categories a hard error in ObjC++.
+ (add_instance_variable): Properly handle unnamed ivars, arrays of
+ zero or no size and bitfields. In ObjC++, check for nontrivial
+ C++ class instances.
+ (is_public): Allow C functions to access non-@public ivars, with
+ a warning.
+ (start_class): Move common initializations to
+ synth_module_prologue(); check for global scope if in ObjC++.
+ (continue_class): Fix calls to finish_struct().
+ (objc_declare_protocols, start_protocol): Check for global scope
+ if in ObjC++.
+ (encode_pointer): Encode 'BOOL *' specially on the NeXT.
+ (encode_aggregate_within): Rewrite to properly distinguish
+ struct tags from typedefs in both ObjC and ObjC++.
+ (encode_bitfield, encode_complete_bitfield): Remove.
+ (encode_next_bitfield, encode_gnu_bitfield): New functions.
+ (encode_field_decl): Call encode_next_bitfield() or
+ encode_gnu_bitfield() as needed.
+ (synth_self_and_ucmd_args): New function.
+ (start_method_def): Use it.
+ (objc_types_are_equivalent): New function.
+ (comp_proto_with_proto): Use it instead of comptypes(), since
+ we need symmetry.
+ (really_start_method): Use lookup_method_static() instead of
+ lookup_class_method_static() and lookup_instance_method_static();
+ Emit 'extern "C"' if in ObjC++ mode.
+ (add_objc_decls): Removed.
+ (UOBJC_SUPER_scope): New variable.
+ (get_super_receiver): Move construction of 'super' from
+ add_objc_decls(); remove dependency on struct objc_class.
+ (encode_method_def): Removed; encode_method_prototype() is
+ used instead.
+ (objc_clear_super_receiver): New function.
+ (objc_expand_function_end): Do not do anything for ordinary
+ C functions.
+ (finish_method_def): Mark ObjC methods as un-inlinable.
+ (gen_declaration_1): Emit widths of bitfields.
+ (finish_objc): Call generate_objc_image_info() if needed;
+ use check_duplicates() when checking for selector duplicates.
+ (generate_objc_image_info): New function.
+ * objc/objc-act.h (add_instance_method, add_class_method,
+ get_class_ivars): Remove prototypes.
+ (objc_build_throw_stmt, objc_build_try_catch_finally_stmt,
+ objc_build_synchronized_prologue, objc_build_synchronized_epilogue,
+ objc_build_catch_stmt, objc_build_catch_epilogue,
+ objc_build_finally_prologue, objc_build_finally_epilogue,
+ add_method, get_class_ivars_from_name): New prototypes.
+ (CLASS_BINFO_ELTS, PROTOCOL_BINFO_ELTS): New.
+ (TYPE_PROTOCOL_LIST): Robustify to distinguish from
+ TRANSLATION_UNIT_DECLs.
+ (OBJC_TYPE_NAME): New.
+ (objc_tree_code): Ensure that either <c-tree.h> or <cp/cp-tree.h>
+ got included.
+ (IS_SUPER): Robustify.
+ (umsg_stret_decl, umsg_super_stret_decl, umsg_nonnil_decl,
+ umsg_nonnil_stret_decl, objc_storage_class, objc_exception_extract_decl,
+ objc_exception_try_enter_decl, objc_exception_try_exit_decl,
+ objc_exception_match_decl, objc_exception_throw_decl,
+ objc_sync_enter_decl, objc_sync_exit_decl, objc_exception_data_template,
+ objc_setjmp_decl, objc_stack_exception_data, objc_caught_exception,
+ objc_rethrow_exception, objc_eval_once, objc_exception_block_stack,
+ objc_catch_type): New ObjC/ObjC++ roots.
+ * objc/objc-tree.def (MESSAGE_SEND_EXPR, CLASS_REFERENCE_EXPR): New
+ ObjC/ObjC++ tree node codes.
+
+2003-09-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * cpplib.c (do_pragma): Reintroduce cb_line_change call in the
+ code path that calls a handler.
+
+2003-09-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (c4x-*, tic4x-*, d30v-*, mmix-knuth-mmixware):
+ Disable fixproto.
+
+ * config.gcc: Clean up and reindent $with_cpu=yes|no clause and
+ the section giving $with_cpu defaults by target.
+
+ * config.gcc (arm-*-coff*, armel-*-coff*, arm*-*-ecos-elf,
+ arm*-*-elf, ep9312-*-elf, arm*-wince-pe*, arm*-*-pe*, arm*-*-pe*,
+ rs6000-ibm-aix4.[3456789]*, powerpc-ibm-aix4.[3456789]*,
+ rs6000-ibm-aix5.1.*, powerpc-ibm-aix5.1.*,
+ rs6000-ibm-aix[56789].*, powerpc-ibm-aix[56789].*,
+ i[34567]86-pc-msdosdjgpp*): Disable fixproto.
+
+2003-09-24 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movti_power): Collapse case 1 and 2
+ together. Protect load string instruction with TARGET_STRING.
+ (movti_string): Collapse case 1 and 2 together.
+
+2003-09-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-common.c (c_common_type_for_mode): Check for VOIDmode.
+
+2003-09-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Wrap in
+ do...while(0)
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Move use_fixproto=no from generic vxworks clause to
+ specific one.
+
+ * config.gcc (powerpc-*-gnu-gnualtivec*): Disable fixproto
+ (accidentally missed in last pass).
+
+2003-09-23 Andrew Pinski <apinski@apple.com>
+
+ PR bootstrap/12383
+ * configure: Regenerate.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (x86_64-*-freebsd*): Disable fixproto (accidentally
+ missed in last pass).
+
+2003-09-23 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md (andsi3): Fix cut&pasto in 0xfffffffe
+ constant.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Move vax-*-vms* unsupported notice up with the rest.
+
+ * config.gcc (alpha64*-dec-*vms*, alpha*-dec-*vms*,
+ powerpc-*-eabisim*, powerpc-*-eabi*, powerpcle-*-eabisim*,
+ powerpcle-*-eabi*): Disable fixproto.
+
+ * config.gcc: Move use_fixproto=no from generic FreeBSD clause to
+ specific FreeBSD clauses.
+ * config.gcc: Move use_fixproto=no from generic NetBSD clause to
+ specific NetBSD clauses.
+ * config.gcc: Move use_fixproto=no from generic OpenBSD clause
+ to specific OpenBSD clauses.
+
+2003-09-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (hppa_expand_prologue): Do pic register save in frame marker
+ without adding a frame note.
+ * pa.md (allocate_stack): Save pic register in new frame marker when
+ generating pic code.
+
+2003-09-23 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * cgraphunit.c (cgraph_expand_all_functions): Renamed from
+ cgraph_expand_functions.
+
+2003-09-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gnucompare*): Merge into ...
+ (slowcompare*): ... here.
+ (fastcompare*): New targets.
+ * aclocal.m4 (gcc_AC_PROG_CMP_IGNORE_INITIAL): Add checks for
+ other "fast" cmp programs.
+ * configure: Regenerate.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * targhooks.c: Include output.h.
+ * Makefile.in (targhooks.o): Add output.h to dependency list.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.host: Removed superfluous newline.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Use ${target}, not $machine.
+ * configure.in: Don't set $machine.
+ * configure: Regenerate.
+
+2003-09-23 Geoffrey Keating <geoffk@apple.com>
+
+ * config/t-darwin (crt2.o): Add stmp-int-hdrs to dependencies.
+
+ * config/rs6000/rs6000.c (function_arg_pass_by_reference): Don't
+ pass zero-size arrays by reference.
+ (rs6000_va_arg): Likewise.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Set use_fixproto=no in each specific *-gnu*
+ configuration, rather than the generic one.
+
+2003-09-23 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (remap_save_expr): Map new save_expr to identity
+ rather than to error_mark_node.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (HAVE_GAS_SHF_MERGE): Always define to test result.
+ Update description.
+ * configure: Regenerate.
+ * config.in: Likewise.
+ * dwarf2out.c (DEBUG_STR_SECTION_FLAGS): Test for
+ HAVE_GAS_SHF_MERGE value.
+ * varasm.c (mergeable_string_section): Likewise.
+ (mergeable_constant_section): Likewise.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * except.h (MUST_USE_SJLJ_EXCEPTIONS): Test for DWARF2_UNWIND_INFO
+ value.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * target.h (struct gcc_target): New member external_libcall.
+ * target-def.h (TARGET_ASM_EXTERNAL_LIBCALL): Provide default.
+ (TARGET_ASM_OUT): Use it.
+ * doc/tm.texi (TARGET_ASM_EXTERNAL_LIBCALL): Document.
+ * targhooks.c: Convert to ISO C 90.
+ (default_external_libcall): New function.
+ * targhooks.h (default_external_libcall): Declare.
+ * varasm.c (assemble_external_libcall): Use
+ targetm.asm_out.external_libcall instead of
+ ASM_OUTPUT_EXTERNAL_LIBCALL.
+ * config/mips/mips-protos.h [TARGET_IRIX5 || TARGET_IRIX 6]
+ (mips_output_external_libcall): Declare.
+ * config/mips/mips.c (mips_output_external_libcall): Change
+ definition guard.
+ Change to match TARGET_ASM_EXTERNAL_LIBCALL.
+ Only operate for O32 ABI.
+ * config/mips/iris5.h (TARGET_ASM_EXTERNAL_LIBCALL): Define
+ instead of ASM_OUTPUT_EXTERNAL_LIBCALL.
+ * config/mips/iris6.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Don't undef,
+ superceded by TARGET_ASM_EXTERNAL_LIBCALL.
+
+2003-09-22 Nathnael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Do per-target disabling of fixproto here in clauses,
+ not in t- fragments.
+ * configure.in: Adjust to set STMP_FIXPROTO correctly.
+ * configure: Regenerate.
+ * config/arm/t-semi, config/cris/t-cris, config/i386/t-beos,
+ config/i386/t-cygming, config/i386/t-nto, config/ia64/t-hpux,
+ t-freebsd, t-linux, t-netbsd, t-openbsd, t-rtems, t-vxworks,
+ xtensa/t-xtensa: Remove setting of STMP_FIXPROTO.
+ * config/i370/t-oe, config/i386/t-netware, config/pa/t-bsd,
+ t-interix, t-linux-aout: Delete files consisting only of
+ setting of STMP_FIXPROTO.
+
+ * config.host: Allow unknown hosts (not targets). Allow
+ ns32k-*-netbsdelf* as a host (not a target). Remove redundant
+ empty clauses. Remove useless obsolete-configuration clause.
+ Prune unsupported configuration list. Collapse identical
+ clauses for closely related systems. Rewrite comment for
+ unsupported hosts list. Reorganize a little.
+
+2003-09-22 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_common_signed_or_unsigned_type): Examine mode,
+ not precision.
+
+2003-09-22 David Edelsohn <edelsohn@gnu.org>
+ Hartmut Penner <hpenner@de.ibm.com>
+ Segher Boessenkool <boessen@de.ibm.com>
+
+ * config/rs6000/rs6000.c (altivec_in_gprs_p): Rename to ...
+ (gpr_or_gpr_p): Test INT_REGNO_P and convert to boolean.
+ (rs6000_split_altivec_in_gprs): Rename to ...
+ (rs6000_split_multireg_move): Add support for update addressing.
+ * config/rs6000/rs6000-protos.h: Same.
+ * config/rs6000/altivec.md: Same.
+ * config/rs6000/rs6000.md (movdi_internal32): Use new splitter for
+ multiple GPRs.
+ (movti): Remove TARGET_STRING || TARGET_POWERPC64 final condition.
+ (movti_power): Use new splitter for multiple GPRs.
+ (movti_string): Same.
+ (movti_ppc64): Same.
+
+2003-09-22 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa-protos.h: Convert to ISO C90.
+ * config/xtensa/xtensa.c: Convert to ISO C90. Minor formatting fixes.
+
+2003-09-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md: Revert 2003-09-17's patch.
+ (andsi3): Set attr cc to set_zn when using shifts or adds.
+
+2003-09-22 Bernardo Innocenti <bernie@develer.com>
+
+ * doc/contrib.texi: Add Peter Barada, Paul Dale and myself.
+
+2003-09-22 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (MASK_RTD, TARGET_RTD, RETURN_POPS_ARGS):
+ Resurrect -mrtd option.
+
+2003-09-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/12281
+ * config/darwin.c (machopic_validate_stub_or_non_lazy_ptr): Call
+ mark_referenced instead of setting TREE_SYMBOL_REFERENCED.
+
+2003-09-22 Olivier Hainque <hainque@act-europe.fr>
+
+ PR target/9786
+ * reg-stack.c (convert_regs_1): Purge possible dead eh edges
+ after potential deletion of trapping insn. Avoids later ICE
+ from call to fixup_abnormal_edges.
+ (convert_regs_2): Stack the current block successors before
+ processing this block, that is, before the potential deletion of
+ dead edges by convert_regs_1, because these edges have been used
+ to initialize the predecessors count.
+
+2003-09-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * real.c: Fix several nits in the head comment.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * tree.h c-aux-info.c, c-decl.c, c-parse.in, coverage.c, dbxout.c,
+ diagnostic.c, dwarf2out.c, dwarfout.c, function.c, integrate.c,
+ print-tree.c, stmt.c, toplev.c, tree-dump.c, tree-inline.c,
+ tree-optimize.c, tree.c, tree.def, xcoffout.c, config/alpha/alpha.c,
+ config/mips/mips.c, doc/c-tree.texi, objc/objc-act.c: Revert.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * tree.h (TREE_LOCUS): Rename from DECL_SOURCE_LOCATION; make const.
+ (TREE_FILENAME, TREE_LINENO): Likewise.
+ (set_tree_locus, copy_tree_locus, set_tree_file_line): New.
+ (TREE_LOCUS_SET_P): New.
+ * c-aux-info.c, c-decl.c, c-parse.in, coverage.c, dbxout.c,
+ diagnostic.c, dwarf2out.c, dwarfout.c, function.c, integrate.c,
+ print-tree.c, stmt.c, toplev.c, tree-dump.c, tree-inline.c,
+ tree-optimize.c, tree.c, tree.def, xcoffout.c, config/alpha/alpha.c,
+ config/mips/mips.c, doc/c-tree.texi, objc/objc-act.c: Update to match.
+
+2003-09-21 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/vax/vax-protos.h: Convert to ISO C90.
+ * config/vax/vax.c: Convert to ISO C90.
+
+2003-09-21 Graham Stott <grahams@btinternet.com>
+
+ PR target/12353
+ * config/i386/i386.md(ffs_no_cmove): Fix operand 2 constraint.
+
+2003-09-21 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12301
+ * reorg.c (stop_search_p): Return 1 for insns that can
+ throw internally.
+
+2003-09-20 Richard Henderson <rth@redhat.com>
+
+ * c-format.c (gcc_diag_char_table): Add %J.
+ (gcc_cdiag_char_table, gcc_cxxdiag_char_table): Likewise.
+ (check_format_types): Fix wanted_type name lookup.
+ (init_dynamic_diag_info): Setup %J.
+ * diagnostic.c (text_specifies_location): Implement %J.
+ * c-common.c, c-decl.c, c-objc-common.c, c-pragma.c, calls.c,
+ dwarfout.c, expr.c, function.c, stmt.c, stor-layout.c, toplev.c,
+ tree-inline.c, tree-optimize.c, varasm.c, config/arm/pe.c,
+ config/i386/winnt.c, config/ia64/ia64.c, config/mcore/mcore.c,
+ config/v850/v850.c, objc/objc-act.c: Use %J in diagnostics.
+
+ * tree-inline.c: Include intl.h
+ (inline_forbidden_p_1): Fix i18n of inline_forbidden_reason.
+ * Makefile.in (tree-inline.o): Update.
+
+2003-09-20 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (ix86_expand_carry_flag_compare): Fix
+ transformation of a>=0 into (unsigned)a<0x80000000.
+
+2003-09-20 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_select_rtx_section): Fix check for PIC code.
+
+2003-09-20 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Don't set (unused) DLLTOOL.
+
+ * config/arm/t-linux, config/arm/t-netbsd, config/arm-t-semi:
+ Remove obsolete references to ENQUIRE.
+
+2003-09-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove --with-elf, which doesn't work.
+ * configure: Regenerate.
+ * config.gcc: Remove references to $elf, which does nothing.
+
+ * config/i386/xm-vsta.h: Remove xm-file believed useless.
+ * config.build (i386-vsta): Remove reference to it.
+ * config.host (i386-vsta): Remove reference to it.
+
+2003-09-19 Phil Edwards <phil@codesourcery.com>
+
+ * doc/install.texi: Document the multiple testsuite options.
+
+2003-09-19 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (Specific): Add the specific versions of GCC
+ where support for FreeBSD 1, HP-UX version 9 and older, and AIX
+ version 3 and older was discontinued.
+
+2003-09-19 Joel Sherrill <joel@oarcorp.com>
+
+ * config/m68k/t-m68kbare, config/m68k/t-rtems: Change 68681 to
+ 68881.
+
+2003-09-19 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (TARGET_CPU_CPP_PREDEFINES): Add predefines
+ for -m68030, -m68020-60 and -m68020-40.
+ * config/m68k/m68k.h (TARGET_68030): New target flag.
+ * config/m68k/m68k.h (MASK_RTD, TARGET_RTD, MASK_REGPARM,
+ TARGET_REGPARM): Remove.
+ * config/m68k/m68k.h: Regroup and renumber target flags.
+ * config/m68k/m68k.h (TARGET_SWITCHES): Fix some tabulations.
+ * config/m68k/m68k.h (RETURN_POPS_ARGS): Always evaluate to 0.
+ * config/m68k/m68k.h (FUNCTION_ARG): Likewise.
+ * config/m68k/m68k.h (FUNCTION_ARG_PARTIAL_NREGS): Likewise.
+ * config/m68k/m68k-none.h: Use MASK_xxx values in M68K_CPU_xxx macros.
+
+2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config/m68k/t-rtems (m68k-*-rtems*): New.
+ * config.gcc: Use config/m68k/t-rtems.
+
+2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config/mips/t-rtems: New.
+ * config.gcc (mips*-*-rtems*): Use config/mips/t-rtems.
+
+2003-09-19 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * cgraph.c: Fix typo in debugging output.
+
+2003-09-19 T. Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12166
+ * config/sparc/sol2-c1.asm (start): Set __Argv if GCRT1.
+
+2003-09-18 Mike Stump <mrs@apple.com>
+
+ * c-ppoutput.c (print): Use fileline typedef for field 'line'.
+ (print_line, maybe_print_line, cb_define, cb_undef, cb_include,
+ cb_ident, cb_def_pragma): Use fileline typedef.
+ * cpphash.h (struct cpp_reader): Likewise for field out.first_line.
+
+2003-09-18 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (gen_stdcall_suffix): Quit summation of
+ total parm size if a parm has incomplete type.
+ (gen_fastcall_suffix): Likewise.
+
+2003-09-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * except.c (output_function_exception_table): Adjust last change
+ to handle TYPE of INTEGER_CST.
+
+2003-09-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR target/11184
+ * builtins.c (expand_builtin_apply): Use convert_memory_address
+ before returning the value.
+
+ * alias.c (find_base_value): Simplify use of
+ convert_memory_address.
+ (find_base_term): Likewise.
+ * builtins.c (expand_builtin_stejmp_setup): Likewise.
+ (expand_builtin_longjmp): Likewise.
+ (expand_builtin_prefetch): Likewise.
+ (get_memory_rtx): Likewise.
+ (expand_builtin_return): Likewise.
+ (expand_builtin_memcpy): Likewise.
+ (expand_builtin_strncpy): Likewise.
+ (expand_builtin_memset): Likewise.
+ (expand_builtin_va_arg): Likewise.
+ (expand_builtin_va_copy): Likewise.
+ (expand_builtin_alloca): Likewise.
+ * calls.c (expand_call): Likewise.
+ * except.c (expand_builtin_extract_return_addr): Likewise.
+ (expand_builtin_eh_return): Likewise.
+ * explow.c (convert_memory_address): Define even when
+ POINTER_EXTEND_UNSIGNED is not defined. Do nothing if the address
+ is already in the right mode.
+ * explow.c (memory_address): Simplify use of convert_memory_address.
+ (probe_stack_range): Likewise.
+ * expmed.c (make_tree): Likewise.
+ * expr.c (emit_block_move_in_libcall): Likewise.
+ (expand_assignment): Likewise.
+ (expand_expr): Likewise.
+ * function.c (assign_parms): Likewise.
+ (expand_function_end): Likewise.
+ * integrate.c (copy_rtx_and_substitute): Likewise.
+ * stmt.c (expand_computed_goto): Likewise.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_unary_operation): Only transform
+ (not (eq X Y)) into (ne X Y) when mode is BImode or STORE_FLAG_VALUE
+ is -1. RTL "not" is a bit-wise not, "~", not a logical not "!".
+
+2003-09-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR target/11674
+ * config/i386/i386.c (x86_emit_floatuns): Also handle SImode operand.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * tree.def (FFS_EXPR, CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR,
+ PARITY_EXPR): Delete unused tree codes.
+ * c-common.c (c_common_truthvalue_conversion): Delete references
+ to FFS_EXPR and POPCOUNT_EXPR.
+ * c-pretty-print.c (pp_c_postfix_expression): Remove FFS_EXPR.
+ (pp_c_expression): Likewise.
+ * expr.c (expand_expr): Delete RTL expansion of FFS_EXPR, CLZ_EXPR,
+ CTZ_EXPR, POPCOUNT_EXPR and PARITY_EXPR.
+ * fold-const.c (tree_expr_nonnegative_p): Remove FFS_EXPR, CLZ_EXPR,
+ CTZ_EXPR, POPCOUNT_EXPR and PARITY_EXPR. Add support for calls to
+ BUILT_IN_FFS, BUILT_IN_PARITY and BUILT_IN_POPCOUNT and their long
+ and long long variants.
+
+2003-09-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (pp_type_specifier_seq): Fix thinko.
+ * c-pretty-print.c: Fix formatting.
+ (pp_c_integer_constant): Append type annotation to literals. Tidy.
+ (pp_c_type_specifier): Tidy.
+ (pp_c_compound_literal): New function.
+ (pp_c_initializer): Simplify..
+ (pp_c_initializer_list): Likewise.
+ (pp_c_brace_enclosed_initializer_list): New function.
+ (pp_c_postfix_expression): Simplify.
+
+2003-09-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md (andsi3, iorsi3, xorsi3,
+ one_complsi2, bit-clear, bit-set, iorqi3): Make them set_zn.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-optimize.c (tree_rest_of_compilation): Save and restore
+ input_location.
+
+2003-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/rs6000/sysv4.h (LIB_LINUX_SPEC): Give -lpthread before -lc.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * cfg.c (dump_flow_info): Skip register dump if reg_n_info null.
+
+2003-09-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_ld_hidden): Don't test gnu_ld_flag.
+ * configure: Regenerate.
+
+2003-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/12066
+ * dbxout.c (dbxout_init): Use a langhook to find builtin types.
+ * langhooks-def.h (lhd_return_null_tree_v): New function.
+ (LANG_HOOKS_BUILTIN_TYPE_DECLS): New macro.
+ (LANG_HOOKS_DECLS): Add it to the intializer.
+ * langhooks.c (lhd_return_null_tree_v): New function.
+ * langhooks.h (lang_hooks_for_decls): Add builtin_type_decls.
+
+2003-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Quote gcc_config_arguments for configargs.h.
+ * configure: Regenerated.
+ * gccbug.in: Don't shell-expand gcc_config_arguments.
+
+2003-09-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11357
+ * c-pretty-print.c (pp_c_floating_constant): Append
+ type-annotation to floating constants.
+
+2003-09-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5.h (TARGET_OS_CPP_BUILTINS): Define _LONGLONG.
+ Define _ABIO32.
+ Use it for _MIPS_SIM.
+ * config/mips/iris6-o32.h (TARGET_OS_CPP_BUILTINS): Removed.
+
+ * config/mips/iris6-o32-as.h (SUBTARGET_ASM_OPTIMIZING_SPEC):
+ Moved ...
+ * config/mips/iris5.h (SUBTARGET_ASM_OPTIMIZING_SPEC): ... here,
+ updating comment.
+ Fixes PR target/10190.
+
+2003-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/rs6000/sysv4.h (LIB_LINUX_SPEC): Make -pthread apply
+ to shared libraries.
+
+2003-09-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11646
+ * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the
+ EDGE_ABNORMAL flag for EH edges.
+ * toplev.c (rest_of_handle_cse): Delete unreachable blocks
+ if dead edges were purged.
+
+2003-09-16 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (TARGET_CPU_CPP_BUILTINS): Add target predefines.
+ * config/m68k/m68k-none.h (CPP_CPU_DEFAULT_SPEC): Kill all definitions.
+ * config/m68k/m68k-none.h (CPP_FPU_SPEC): Remove.
+ * config/m68k/m68k-none.h (CPP_SPEC): Likewise.
+
+2003-09-16 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * cfgcleanup.c (label_is_jump_target_p): Correct use of table
+ returned by tablejump_p.
+
+2003-09-16 Joel Brobecker <brobecker@gnat.com>
+
+ * dwarf2asm.c (dw2_asm_output_nstring): Add comment.
+
+2003-09-16 Roger Sayle <roger@eyesopen.com>
+
+ PR bootstrap/12269
+ * simplify-rtx.c (simplify_gen_relational): Allow the cmp_mode
+ argument to be VOIDmode, taking the mode of the comparison from
+ the operands. Only call simplify_relational_operation if we
+ know the mode of the comparison. Honor FLOAT_STORE_FLAG_VALUE
+ if comparison has a floating point result. Ensure that the
+ result is always of the specified mode.
+ (simplify_replace_rtx): Simplify call to simplify_gen_relational.
+ (simplify_unary_operation): Ensure the correct mode and cmp_mode
+ are always passed to simplify_gen_relational. Simplify NOT of
+ comparison operator in any mode, not just BImode.
+ (simplify_ternary_operation): Correct tests on the return value
+ of simplify_relational_operation to use const_true_rtx, not
+ const1_rtx. Abort if it ever returns a non-constant result.
+
+ * cfgloopanal.c (count_strange_loop_iterations): Use the function
+ simplify_relational_operation, not simplify_gen_relational, if
+ we're only interested in constant comparisons and will ignore
+ non-constant results.
+
+2003-09-16 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (tree_swap_operands_p): New function to determine
+ the prefered ordering of operands.
+ (fold): Numerous clean-ups. Use tree_swap_operands_p when swapping
+ operands to commutative, comparison or ternary operators. Replace
+ uses of TREE_SET_CODE with recursive call to fold. Remove duplicate
+ transformation of A ? B : C into !A ? C : B.
+
+2003-09-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/alpha/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/arm/linux-elf.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/rs6000/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/rs6000/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/sh/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/sparc/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/sparc/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+
+2003-09-16 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.c (handle_warn_unused_result_attribute): New function.
+ (c_common_attribute_table): Add warn_unused_result.
+ (c_expand_expr): Issue warning when result of inlined function
+ with warn_unused_result attribute is ignored.
+ * calls.c (expand_call): Issue warning when result of function
+ with warn_unused_result attribute is ignored.
+ * c-common.h (STMT_EXPR_WARN_UNUSED_RESULT): Define.
+ * expr.c (expr_wfl_stack): Define.
+ (expand_expr) <case EXPR_WITH_FILE_LOCATION>: If ignore,
+ pass const0_rtx as target. Chain locations into expr_wfl_stack.
+ * tree-inline.c (expand_call_inline): Set STMT_EXPR_WARN_UNUSED_RESULT
+ bit if inlined function has warn_unused_result attribute.
+ * input.h (expr_wfl_stack): Declare.
+ * doc/extend.texi: Document warn_unused_result attribute.
+
+2003-09-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * cpplib.c (do_pragma): Remove unnecessary cb_line_change.
+
+2003-09-15 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Add
+ ATTRIBUTE_UNUSED.
+ (call_insn_operand): For PIC, don't allow a direct call to a
+ function in a different section than the current one.
+
+2003-09-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/invoke.texi (Warning Options): Add missing hyphen before
+ "Wimport". Change "-Wno-endif-labels" to "-Wendif-labels".
+ Move "-Wold-style-definition" to the C-only section.
+ Fix the ordering of the warning options.
+
+2003-09-15 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * gcse.c (remove_reachable_equiv_notes): New.
+ replace_store_insn): Call it. Update antic list.
+ (store_killed_in_insn): Take REG_EQUAL notes into account.
+ (build_store_vectors, delete_store): Add parameter to
+ replace_store_insn call.
+
+2003-09-15 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (LEGITIMATE_PIC_OPERAND_P): Use
+ SYMBOL_REF_LOCAL_P.
+
+2003-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.h (DEFAULT_FUNCTION_ARG_PADDING): New.
+ (FUNCTION_ARG_PADDING): Use DEFAULT_FUNCTION_ARG_PADDING.
+ * config/ia64/ia64.c (ia64_hpux_function_arg_padding):
+ Likewise.
+ * config/m68hc11/m68hc11.c (m68hc11_function_arg_padding):
+ Likewise.
+ * config/rs6000/rs6000.c (function_arg_padding): Likewise.
+ * config/sparc/sparc.c (function_arg_padding): Likewise.
+
+2003-09-15 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (schedule_block): Use ready_remove_first instead
+ of choose_ready for non-dfa insn scheduling.
+
+2003-09-15 Andreas Jaeger <aj@suse.de>
+ Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/invoke.texi (Warning Options): Describe -Wold-style-definition.
+ * c-opts.c (c_common_handle_option): Handle OPT_Wold_style_definition.
+ * c-parse.in: Warn about old-style parameter definition.
+ * c-common.c: Define warn_old_style_defintion.
+ * c-common.h: Declare it.
+ * c.opt: Add Wold-style-defintion.
+
+2003-09-15 Andreas Jaeger <aj@suse.de>
+
+ * config/rs6000/altivec.h: Convert () prototypes to ISO C90.
+ * config/rs6000/rs6000.c: Likewise.
+
+2003-09-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/10914
+ * expr.h (get_condition, canonicalize_condition): Declaration changed.
+ * cfgloopanal.c (simple_loop_exit_p): Add parameter to a get_condition
+ and canonicalize_condition calls.
+ * gcse.c (fis_get_condition, delete_null_pointer_checks_1,
+ delete_null_pointer_checks): Ditto.
+ * ifcvt.c (noce_get_alt_condition, noce_get_condition): Ditto.
+ * predict.c (estimate_probability, expected_value_to_br_prob): Ditto.
+ * loop.c (check_dbra_loop, get_condition_for_loop): Ditto.
+ (canonicalize_condition, get_condition): Allow to return comparisons
+ of cc mode registers.
+ * loop-unswitch.c (may_unswitch_on_p, unswitch_single_loop): Allow
+ cc mode registers comparison in condition.
+
+2003-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ * coverage.c (create_coverage): Do not call pushlevel/poplevel.
+ * langhooks-def.h (lhd_do_nothing_iii_return_null_tree): New
+ function.
+ * langhooks.c (lhd_do_nothing_iii_return_null_tree): Define it.
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison): Convert
+ (ne (and (lshiftrt (xor X CST) Y) 1) 0) into
+ (eq (and (lshiftrt X Y) 1) 0).
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Follow spelling conventions.
+ * cpphash.h: Likewise.
+ * fold-const.c: Likewise.
+
+2003-09-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-ppoutput.c (cb_line_change): Revert 2003-08-04's change.
+ * c-lex.c (cb_line_change): Skip line changing whenever
+ c-ppoutput.c would.
+
+2003-09-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ra.c: Convert to ISO C90 prototypes.
+ * ra-build.c: Likewise.
+ * ra-colorize.c: Likewise.
+ * ra-debug.c: Likewise.
+ * ra-rewrite.c: Likewise.
+
+2003-09-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (%.dvi): Remove excess $(docdir).
+
+2003-09-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * function.c (STACK_BYTES): Move definition to head of file.
+ (assign_parms): Don't pass current_function_pretend_args_size
+ directly to SETUP_INCOMING_VARARGS. For partial register arguments,
+ round current_function_pretend_args_size up to STACK_BYTES. Skip any
+ excess before laying out the argument.
+
+2003-09-14 Andreas Jaeger <aj@suse.de>
+
+ * objc/objc-act.c: Convert to ISO C90 prototypes.
+ * objc/objc-act.h: Likewise.
+
+2003-09-14 Olaf Hering <olh@suse.de>
+
+ * config/rs6000/rs6000.c: Fix typo: Remove extra ')'.
+
+2003-09-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/12021
+ * config/m68k/netbsd-elf.h (TARGET_OS_CPP_BUILTINS): Remove the asserts
+ as they already are done in config/m68k/m68k.h.
+ * config/m68k/netbsd.h (TARGET_OS_CPP_BUILTINS): Likewise
+
+ * config/rs6000/rs6000.c (GEN_LOCAL_LABEL_FOR_SYMBOL): Remove.
+ (machopic_output_stub): Only generate pic base symbols when using pic
+ and generate them in the form L00000000$spb.
+
+2003-09-13 Richard Henderson <rth@redhat.com>
+
+ * cgraphunit.c (cgraph_assemble_pending_functions): Export.
+ (cgraph_finalize_function): Revert TREE_ASM_WRITTEN check.
+ * cgraph.h: Update.
+
+2003-09-12 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c: Fix typos in previous.
+
+2003-09-12 Ziemowit Laski <zlaski@apple.com>
+
+ * pretty-print.c (pp_construct): Use xcalloc instead of xmalloc
+ when allocating pp->buffer.
+
+2003-09-12 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.c (machopic_select_rtx_section): Use
+ const_data_section for things that might require relocation.
+
+2003-09-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/12264
+ * tree-inline.c (inline_forbidden_p_1): Cast the 3rd arg to tree.
+
+2003-09-12 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/elf.h (ASM_SPEC): Remove no-density option. Reformat.
+ * config/xtensa/linux.h (ASM_SPEC): Likewise.
+ * config/xtensa/xtensa.h (TARGET_SWITCHES): Remove -mbig-endian,
+ -mlittle-endian, -m[no-]density, -m[no-]abs, -m[no-]addx, -m[no-]mac16,
+ -m[no-]mul16, -m[no-]mul32, -m[no-]nsa, -m[no-]minmax, -m[no-]sext,
+ -m[no-]booleans, -mhard-float, -msoft-float, -m[no-]hard-float-div,
+ -m[no-]hard-float-recip, -m[no-]hard-float-sqrt, and
+ -m[no-]hard-float-rsqrt options. Delete corresponding MASK_* macros
+ and redefine corresponding TARGET_* macros with constants from the
+ xtensa-config.h header.
+ * doc/invoke.texi (Option Summary, Xtensa Options): Remove documention
+ for the options listed above.
+
+2003-09-12 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000-protos.h: Use C90 prototypes.
+ * config/rs6000/rs6000-c.c: Ditto.
+ * config/rs6000/rs6000.c: Ditto.
+ * config/rs6000/ sysv4.h: Ditto.
+
+2003-09-12 Chris Lattner <sabre@nondot.org>
+
+ * loop.c: Move comments describing BIV's and GIV's to top of file
+
+2003-09-12 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/8967
+ * alias.c (write_dependence_p): Modify to take an additional constp
+ argument that controls whether the UNCHANGING_RTX_P flags are used.
+ (anti_dependence, output_dependence): Adjust write_dependence_p
+ callers to pass this additional argument, to return the same result.
+ (unchanging_anti_dependence): New variant of anti_dependence that
+ ignores the UNCHANGING_RTX_P property on memory references.
+ * rtl.h (unchaning_anti_dependence): Prototype here.
+ * flow.c (init_propagate_block): Place fake constant mem writes on
+ the mem_set_list so that dead writes to const variables are deleted.
+ (insn_dead_p): Change anti_dependence to unchanging_anti_dependence.
+ (mark_used_regs): Likewise.
+
+2003-09-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mcore/mcore-protos.h (mcore_r15_operand_p): Declare.
+ (mcore_secondary_reload_class): Declare.
+ (mcore_output_inline_const_forced): Remove.
+ * config/mcore/mcore.md (movsi): Remove the code that forced
+ non-inlineable constants into a register if the target was r15
+ or the stack pointer. Remove constant restrictions from the main
+ define_insn. Remove r <- I, r <- M and r <- N alternatives in favor
+ of an r <- P alternative. Remove fallback define_insn for reload.
+ (movhi, movqi): Use gen_lowpart rather than gen_SUBREG. Remove reload
+ define_insn. Use mcore_output_move in the remaining define_insn.
+ Adjust condition and constraints in the way as for movsi.
+ (movdi): Always split unacceptable constants into two. Use
+ simplify_gen_subreg instead of operand_subword{,_force}.
+ * config/mcore/mcore.c (mcore_output_inline_const_forced): Remove.
+ (mcore_output_move): Support HImode and QImode moves as well.
+ (mcore_m15_operand_p): New function.
+ (mcore_reload_class): Use it to detect cases where LRW_REGS are better.
+ (mcore_secondary_reload_class): New function.
+ * config/mcore/mcore.h (SECONDARY_RELOAD_CLASS): Redefine in
+ terms of mcore_secondary_reload_class.
+
+2003-09-11 Mike Stump <mrs@apple.com>
+
+ * c-lex.c (fe_file_change): Don't transform to_line with SOURCE_LINE.
+
+2003-09-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_logarithm): if N can't be truncated to
+ MODE exactly, then only convert logN(N) -> 1.0 if
+ flag_unsafe_math_optimizations is set.
+
+ * builtins.c (builtin_dconsts_init, dconstpi, dconste,
+ init_builtin_dconsts): Delete.
+ * emit-rtl.c (dconstpi, dconste): Define.
+ (init_emit_once): Initialize dconstpi & dconste.
+ * real.h (dconstpi, dconste): Declare.
+
+2003-09-11 Alexandre Oliva <aoliva@redhat.com>
+
+ PR fortran/11522
+ * dwarf2out.c (gen_inlined_subroutine_die): Emit abstract function
+ for ultimate origin even if block is abstract.
+
+2003-09-11 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (combine_simplify_rtx): Move several NOT and NEG
+ optimizations from here...
+ * simplify-rtx.c (simplify_unary_operation): to here. Recursively
+ simplify expressions using simplify_gen_*ary instead of gen_rtx_*.
+
+2003-09-11 Richard Henderson <rth@redhat.com>
+
+ * cgraphunit.c (cgraph_finalize_function): Add nested arg.
+ Tweek tests for function already generated.
+ (cgraph_expand_function): Don't double announce in !unit-at-a-time.
+ * cgraph.h (cgraph_finalize_function): Update for extra arg.
+ * c-decl.c (finish_function): Likewise.
+
+2003-09-10 Joe Buck <jbuck@welsh-buck.org>
+
+ * c-decl.c (poplevel): Eliminate use of |= in function_body assignment.
+
+2003-09-10 Jerry Quinn <jlquinn@optonline.net>
+
+ * real.c: Update URL to VAX floating point docs.
+ (decode_vax_d): Extract 8 exponent bits instead of 7.
+
+2003-09-10 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * combine.c (force_to_mode): Set fuller_mask based only on mask,
+ not op_mode.
+
+2003-09-11 Jan Hubicka <jh@suse.cz>
+
+ * c-objc-common.c (c_cannot_inline_tree_fn): Warn
+ on why function is not inlinable; do not check
+ the body.
+ (inline_forbidden_p): Move to...
+ * tree-inline.c (inline_forbidden_p_1): ... here; Add warnings;
+ deal with alloca, longjmp.
+ (inline_forbidden_p): New static function.
+ (find_alloca_call_1, find_alloca_call, find_builtin_longjmp_call_1,
+ find_builtin_longjmp_call): Kill.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * cgraph.h (struct cgraph_node): Rename lowered to analyzed.
+ * cgraphunit.c: Update to match.
+ (record_call_1): Rearrange. Call lang hook for language nodes.
+ (cgraph_analyze_function): Don't call lower_function.
+ * langhooks.h (struct lang_hooks_for_callgraph): Replace
+ lower_function with analyze_expr.
+ * langhooks-def.h: Update to match.
+ * langhooks.c (lhd_callgraph_analyze_expr): New.
+
+2003-09-10 Martin Husemann <martin@duskware.de>
+
+ PR target/11965
+ * config/sparc/sparc.c (sparc_v8plus_shift): Protect against
+ constants greater than 63.
+ * config/sparc/sparc.md (ashlsi3, ashrsi3, lshrsi3): Protect
+ against constants greater than 31.
+ (*ashldi3_sp64, *ashrdi3_sp64, *lshrdi3_sp64): Protect against
+ constants greater than 63.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * cgraphunit.c (cgraph_finalize_function): Remove unused argument.
+ * cgraph.h (cgraph_finalize_function): Update.
+ * c-decl.c (finish_function): Update.
+
+2003-09-09 Devang Patel <dpatel@apple.com>
+
+ * config/darwin.h (LINK_SPEC): Pass -nofixprebinding to linker.
+ * doc/invoke.texi: Document new Darwin linker option -nofixprebinding.
+
+2003-09-09 Eric Christopher <echristo@redhat.com>
+
+ * configure.in: Change usage of 'head' to 'sed 1q'.
+ * configure: Regenerate.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * except.c: Include cgraph.h.
+ (output_function_exception_table): Invoke
+ cgraph_varpool_mark_needed_node.
+ * Makefile.in (except.o): Update.
+
+2003-09-07 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in: Define REMAKEFLAGS for LANGUAGES & BOOT_CFLAGS
+ and use it throughout.
+
+2003-09-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (real_dconstp, fold_builtin_logarithm,
+ fold_builtin_exponent): New, split out from fold_builtin. Also
+ generalize to add log2, log10, exp2 and exp10/pow10 equivalents.
+ * emit-rtl.c (dconst3, dconst10, dconstthird): New.
+ (init_emit_once): Initialize new dconsts, use ARRAY_SIZE in lieu
+ of hardcoded array size.
+ * fold-const.c (fold): Add cases for exp2, exp10 and pow10.
+ (tree_expr_nonnegative_p): Likewise.
+ * real.h (dconst3, dconst10, dconstthird): New.
+
+2003-09-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_function): Fix handling of extern
+ inline functions.
+ (cgraph_finalize_compilation_unit): Fix crash when dealing with lost
+ DECL_SAVED_TREE.
+
+2003-09-09 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_cabs): Protect the complex argument
+ against multiple evaluation when optimizing cabs* into sqrt*.
+
+2003-09-09 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (notice_global_symbol): Properly deal with weak symbols.
+
+2003-09-08 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in: Revert yesterday's change.
+
+2003-09-08 Bernardo Innocenti <bernie@develer.com>
+ Peter Barada <peter@baradas.org>
+
+ * config/m68k/coff.h (REGISTER_NAMES): Add fake register `argptr'
+ * config/m68k/hp320.h (REGISTER_NAMES): Likewise.
+ * config/m68k/linux.h (REGISTER_NAMES): Likewise.
+ * config/m68k/m68kelf.h (REGISTER_NAMES): Likewise.
+ * gcc/config/m68k/sgs.h (REGISTER_NAMES): Likewise.
+ * config/m68k/m68k-protos.h (m68k_initial_elimination_offset): Add prototype.
+ * config/m68k/m68k.c (m68k_frame): New struct, simular to ix86 back-end.
+ (m68k_compute_frame_layout): New function.
+ (m68k_initial_elimination_offset): New function.
+ (m68k_output_function_prologue): ColdFire-specific movem handling.
+ (m68k_output_function_epilogue): Likewise.
+ * config/m68k/m68k.h (FIRST_PSEUDO_REGISTER): Make room for argptr reg.
+ (ARG_POINTER_REGNUM): Add new definition.
+ (INITIAL_FRAME_POINTER_OFFSET): Remove macro.
+ (ELIMINABLE_REGS): Define new macro, like in ix86 back-end.
+ (CAN_ELIMINATE): Likewise.
+ (INITIAL_ELIMINATION_OFFSET): Likewise.
+
+2003-09-08 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Simplify
+ by removing redundant variable cfa_store_offset.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * langhooks-def.h (lhd_register_builtin_type): New function.
+ (LANG_HOOKS_REGISTER_BUILTIN_TYPE): New macro.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Update.
+ * langhooks.h (lang_hooks_for_types): Add register_builtin_type.
+ * langhooks.c (lhd_register_builtin_type): New function.
+ * c-common.h (c_register_builtin_type): Declare.
+ * c-common.c (c_register_builtin_type): New function.
+ * c-lang.c (LANG_HOOKS_REGISTER_BUILTIN_TYPE): Define to
+ c_register_builtin_type.
+ * config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Remove __fpreg,
+ __float80, and __float128 macros.
+ * config/ia64/ia64.c (ia64_init_builtins): Create __fpreg,
+ __float80, and __float128 types.
+
+2003-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def
+ (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
+ BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
+ BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT): New.
+ * builtins.def (BUILT_IN_CACOS, BUILT_IN_CACOSF, BUILT_IN_CACOSH,
+ BUILT_IN_CACOSHF, BUILT_IN_CACOSHL, BUILT_IN_CACOSL,
+ BUILT_IN_CARG, BUILT_IN_CARGF, BUILT_IN_CARGL, BUILT_IN_CASIN,
+ BUILT_IN_CASINF, BUILT_IN_CASINH, BUILT_IN_CASINHF,
+ BUILT_IN_CASINHL, BUILT_IN_CASINL, BUILT_IN_CATAN,
+ BUILT_IN_CATANF, BUILT_IN_CATANH, BUILT_IN_CATANHF,
+ BUILT_IN_CATANHL, BUILT_IN_CATANL, BUILT_IN_CCOS, BUILT_IN_CCOSF,
+ BUILT_IN_CCOSH, BUILT_IN_CCOSHF, BUILT_IN_CCOSHL, BUILT_IN_CCOSL,
+ BUILT_IN_CEXP, BUILT_IN_CEXPF, BUILT_IN_CEXPL, BUILT_IN_CPOW,
+ BUILT_IN_CPOWF, BUILT_IN_CPOWL, BUILT_IN_CPROJ, BUILT_IN_CPROJF,
+ BUILT_IN_CPROJL, BUILT_IN_CSIN, BUILT_IN_CSINF, BUILT_IN_CSINH,
+ BUILT_IN_CSINHF, BUILT_IN_CSINHL, BUILT_IN_CSINL, BUILT_IN_CSQRT,
+ BUILT_IN_CSQRTF, BUILT_IN_CSQRTL, BUILT_IN_CTAN, BUILT_IN_CTANF,
+ BUILT_IN_CTANH, BUILT_IN_CTANHF, BUILT_IN_CTANHL, BUILT_IN_CTANL):
+ New.
+ * doc/extend.texi: Document new builtins.
+
+2003-09-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_varpool_finalize_decl): Sanity check duplicated
+ finalization.
+ * cgraphunit.c (decide_is_fnction_needed): Avoid special case of nested
+ functions, check for COMDAT.
+ (cgraph_assemble_pending_functions): Break out from...
+ (cgraph_finalize_function): ... here; allow redefinig of extern inline
+ functions.
+ (record_call_1): Record function references only in non-unit-at-a-time
+ mode.
+ (cgraph_analyze_function): Reset current_function_decl.
+ (cgraph_finalize_compilation_unit): Assemble pending functions.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * mklibgcc.in (libcc.a): Depend on stmp-dirs.
+ (libgov.a): Likewise.
+ (libgcc_eh.a): Likewise.
+
+2003-09-08 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (operand_equal_p): Clarify documentation.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (c_expand_body_1): Push and pop function context here.
+ * tree-optimize.c (tree_rest_of_compilation): ... not here. Take
+ nested argument instead of computing nesting ourselves.
+
+2003-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ * toplev.c (rest_of_handle_stack_regs): Call split_all_insns before
+ regstack if optimizing but not scheduling after reload.
+
+2003-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.c (struct machine_function): New type.
+ (TARGET_HAVE_TLS, TARGET_CANNOT_FORCE_CONST_MEM): Define.
+ (sparc_override_options): Initialize init_machine_status.
+ (tls_symbolic_operand, tgd_symbolic_operand, tld_symbolic_operand,
+ tie_symbolic_operand, tle_symbolic_operand): New functions.
+ (symbolic_operand): Disallow tls_symbolic_operand.
+ (symbolic_memory_operand): Likewise.
+ (tls_call_delay, sparc_cannot_force_const_mem, legitimate_constant_p,
+ constant_address_p, legitimate_pic_operand_p, legitimate_address_p):
+ New functions.
+ (sparc_tls_symbol): New variable.
+ (sparc_tls_get_addr, sparc_tls_got, legitimize_tls_address,
+ legitimize_address): New functions.
+ (print_operand): Handle %&.
+ (sparc_init_machine_status, get_some_local_dynamic_name,
+ get_some_local_dynamic_name_1): New functions.
+ (sparc_output_dwarf_dtprel): New function.
+ * config/sparc/sparc.h (CONSTANT_ADDRESS_P): Moved into
+ constant_address_p.
+ (LEGITIMATE_PIC_OPERAND_P): Moved into legitimate_pic_operand_p.
+ (LEGITIMATE_CONSTANT_P): Moved into legitimate_constant_p.
+ (GO_IF_LEGITIMATE_ADDRESS): Moved into legitimate_address_p.
+ (LEGITIMIZE_ADDRESS): Moved into legitimize_address.
+ (PRINT_OPERAND_PUNCT_VALID_P): Add '&'.
+ (TARGET_TLS, TARGET_SUN_TLS, TARGET_GNU_TLS): Define.
+ (ASM_OUTPUT_DWARF_DTPREL): Define.
+ (PREDICATE_CODES): Add tgd_symbolic_operand, tld_symbolic_operand,
+ tie_symbolic_operand, tle_symbolic_operand.
+ * config/sparc/sparc.md (UNSPEC_TLSGD, UNSPEC_TLSLDM, UNSPEC_TLSLDO,
+ UNSPEC_TLSIE, UNSPEC_TLSLE, UNSPEC_TLSLD_BASE): New constants.
+ (tls_call_delay): New attribute.
+ (in_call_delay): Use it.
+ (movqi, movhi, movsi, movdi): Call legitimize_tls_address if needed.
+ (tgd_hi22, tgd_lo10, tgd_add32, tgd_add64, tgd_call32, tgd_call64,
+ tldm_hi22, tldm_lo10, tldm_add32, tldm_add64, tldm_call32, tldm_call64,
+ tldo_hix22, tldo_lox10, tldo_add32, tldo_add64, tie_hi22, tie_lo10,
+ tie_ld32, tie_ld64, tie_add32, tie_add64, tle_hix22_sp32,
+ tle_lox10_sp32, tle_hix22_sp64, tle_lox10_sp64): New insns.
+ (tldo_ldub_sp32, tldo_ldub1_sp32, tldo_ldub2_sp32, tldo_ldsb1_sp32,
+ tldo_ldsb2_sp32, tldo_ldub_sp64, tldo_ldub1_sp64, tldo_ldub2_sp64,
+ tldo_ldub3_sp64, tldo_ldsb1_sp64, tldo_ldsb2_sp64, tldo_ldsb3_sp64,
+ tldo_lduh_sp32, tldo_lduh1_sp32, tldo_ldsh1_sp32, tldo_lduh_sp64,
+ tldo_lduh1_sp64, tldo_lduh2_sp64, tldo_ldsh1_sp64, tldo_ldsh2_sp64,
+ tldo_lduw_sp32, tldo_lduw_sp64, tldo_lduw1_sp64, tldo_ldsw1_sp64,
+ tldo_ldx_sp64, tldo_stb_sp32, tldo_stb_sp64, tldo_sth_sp32,
+ tldo_sth_sp64, tldo_stw_sp32, tldo_stw_sp64, tldo_stx_sp64): New
+ insns.
+ * config/sparc/sparc-protos.h (legitimate_constant_p,
+ constant_address_p, legitimate_pic_operand_p, legitimate_address_p,
+ legitimize_tls_address, legitimize_address, tls_symbolic_operand,
+ tls_call_delay, sparc_output_dwarf_dtprel): New prototypes.
+ * config/sparc/linux.h (TARGET_GNU_TLS, TARGET_SUN_TLS): Define.
+ * config/sparc/linux64.h (TARGET_GNU_TLS, TARGET_SUN_TLS): Likewise.
+ * configure.in (sparc*-*-*): Add TLS check.
+ * configure: Rebuilt.
+
+2003-09-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/11689
+ * config/i386/i386.c (memory_address_length): Fix computation when
+ the base is esp or ebp.
+
+2003-09-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11852
+ * varasm.c (initializer_constant_valid_p): Correct logic for
+ CONSTRUCTORs.
+
+2003-09-07 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_operands): New function to expand an operand pair.
+ (expand_expr): Call expand_operands whenever we need to expand both
+ operands of a binary operator.
+ (do_store_flag): Likewise for operands of comparison operations.
+
+2003-09-07 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (combine_simplify_rtx): Don't convert -(A*B) into
+ (-A)*B if we care about sign-dependent rounding.
+
+2003-09-07 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ * c-pretty-print.h (pp_c_left_brace): Declare.
+ (pp_c_right_brace): Likewise.
+ * c-pretty-print.c (pp_c_left_brace): Now a function
+ (pp_c_right_brace): Likewise.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_simplify_condjump): Fix again the preivous patch.
+
+2003-09-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (warn_deprecated_use): Move to toplev.c
+
+2003-09-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * langhooks.c (lhd_print_error_function): Move from diagnostic.c.
+ * Makefile.in (langhooks.o): Depend on diagnostic.h
+
+2003-09-06 James E Wilson <wilson@tuliptree.org>
+
+ * loop.c (loop_regs_update): Delete else clause for PATTERN rtx and
+ simplify.
+
+2003-09-07 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in: Define $REMAKE to be $MAKE with LANGUAGES & BOOT_CFLAGS
+ and use it throughout.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_simplify_condjump): Fix my previous patch.
+
+ * toplev.c (rest_of_decl_compilation): Do not finalize external
+ virables.
+
+ * cgraph.c (cgraph_mark_reachable_node): Only enqueue finalized
+ functions.
+ (cgraph_varpool_finalize_decl): Notice global symbol when needed.
+
+2003-09-06 Jan Hubicka <jh@suse.cz>
+
+ PR target/12070
+ * calls.c (emit_library_call_value_1): Fix saving of BLKmode arguments.
+
+ PR opt/12082
+ * cfgcleanup.c (try_simplify_condjump): Avoid unreachable code warning.
+
+2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (announce_function): Move to toplev.c.
+
+2003-09-06 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (expr_equiv_p): Don't consider anything to be equal to
+ volatile mem.
+
+2003-09-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ggc-common.c (init_ggc_heuristics): Don't use the heuristics
+ when gc checking is enabled.
+
+2003-09-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c/9862
+ * c-decl.c (c_expand_body_1): Move return warning from here...
+ (finish_function): ...to here.
+
+2003-09-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/darwin.h (PREFERRED_RELOAD_CLASS): Always return
+ a subset of the input class.
+
+2003-09-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i860/i860.c: Follow spelling conventions.
+ * config/i860/i860.h: Likewise.
+ * config/sh/sh.h: Likewise.
+
+2003-09-05 Nitin Yewale <NitinY@KPITCummins.com>
+
+ * config/h8300/h8300-protos.h: Declare h8300_hard_regno_rename_ok
+ * config/h8300/h8300.h (HARD_REGNO_RENAME_OK): New.
+ * config/h8300/h8300.c (h8300_hard_regno_rename_ok): New.
+
+2003-09-05 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/1823
+ * expmed.c (expand_divmod <EXACT_DIV_EXPR>): Use an unsigned
+ multiplication to implement division by constant integer.
+
+2003-09-05 Jan Hubicka <jh@suse.cz>
+
+ * opts.c (decode_options): Enable unit-at-a-time at -O2.
+ * params.def (max-inline-insns-single): Set to 500
+ (max-inline-insns-auto): Set to 150
+ * invoke.texi (max-inline-insns-single, max-inline-insns-auto): Update.
+
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * cgraph.c (cgraph_mark_reachable_node): Split out from ...
+ (cgraph_mark_needed_node): Remove needed argument.
+ * cgraph.h: Update to match.
+ * cgraphunit.c (decide_is_function_needed): Split out from ...
+ (cgraph_finalize_function): Reorg. Avoid deferred_inline_function
+ if we generated the function.
+ (record_call_1): Update for cgraph_mark_reachable_node.
+ * varasm.c (mark_referenced): Likewise.
+ * objc/objc-act.c (mark_referenced_methods): Likewise.
+
+2003-09-04 DJ Delorie <dj@redhat.com>
+
+ * targhooks.c: Add comment explaining the migration process.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * config/frv/t-frv: Fix path for frv-abi.h.
+ * config/frv/frv-asm.h: Fix string concatenation.
+
+2003-09-04 DJ Delorie <dj@redhat.com>
+
+ * builtins.c (apply_args_size): Guard against a NULL cfun.
+ (expand_builtin_apply_args_1): Likewise.
+ (expand_builtin_apply): Likewise.
+ Fixes PR bootstrap/12172.
+
+2003-09-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_as_ix86_cmov_sun_syntax): Check if
+ assembler supports Sun syntax for cmov.
+ * configure: Regenerate.
+ * config.in: Likewise.
+ * config/i386/i386.c: Rename CMOV_SUN_AS_SYNTAX to
+ HAVE_AS_IX86_CMOV_SUN_SYNTAX.
+ * config/i386/sol2.h (CMOV_SUN_AS_SYNTAX): Remove.
+ Fixes PR target/12101.
+
+2003-09-04 Matt Austern <austern@apple.com>
+
+ * c-common.c (fname_as_string): Use lang_hooks.decl_printable_name
+ with verbosity 0, instead of DECL_NAME, for human-readable string.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * targhooks.c (default_return_in_memory): Allow
+ unconverted ports.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * targhooks.c (default_return_in_memory): Fix typo
+ in last checkin.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * targhooks.c (default_return_in_memory): Fix default
+ definition.
+
+2003-09-04 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_coff_asm_named_section): Restore
+ deleted function.
+ * config/m68k/coff.h (M68K_TARGET_COFF): Add flag used to
+ enable coff-only code in m68k.c.
+
+2003-09-04 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc: Add v850e1 target. Allow --with-cpu to accept
+ v850e1.
+ * config/v850/v850.h: Accept v850e1 as a default CPU.
+ Accept -mv850e1 as a command line option.
+ * doc/invoke.texi: Document new -mv850e1 command line switch.
+ * config/v850/t-v850: Treat -mv850e1 as a multilib alias for
+ -mv850e.
+
+2003-09-04 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc (v850e-*-*): Use t-v850e makefile fragment.
+ * config/v850/t-v850: Only produce one extra multilib - for
+ the v850e.
+ * config/v850/t-v850e: New file: Only produce one extra
+ multilib - for the v850.
+
+2003-09-04 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/libgcc-ia64.ver: Export _Unwind_GetBSP@@GCC_3.3.2.
+ * config/ia64/unwind-ia64.c (_Unwind_GetBSP): New function.
+ * unwind.h (_Unwind_GetBSP): New prototype.
+ * libgcc-std.ver: Add empty GCC_3.3.2 version.
+ * mkmap-symver.awk: For symbol versions with no exported symbols,
+ don't put anything into version script, just change all symbol
+ versions which inherit from it to inherit from its ancestor.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_prologue): Convert to
+ calls.struct_value_rtx hook.
+ (reg_or_const_float_1_operand): New.
+ * config/mips/mips.h: Update Comments.
+ (mips_arg): Add reg_or_const_float_1_operand.
+ * config/mips/mips.md (divdf3); Convert to expander.
+ (divsf3): Ditto.
+ (*divdf3): New pattern.
+ (*divsf3): Ditto.
+
+2003-09-04 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (wrapup_global_declarations): Fix final pass in
+ unit-at-atime mode.
+
+2003-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/extend.texi: Document removal of cast-as-lvalue extension in
+ C++.
+
+2003-09-04 Nicolas Roche <roche@act-europe.fr>
+
+ * gcc.c (process_command): Fix typo.
+
+2003-09-03 David O'Brien <obrien@FreeBSD.org>
+
+ optimization/11980
+ * config/i386/freebsd.h (SIZE_TYPE): Support TARGET_64BIT.
+ (PTRDIFF_TYPE): Likewise.
+ (WCHAR_TYPE_SIZE): Likewise.
+
+2003-09-03 DJ Delorie <dj@redhat.com>
+
+ * targhooks.c: New file.
+ * targhooks.h: New file.
+ * Makefile.in: Add targhooks.o support.
+ (function.o): Depend on$(TARGET_H).
+ (stmt.o): Likewise.
+ (combine.o): Depend on $(TREE_H) and $(TARGET_H).
+ * builtins.c (apply_args_size, expand_builtin_apply_args_1,
+ expand_builtin_apply): Convert to calls.struct_value_rtx hook.
+ (expand_builtin_saveregs): Convert to
+ calls.expand_builtin_saveregs hook.
+ * c-decl.c (start_decl): Handle new calls.promote_prototypes hook
+ here, instead of ...
+ (get_parm_info) ... here.
+ (store_parm_decls_oldstyle): Convert to calls.promote_prototypes
+ hook.
+ (finish_function): Handle calls.promote_prototypes hook here too.
+ * c-typeck.c (convert_arguments): Convert to
+ calls.promote_prototypes hook.
+ (c_convert_parm_for_inlining): Likewise.
+ * calls.c (initialize_argument_information): Convert to
+ calls.promote_function_args hook.
+ (expand_call): Convert to calls.struct_value_rtx,
+ calls.strict_argument_naming,
+ calls.pretend_outgoing_varargs_named, and
+ calls.promote_function_return hooks. Pass fndecl to
+ aggregate_value_p. Initialize CUMULATIVE_ARGS before calling
+ hooks, so they can use that.
+ (emit_library_call_value_1): Likewise.
+ * combine.c (setup_incoming_promotions): Convert to
+ calls.promote_function_args hook.
+ * emit-rtl.c: Convert to calls.struct_value_rtx hook.
+ * expr.c (expand_assignment): Pass call to aggregate_value_p.
+ (expand_expr): Likewise.
+ * expr.h: Remove support for SETUP_INCOMING_VARARGS,
+ STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED,
+ RETURN_IN_MEMORY macro defaults.
+ * final.c (profile_function): Convert to calls.struct_value_rtx
+ hook.
+ * function.c (aggregate_value_p): Accept function type tree as
+ second parameter; try to deduce fntype from it. Convert to
+ calls.return_in_memory hook.
+ (assign_parms): Convert to calls.setup_incoming_varargs,
+ calls.strict_argument_naming, calls.promote_function_args,
+ calls.pretend_outgoing_varargs_named hooks. Pass fndecl to
+ aggregate_value_p.
+ (expand_function_start): Likewise. Convert to
+ calls.struct_value_rtx hook.
+ (expand_function_end): Convert to calls.promote_function_return hook.
+ (allocate_struct_function): Pass fndecl to aggregate_value_p.
+ * hard-reg-set.h: Update comments to new hook names.
+ * integrate.c (expand_inline_function): Pass fndecl to aggregate_value_p.
+ * reg-stack.c (stack_result): Likewise.
+ * rtl.h (struct_value_rtx, struct_value_incoming_rtx): Delete.
+ * stmt.c (expand_value_return): Convert to
+ calls.promote_function_return hook.
+ * target-def.h: Add TARGET_PROMOTE_FUNCTION_ARGS,
+ TARGET_PROMOTE_FUNCTION_RETURN, TARGET_PROMOTE_PROTOTYPES,
+ TARGET_STRUCT_VALUE_RTX, TARGET_RETURN_IN_MEMORY,
+ TARGET_EXPAND_BUILTIN_SAVEREGS, TARGET_SETUP_INCOMING_VARARGS,
+ TARGET_STRICT_ARGUMENT_NAMING,
+ TARGET_PRETEND_OUTGOING_VARARGS_NAMED, and TARGET_CALLS.
+ * target.h: Likewise.
+ * tree.h (aggregate_value_p): Also takes a tree to deduce function
+ attributes from (for target hooks).
+ * doc/tm.texi (PROMOTE_FUNCTION_ARGS, PROMOTE_FUNCTION_RETURN,
+ PROMOTE_PROTOTYPES, RETURN_IN_MEMORY, STRUCT_VALUE_REGNUM,
+ STRUCT_VALUE, STRUCT_VALUE_INCOMING_REGNUM, STRUCT_VALUE_INCOMING,
+ EXPAND_BUILTIN_SAVEREGS, SETUP_INCOMING_VARARGS,
+ STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED): Convert
+ to hooks.
+
+ * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Pass function
+ to aggregate_value_p.
+ * config/arm/arm.c (arm_init_cumulative_args,
+ arm_output_mi_thunk): Likewise.
+ * config/i386/i386.c (ix86_return_pops_args, x86_this_parameter):
+ Likewise.
+ * config/mips/mips.c (mips_save_reg_p, mips_expand_prologue,
+ mips_can_use_return_insn): Likewise.
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
+ * config/s390/s390.c (s390_output_mi_thunk): Likewise.
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Pass function to
+ aggregate_value_p.
+ * config/story16/stormy16.c (xstormy16_asm_output_mi_thunk): Pass
+ function to aggregate_value_p.
+ * objc/objc-act.c (generate_struct_by_value_array): Pass NULL to
+ aggregate_value_p.
+
+ * config/sh/sh-protos.h (sh_builtin_saveregs): Remove.
+ (sh_attr_renesas_p, sh_cfun_attr_renesas_p, sh_function_arg,
+ sh_function_arg_advance, sh_pass_in_reg_p): New. * config/sh/sh.c
+ (sh_handle_renesas_attribute, sh_promote_prototypes,
+ sh_struct_value_rtx, sh_return_in_memory, sh_builtin_saveregs,
+ sh_setup_incoming_varargs, sh_strict_argument_naming,
+ sh_pretend_outgoing_varargs_named): New decls.
+ (targetm): Add new hooks.
+ (calc_live_regs): Save MACL and MACH if the function has the
+ renesas attribute.
+ (sh_expand_prologue): Support renesas attribute.
+ (sh_builtin_saveregs): Make static.
+ (sh_build_va_list): Support renesas attribute.
+ (sh_va_start): Likewise.
+ (sh_va_arg): Likewise.
+ (sh_promote_prototypes): New.
+ (sh_function_arg): New, moved from sh.h. Support renesas
+ attribute.
+ (sh_function_arg_advance): Likewise.
+ (sh_return_in_memory): Likewise.
+ (sh_strict_argument_naming): Likewise.
+ (sh_pretend_outgoing_varargs_named): Likewise.
+ (sh_struct_value_rtx): New.
+ (sh_attribute): Add renesas attribute.
+ (sh_handle_renesas_attribute): New.
+ (sh_attr_renesas_p, sh_cfun_attr_renesas_p): New.
+ (sh_ms_bitfield_layout_p): Support renesas attribute also.
+ (sh_output_mi_thunk): Pass function to aggregate_value_p. *
+ config/sh/sh.h (TARGET_SWITCHES): Add -mrenesas as an alias for
+ -mhitachi.
+ (STRUCT_VALUE_REGNUM, STRUCT_VALUE, RETURN_IN_MEMORY): Moved to
+ target hooks.
+ (sh_args): Add renesas_abi flag.
+ (INIT_CUMULATIVE_ARGS): Set it. Pass fndecl to aggregate_value_p.
+ (FUNCTION_ARG_ADVANCE, FUNCTION_ARG): Move to sh.c.
+ (PASS_IN_REG_P): Support renesas attribute. Pass DF and TF on the
+ stack for the renesas abi.
+ (STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED,
+ SETUP_INCOMING_VARARGS, EXPAND_BUILTIN_SAVEREGS,
+ PROMOTE_PROTOTYPES): Moved to sh.c. * config/sh/sh.md (call): Set
+ call cookie to indicate renesas calls.
+
+2003-09-03 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * gcse.c (replace_one_set): New function.
+ (pre_insert_copy_insn): Change the order of copying
+ to make copy propagation discover additional PRE opportunities.
+
+2003-09-03 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11700.
+ * simplify-rtx.c (simplify_subreg): Check that the subreg offset
+ of a hard register is representable before trying to simplify it
+ using subreg_hard_regno.
+
+2003-09-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_ld_hidden): Disable unless using GNU ld.
+ * configure: Regenerate.
+
+2003-09-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * intl.h (N_): Remove parentheses.
+
+2003-09-03 Bernardo Innocenti <bernie@develer.com>
+
+ * config.gcc (m68k-*-linux*): Remove definition of LINUX_DEFAULT_ELF.
+ * config/i370/linux.h (LINUX_DEFAULT_ELF): Remove unconditional
+ definition and code blocks compiled when not defined.
+ * config/i386/linux.h (LINUX_DEFAULT_ELF): Likewise.
+ * config/i386/linux64.h (LINUX_DEFAULT_ELF): Likewise.
+ * config/sparc/linux.h: (LINUX_DEFAULT_ELF): Likewise.
+ * config/sparc/linux64.h: (LINUX_DEFAULT_ELF): Likewise.
+
+2003-09-03 Jeff Sturm <jsturm@one-point.com>
+
+ * cgraphunit.c (visited_nodes): New static variable.
+ (record_call_1): Use walk_tree with visited_nodes.
+ (cgraph_create_edges): Use walk_tree with visited_nodes.
+ Setup/teardown visited_nodes hashtable.
+
+2003-09-03 Roger Sayle <roger@eyesopen.com>
+
+ * toplev.c (flag_rounding_math): New global variable.
+ (f_options): Add to the list of language independent options.
+ * flags.h (flag_rounding_math): Prototype here.
+ (HONOR_SIGN_DEPENDENT_ROUNDING): Use flag_rounding_math instead.
+ * common.opt (frounding-math): New common command line option.
+ * opts.c (common_handle_option): Handle OPT_frounding_math.
+ (set_fast_math_flags): -ffast-math clears flag_rounding_math.
+
+ * doc/invoke.texi: Document this new command line option.
+
+2003-09-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/sol2.h (NO_IMPLICIT_EXTERN_C): Update comment.
+
+2003-09-03 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (c-objc-common.o): Kill gt-c-objc-common.h dependency.
+ * c-decl.c (finish_function): Kill arguments, always use cgraph path.
+ * c-objc-common.c: Kill include of gt-c-objc-common.h
+ (expand_deferred_fns, deffer_fn): Kill function.
+ (deferred_fns): Kill variable.
+ (finish_cdtor): Update finish_function call.
+ (c_objc_common_finish_file): Always call cgraph code.
+ * c-parse.c: Regenerate.
+ * c-parse.y: Regenerate.
+ * c-tree.h (finish_function): Update prototype.
+ * objc-acct.c (build_module_descriptor, finish_method_def):
+ Update call of finish_function.
+ * cgraphunit.c (cgraph_default_inline_p, cgraph_analyze_function): Add
+ forward prototype.
+ (cgraph_finalize_function): In non-unit-at-a-time mode analyze the
+ function and assemble it if needed.
+ (cgraph_finalize_compilation_unit): Do nothing in non-unit-at-a-time
+ mode.
+ (cgraph_optimize): Likewise.
+ (cgraph_expand_function): In non-unit-at-a-time mode keep function body
+ even when it has no inline callees.
+ * c-parse.in: Update calls to finish_function.
+
+2003-09-03 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.h: Handle TARGET_CPU_iwmmxt.
+ Use #error to generate the message if TARGET_DEFAULT is not
+ recognised.
+
+2003-09-03 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MASK_UNUSED1): Remove.
+ (MASK_XGOT, TARGET_XGOT): Define.
+ (TARGET_SWITCHES): Add an entry for -mxgot.
+ (ASM_SPEC): Map -mxgot to -xgot.
+ * config/mips/mips.c (mips_symbol_insns): Use TARGET_XGOT to decide
+ whether we're using a big-GOT sequences.
+ (mips_legitimize_const_move, mips_expand_call): Likewise.
+ (override_options): Revert 2003-01-09 change.
+ * doc/invoke.texi: Document -mxgot.
+
+2003-09-02 Jason Merrill <jason@redhat.com>
+
+ * config/sol2.h (NO_IMPLICIT_EXTERN_C): Define here.
+ * config/sparc/sol2.h: Not here.
+
+2003-09-02 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr): The code following both_summands performs
+ the same task as simplify_gen_binary. Replace all gotos to
+ both_summands with a call to simplify_gen_binary and delete the
+ now unused label.
+
+2003-09-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/7327
+ * config/sparc/sol2.h (NO_IMPLICIT_EXTERN_C): Define.
+
+2003-09-02 Jeff Sturm <jsturm@one-point.com>
+
+ * cgraphunit.c (record_call_1): Use walk_tree_without_duplicates.
+ (cgraph_optimize_function): Set current_function_decl to the
+ fndecl we're integrating from.
+
+2003-09-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Break out _Complex math functions into their
+ own category.
+
+2003-09-02 Andreas Jaeger <aj@suse.de>
+
+ * langhooks-def.h (LANG_HOOKS_RTL_EXPAND_STMT): Cast properly.
+
+2003-09-02 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgbuild.c (compute_outgoing_frequencies): Use NOTE instead of
+ finding the note again.
+
+2003-09-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove host-specific rewrites of target_alias.
+
+2003-09-01 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (genprogs): Fix typo.
+
+ * Makefile.in (gencheck.o): Remove build commands.
+ (dummy-conditions.o): Likewise.
+ (read-rtl.o): Likewise.
+ (gensupport.o): Likewise.
+ (genconfig$(build_exeext)): Remove rule.
+ (genconfig.o): Remove build commands.
+ (genflags$(build_exeext)): Remove rule.
+ (genflags.o): Remove build commands.
+ (gencodes$(build_exeext)): Remove rule.
+ (gencodes.o): Remove build commands.
+ (genconstants.o): Remove build commands.
+ (genemit$(build_exeext)): Remove rule.
+ (genemit.o): Remove build commands.
+ (genrecog$(build_exeext)): Remove rule.
+ (genrecog.o): Remove build commands.
+ (genextract$(build_exeext)): Remove rule.
+ (genextract.o): Remove build commands.
+ (genpeep$(build_exeext)): Remove rule.
+ (genpeep.o): Remove build commands.
+ (genattr$(build_exeext)): Remove rule.
+ (genattr.o): Remove build commands.
+ (genprognames): New variable.
+ (genprogs): Likewise.
+ (genobjs): Likewise.
+ (genprogs): New rule.
+ (genobjs): Likewise.
+ (genattrtab.o): Remove build commands.
+ (genautomata.o): Likewise.
+ (genoutput$(build_exeext)): Remove rule.
+ (genoutput.o): Remove build commands.
+ (gengenrtl.o): Likewise.
+ (genpreds.o): Likewise.
+ (gengtype.o): Likewise.
+ (genconditions.o): Likewise.
+ (gen-protos.o): Likewise.
+ (scan.o): Likewise.
+ (fix-header.o): Likewise.
+ (scan-decls.o): Likewise.
+ (check-g++): Combine with other check targets.
+ (check-gcc): Likewise.
+ (check-g77): Likewise.
+ (check-objc): Likewise.
+
+2003-09-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove host-specific stuff which is unused here
+ since the introduction of config.host.
+
+ * doc/fragments.texi: Mention config.host.
+ * doc/sourcebuild.texi: Mention config.host. Give brief descriptions
+ of config.build, config.host, and config.gcc.
+
+2003-09-01 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (pushdecl): Don't put variables on
+ C_TYPE_INCOMPLETE_VARS of a type unless that type is itself
+ incomplete.
+
+2003-09-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.host: New file.
+ * config.gcc: Remove some host-specific stuff and some
+ logic needed only for repeated invocation.
+ * configure.in: Use config.host.
+ * configure: Regenerate.
+
+2003-09-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * c-typeck.c (build_binary_op): Kill BIT_ANDTC_EXPR.
+ * convert.c (convert_to_integer): Kill BIT_ANDTC_EXPR.
+ * fold-const.c (int_const_binop): Kill BIT_ANDTC_EXPR.
+ (fold): Kill BIT_ANDTC_EXPR and label bit_and.
+ * tree.def (BIT_ANDTC_EXPR): Kill.
+
+2003-08-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove uses of "for x in .. ${foo}" idiom.
+ * configure: Regenerate.
+
+ * config.gcc: Remove references to install_headers_dir, now unused
+ since introduction of config.build.
+ * config.gcc (i860-*-sysv4*): Don't set unused USG, SVR3 defines.
+
+ * doc/fragments.texi, doc/sourcebuild.texi: Mention new file
+ config.build.
+
+ * config.build: New file.
+ * config.gcc: Remove some build-specific stuff.
+ * configure.in: Use config.build.
+ * configure: Regnerate.
+
+2003-08-31 Steven Bosscher <steven@gcc.gnu.org>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11823
+ * stmt.c (expand_end_case_type): Only use jump tables for dense
+ switch statements when optimizing for size.
+
+2003-08-31 Olivier Hainque <hainque@act-europe.fr>
+
+ * builtins.c (expand_builtin_setjmp): Use emit_jump to jump around
+ the != 0 case, which ensures pending stack adjustments are flushed.
+
+2003-08-30 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.frag: Delete file.
+ * configure.in: Rename the substitution variables
+ dep_host_xmake_file and dep_tmake_file to xmake_file and
+ tmake_file respectively. Do not expand $srcdir in the
+ value of these; leave that for Make. Introduce a new
+ substitution varaible, all_lang_makefrags, which lists
+ subdirectory Make-lang.in files; exclude these from
+ all_lang_makefiles, which is now only for subdirectory
+ outputs. Do not invoke configure.frag. Do not set nor
+ AC_SUBST_FILE target_overrides, host_overrides, or
+ language_fragments. Create build subdirectories in
+ config.status extra commands.
+ * configure: Regenerate.
+ * Makefile.in: Update substitutions to match changes to
+ configure. Use include directives instead of @-insertions
+ to read in host, target, and language fragments.
+ (Makefile rule): Do not invoke configure.frag. Do not copy
+ config.status to config.run before executing it. Set
+ CONFIG_HEADERS and CONFIG_FILES so that only Makefile gets
+ regenerated.
+ (cstamp-h rule): Set CONFIG_FILES as well as CONFIG_HEADERS.
+
+2003-08-30 Zack Weinberg <zack@codesourcery.com>
+
+ * c-tree.h: Delete COMPARE_DIFFERENT_TU from enumeration.
+ * c-typeck.c (same_translation_unit_p): New function.
+ (comptypes): Use it instead of flags parameter to identify
+ structure types from different translation units.
+ * c-decl.c (duplicate_decls): Always call comptypes with
+ COMPTYPE_STRICT flags argument.
+ (c_reset_state): Set BLOCK_SUPERCONTEXT of the block formed
+ to file_scope_decl.
+
+2003-08-30 Zack Weinberg <zack@codesourcery.com>
+
+ * c-tree.h (C_TYPE_INCOMPLETE_VARS): New macro.
+ * c-decl.c (struct c_scope): Remove "incomplete" field.
+ (pushdecl): Attach variables with incomplete types to
+ the TYPE_MAIN_VARIANT of the incomplete type in question.
+ (finish_struct): Look at C_TYPE_INCOMPLETE_VARS for variables
+ to complete, not at current_scope->incomplete. All such
+ variables do need completion.
+
+2003-08-30 Richard Earnshaw <rearnsha@arm.com>
+ Nicolas Pitre <nico@cam.org>
+
+ * arm/lib1funcs.asm (RETCOND): Delete.
+ (RETLDM): New assembler macro. Use it for returning with ldm/ldr.
+ (ARM_LDIV0, THUMB_LDIV0): Collapse multiple definitions.
+ (__ARM_ARCH__): Move here from ieee754-?f.S.
+ (RET, RETc): Clean up definitions.
+ (DIV_FUNC_END): Renamed from FUNC_END. All uses changed.
+ (FUNC_END): New macro that marks the end of any function.
+ (ARM_FUNC_START): New macro that allows an assembler routine to be
+ implemented in ARM code even if a Thumb-only build.
+ Unconditionally include ieee754-?f.S.
+ * arm/ieee754-df.S: Delete macros moved to lib1funcs.asm.
+ Mark ends of functions.
+ Split into separate conditionally-compiled units.
+ Use RETLDM to return from routines.
+ * arm/ieee754-sf.S: Similarly.
+ * t-arm-elf (LIB1ASMFUNCS): Remove _ieee754_dp and _ieee754_sp.
+ Add _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2
+ _fixsfsi and _fixunssfsi.
+
+ * arm/ieee754-df.S (__muldf3): Fix bug when result of a
+ multiplication underflows to zero.
+ (__adddf3): Fix bug when using VFP ordering on little-endian
+ processors.
+ (__fixdfsi): Use rrx to extract the carry into a register instead of
+ MRS instruction. Optimize later use of result.
+ * arm/ieee754-sf.S (__fixsfsi): Likewise.
+ (__fixunssfsi): Use a better sequence for handling negative-or-zero.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * tree-optimize.c: New file.
+ * Makefile.in (OBJS-archive): Add tree-optimize.o.
+ (tree-optimize.o): New.
+ * c-decl.c (store_parm_decls): Use allocate_struct_function.
+ (finish_function): Don't free_after_parsing or free_after_compilation.
+ (set_save_expr_context): Move to tree-optimize.c.
+ (c_expand_body_1): Use tree_rest_of_compilation.
+ * c-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * objc/objc-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * c-objc-common.c (expand_deferred_fns): Don't emit unused inlines;
+ iterate until closure.
+ * langhooks-def.h (LANG_HOOKS_RTL_EXPAND_START,
+ LANG_HOOKS_RTL_EXPAND_STMT, LANG_HOOKS_RTL_EXPAND_END): New.
+ (LANG_HOOKS_RTL_EXPAND_INITIALIZER): New.
+ * langhooks.h (struct lang_hooks_for_rtl_expansion): New.
+ * toplev.h (tree_rest_of_compilation): Declare it.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Add rtl_inline_init, saved_for_inline.
+ * integrate.c (save_for_inline): Set saved_for_inline.
+ * c-semantics.c (genrtl_scope_stmt): Check it.
+ * toplev.c (wrapup_global_declarations): Check it.
+ (rest_of_handle_inlining): Set and check rtl_inline_init.
+ (rest_of_compilation): Remove out of date comment.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * function.c (allocate_struct_function): New, split out of ...
+ (prepare_function_start, init_function_start): ... here.
+ * expr.c (init_expr): Use ggc_alloc_cleared.
+ * stmt.c (init_stmt_for_function): Likewise.
+ * tree.h (allocate_struct_function): Declare.
+
+2003-08-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Don't use negated character class in shell case
+ clause.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Move function_frequency and
+ max_jumptable_ents before start of bit field members.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin_constant_p): Check cse_not_expected here,
+ (fold_builtin_constant_p) ... not here.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * c-tree.h (C_DECL_FILE_SCOPE): Move ...
+ * tree.h (DECL_FILE_SCOPE_P): ... here, and rename.
+ * c-decl.c, c-objc-common.c, c-typeck.c: Update to match.
+
+2003-08-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Fix typos.
+ (ATTR_MATHFN_FPROUNDING_STORE): New macro.
+ (BUILT_IN_FREXP, BUILT_IN_FREXPF, BUILT_IN_FREXPL, BUILT_IN_MODF,
+ BUILT_IN_MODFF, BUILT_IN_MODFL, BUILT_IN_REMQUO, BUILT_IN_REMQUOF,
+ BUILT_IN_REMQUOL, BUILT_IN_SINCOS, BUILT_IN_SINCOSF,
+ BUILT_IN_SINCOSL): Use ATTR_MATHFN_FPROUNDING_STORE.
+
+ * builtins.def (BUILT_IN_ERFC, BUILT_IN_ERFCF, BUILT_IN_ERFCL):
+ Use ATTR_MATHFN_FPROUNDING_ERRNO.
+
+2003-08-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (i386-*-vsta): Fix obvious bogosity.
+
+ * fixinc/inclhack.def: Remove special cases for unsupported
+ PTX 1 and PTX 2 (including i[34567]86-sequent-sysv3).
+ * fixinc/fixincl.x: Regenerate.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (cpp.info): Just state dependencies.
+ (gcc.info): Likewise.
+ (gccint.info): Likewise.
+ (gccinstall.info): Likewise.
+ (cppinternals.info): Likewise.
+ (cpp.dvi): Likewise.
+ (gcc.dvi): Likewise.
+ (gccint.dvi): Likewise.
+ (gccinstall.dvi): Likewise.
+ (cppinternals.dvi): Likewise.
+ (gcov.1): Likewise.
+ (cpp.1): Likewise.
+ (gcc.1): Likewise.
+ (gfdl.7): Likewise.
+ (gpl.7): Likewise.
+ (fsf-funding.7): Likewise.
+ ($(objdir)/%.info): New pattern rule.
+ (%.dvi): Likewise.
+
+2003-08-29 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in (restage1): Pass BOOT_CFLAGS to recursive make.
+ (restage2): Likewise.
+ (restage3): Likewise.
+ (restage4): Likewise.
+ (restageprofile): Likewise.
+ (restagefeedback): Likewise.
+ (bubblestrap): Likewise.
+
+2003-08-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Narrow unsupported target match to avoid clobbering
+ i?86-sequent-sysv4*.
+
+2003-08-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (mathfn_built_in): Handle new math builtins.
+
+2003-08-28 Per Bothner <per@bothner.com>
+
+ Fix (hopefully temporary) for breakage caused by my 08-21 patch.
+ * cpplex.c (_cpp_get_fresh_line): Check for null buffer.
+ (_cpp_lex_buffer): Likewise.
+ * cpptrad.c (_cpp_read_logical_line_trad): Likewise.
+
+2003-08-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*mulsi3_sign"): New insn.
+ ("mulsidi3" expander, "mulsi_6432" insn): Remove, replace by ...
+ ("mulsidi3"): ... this new insn.
+ ("umulsidi3"): New insn.
+ ("divmoddi3", "divmodtidi3", "divmodtisi3"): Simplify by using
+ mixed-mode matching constraints.
+ ("udivmodsi4", "udivmoddisi3"): New insns.
+ ("udivsi3", "umodsi3"): Use only in ESA/390 mode.
+
+2003-08-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_INT_PTR, BT_FLOAT_PTR, BT_DOUBLE_PTR,
+ BT_LONGDOUBLE_PTR, BT_FN_FLOAT_FLOAT_FLOATPTR,
+ BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR,
+ BT_FN_FLOAT_FLOAT_INTPTR, BT_FN_DOUBLE_DOUBLE_INTPTR,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR,
+ BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR,
+ BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR,
+ BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR,
+ BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR): New.
+ * builtins.def (BUILT_IN_FREXP, BUILT_IN_FREXPF, BUILT_IN_FREXPL,
+ BUILT_IN_MODF, BUILT_IN_MODFF, BUILT_IN_MODFL, BUILT_IN_REMQUO,
+ BUILT_IN_REMQUOF, BUILT_IN_REMQUOL, BUILT_IN_SINCOS,
+ BUILT_IN_SINCOSF, BUILT_IN_SINCOSL): New.
+ * tree.c: Assign new type_nodes.
+ * tree.h (tree_index): Add TI_FLOAT_PTR_TYPE, TI_DOUBLE_PTR_TYPE,
+ TI_LONG_DOUBLE_PTR_TYPE, TI_INTEGER_PTR_TYPE.
+ (float_ptr_type_node, double_ptr_type_node,
+ long_double_ptr_type_node, integer_ptr_type_node): New type_nodes.
+
+ * doc/extend.texi: Document new builtins.
+
+2003-08-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_FN_FLOAT_INT_FLOAT,
+ BT_FN_DOUBLE_INT_DOUBLE, BT_FN_LONGDOUBLE_INT_LONGDOUBLE): New.
+
+ * builtins.def (BUILT_IN_ERF, BUILT_IN_ERFC, BUILT_IN_ERFCF,
+ BUILT_IN_ERFCL, BUILT_IN_ERFF, BUILT_IN_ERFL, BUILT_IN_GAMMA,
+ BUILT_IN_GAMMAF, BUILT_IN_GAMMAL, BUILT_IN_J0, BUILT_IN_J0F,
+ BUILT_IN_J0L, BUILT_IN_J1, BUILT_IN_J1F, BUILT_IN_J1L,
+ BUILT_IN_JN, BUILT_IN_JNF, BUILT_IN_JNL, BUILT_IN_LGAMMA,
+ BUILT_IN_LGAMMAF, BUILT_IN_LGAMMAL, BUILT_IN_SIGNIFICAND,
+ BUILT_IN_SIGNIFICANDF, BUILT_IN_SIGNIFICANDL, BUILT_IN_TGAMMA,
+ BUILT_IN_TGAMMAF, BUILT_IN_TGAMMAL, BUILT_IN_Y0, BUILT_IN_Y0F,
+ BUILT_IN_Y0L, BUILT_IN_Y1, BUILT_IN_Y1F, BUILT_IN_Y1L,
+ BUILT_IN_YN, BUILT_IN_YNF, BUILT_IN_YNL): New.
+
+ * doc/extend.texi: Document new builtins.
+
+2003-08-28 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Remove special case code for unsupported
+ variants of i?86, powerpcle, and thumb.
+ * fixinc/mkfixinc.sh: Remove special case code for unsupported
+ arm and hppa variants.
+
+2003-08-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_FN_INT_FLOAT, BT_FN_INT_DOUBLE,
+ BT_FN_INT_LONGDOUBLE, BT_FN_LONG_FLOAT, BT_FN_LONG_DOUBLE,
+ BT_FN_LONG_LONGDOUBLE, BT_FN_LONGLONG_FLOAT,
+ BT_FN_LONGLONG_DOUBLE, BT_FN_LONGLONG_LONGDOUBLE,
+ BT_FN_FLOAT_FLOAT_LONGDOUBLE, BT_FN_DOUBLE_DOUBLE_LONGDOUBLE,
+ BT_FN_FLOAT_FLOAT_INT, BT_FN_DOUBLE_DOUBLE_INT,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_INT, BT_FN_FLOAT_FLOAT_LONG,
+ BT_FN_DOUBLE_DOUBLE_LONG, BT_FN_LONGDOUBLE_LONGDOUBLE_LONG,
+ BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE): New.
+
+ * builtins.def (BUILT_IN_ACOS, BUILT_IN_ACOSF, BUILT_IN_ACOSH,
+ BUILT_IN_ACOSHF, BUILT_IN_ACOSHL, BUILT_IN_ACOSL, BUILT_IN_ASIN,
+ BUILT_IN_ASINF, BUILT_IN_ASINH, BUILT_IN_ASINHF, BUILT_IN_ASINHL,
+ BUILT_IN_ASINL, BUILT_IN_ATANH, BUILT_IN_ATANHF, BUILT_IN_ATANHL,
+ BUILT_IN_CBRT, BUILT_IN_CBRTF, BUILT_IN_CBRTL, BUILT_IN_COPYSIGN,
+ BUILT_IN_COPYSIGNF, BUILT_IN_COPYSIGNL, BUILT_IN_COSH,
+ BUILT_IN_COSHF, BUILT_IN_COSHL, BUILT_IN_DREM, BUILT_IN_DREMF,
+ BUILT_IN_DREML, BUILT_IN_EXP10, BUILT_IN_EXP10F, BUILT_IN_EXP10L,
+ BUILT_IN_EXP2, BUILT_IN_EXP2F, BUILT_IN_EXP2L, BUILT_IN_EXPM1,
+ BUILT_IN_EXPM1F, BUILT_IN_EXPM1L, BUILT_IN_FDIM, BUILT_IN_FDIMF,
+ BUILT_IN_FDIML, BUILT_IN_FMA, BUILT_IN_FMAF, BUILT_IN_FMAL,
+ BUILT_IN_FMAX, BUILT_IN_FMAXF, BUILT_IN_FMAXL, BUILT_IN_FMIN,
+ BUILT_IN_FMINF, BUILT_IN_FMINL, BUILT_IN_HYPOT, BUILT_IN_HYPOTF,
+ BUILT_IN_HYPOTL, BUILT_IN_ILOGB, BUILT_IN_ILOGBF, BUILT_IN_ILOGBL,
+ BUILT_IN_LDEXP, BUILT_IN_LDEXPF, BUILT_IN_LDEXPL, BUILT_IN_LLRINT,
+ BUILT_IN_LLRINTF, BUILT_IN_LLRINTL, BUILT_IN_LLROUND,
+ BUILT_IN_LLROUNDF, BUILT_IN_LLROUNDL, BUILT_IN_LOG10,
+ BUILT_IN_LOG10F, BUILT_IN_LOG10L, BUILT_IN_LOG1P, BUILT_IN_LOG1PF,
+ BUILT_IN_LOG1PL, BUILT_IN_LOG2, BUILT_IN_LOG2F, BUILT_IN_LOG2L,
+ BUILT_IN_LOGB, BUILT_IN_LOGBF, BUILT_IN_LOGBL, BUILT_IN_LRINT,
+ BUILT_IN_LRINTF, BUILT_IN_LRINTL, BUILT_IN_LROUND,
+ BUILT_IN_LROUNDF, BUILT_IN_LROUNDL, BUILT_IN_NEXTAFTER,
+ BUILT_IN_NEXTAFTERF, BUILT_IN_NEXTAFTERL, BUILT_IN_NEXTTOWARD,
+ BUILT_IN_NEXTTOWARDF, BUILT_IN_NEXTTOWARDL, BUILT_IN_POW10,
+ BUILT_IN_POW10F, BUILT_IN_POW10L, BUILT_IN_REMAINDER,
+ BUILT_IN_REMAINDERF, BUILT_IN_REMAINDERL, BUILT_IN_RINT,
+ BUILT_IN_RINTF, BUILT_IN_RINTL, BUILT_IN_SCALB, BUILT_IN_SCALBF,
+ BUILT_IN_SCALBL, BUILT_IN_SCALBLN, BUILT_IN_SCALBLNF,
+ BUILT_IN_SCALBLNL, BUILT_IN_SCALBN, BUILT_IN_SCALBNF,
+ BUILT_IN_SCALBNL, BUILT_IN_SINH, BUILT_IN_SINHF, BUILT_IN_SINHL,
+ BUILT_IN_TANH, BUILT_IN_TANHF, BUILT_IN_TANHL): New.
+
+ * doc/extend.texi: Document new builtins.
+
+2003-08-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (legitmate_constant_p): Use LARL on
+ zSeries machines even in 31-bit addressing mode.
+ (legitimate_reload_constant_p): Likewise.
+ (legitimize_pic_address): Likewise.
+ (legitimize_tls_address): Likewise.
+ (s390_split_branches): Likewise.
+ (s390_dump_pool): Likewise.
+ (s390_mainpool_finish): Likewise.
+ (s390_chunkify_start): Likewise.
+ (s390_select_rtx_section): Likewise.
+ * config/s390/s390.md ("doloop_si"): Likewise.
+ ("pool_start_31", "pool_end_31"): Likewise.
+ ("pool_start_64", "pool_end_64"): Likewise.
+ ("main_base_31_small", "main_base_31_large"): Likewise.
+ ("main_base_64"): Likewise.
+ ("reload_base_31", "reload_base_64"): Likewise.
+ ("*movsi_larl"): New insn.
+ ("cjump", "icjump"): Use long branches on zSeries machines.
+ ("jump"): Likewise.
+ ("call"): Use BRASL on zSeries machines.
+ ("call_value", "call_value_tls"): Likewise.
+ ("brasl", "bras", "basr_64", "basr_31", "bas_64", "bas_31"): Remove
+ and replace by ...
+ ("*bras", "*brasl", "*basr") ... these new insns.
+ ("brasl_r", "bras_r", "basr_64_r", "basr_31_r", "bas_64_r",
+ "bas_31_r"): Remove and replace by ...
+ ("*bras_r", "*brasl_r", "*basr_r") ... these new insns.
+ ("brasl_tls", "bras_tls", "basr_64_tls", "basr_31_tls",
+ "bas_64_tls", "bas_31_tls"): Remove and replace by ...
+ ("*bras_tls", "*brasl_tls", "*basr_tls") ... these new insns.
+ ("*return_si", "*return_di"): Remove and replace by ...
+ ("*return"): ... this new insn.
+ ("rotlsi3"): Allow on zSeries machines.
+
+ * config/s390/s390.c (legitimize_reload_constant_p): Use
+ LL/LH type instructions in z/Architecture mode.
+ * config/s390/s390.md ("*movsi_lli"): Likewise.
+ ("*andsi3_ni", "*andhi3_ni", "*andqi3_ni"): Likewise.
+ ("*iorsi3_ni", "*iorhi3_ni", "*iorqi3_ni"): Likewise.
+ ("*extendqisi2"): Use LB in z/Architecture mode.
+ ("*zero_extendqisi2_64", "*zero_extendqisi2_31"): Use LLGC in
+ z/Architecture mode.
+ ("zero_extendqihi2", "*zero_extendqihi2_64", "*zero_extendqihi2_31"):
+ Likewise.
+
+ * config/s390/s390.md ("*tmdi_ext"): Allow in both 64-bit
+ and 31-bit mode.
+ ("ptr_extend"): Allow only in 64-bit mode.
+
+2003-08-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * gcc.c (STANDARD_EXEC_PREFIX, STANDARD_STARTFILE_PREFIX)
+ (TOOLDIR_BASE_PREFIX, STANDARD_BINDIR_PREFIX): Remove unnecessary
+ definitions.
+ (main): Only use standard_startfile_prefix if native.
+ * doc/tm.texi (STANDARD_STARTFILE_PREFIX): Update.
+
+2003-08-27 Per Bothner <pbothner@apple.com>
+
+ * cpperror.c (print_location): Don't check for !pfile->buffer. That
+ test fails following my 08-21 change, and it seems unnecessary anyway.
+ (cpp_error): Likewise.
+
+2003-08-27 Jason Merrill <jason@redhat.com>
+
+ * real.c (do_multiply): Initialize with memset.
+
+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 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (struct machine_function): Remove member
+ literal_pool_label.
+ (s390_optimize_prolog): Replace TEMP_REG argument with
+ TEMP_USED and BASE_USED. Do not check get_pool_size ().
+ (general_s_operand): Accept all immediates before reload if
+ ALLOW_IMMEDIATE. If not ALLOW_IMMEDIATE, reject literal pool
+ references.
+ (s390_output_symbolic_const): Remove UNSPEC_LTREL_OFFSET handling.
+ (find_constant_pool_ref): Ignore UNSPECV_POOL_ENTRY insns.
+ (s390_alloc_pool): New function.
+ (s390_new_pool): Call it.
+ (s390_dump_pool): Add REMOTE_LABEL argument.
+ (s390_chunkify_start): Add BASE_REG argument. Do not check
+ get_pool_size ().
+ (s390_chunkify_finish): Add BASE_REG argument. Adapt
+ s390_dump_pool call.
+ (s390_pool_count, s390_nr_constants): Remove.
+ (s390_output_constant_pool): Remove.
+ (s390_mainpool_start): New function.
+ (s390_mainpool_finish): New function.
+ (s390_mainpool_cancel): New function.
+ (s390_reorg): Implement main literal pool handling.
+ (s390_emit_prologue): Emit main_pool placeholder instead of
+ literal_pool_31 / literal_pool_64 insns.
+ * config/s390/s390.h (s390_pool_count, s390_nr_constants): Remove.
+ (ASM_OUTPUT_POOL_PROLOGUE, ASM_OUTPUT_SPECIAL_POOL_ENTRY): Remove.
+ * config/s390/s390.md (UNSPEC_MAIN_BASE): New symbolic constant.
+ ("main_base_31_small", "main_base_31_large"): New insns.
+ ("main_base_64", "main_pool"): New insns.
+ ("literal_pool_31", "literal_pool_64"): Remove.
+
+2003-08-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (ptx_netswap): New disabled fix, ported from
+ fixinc.ptx.
+ * fixinc/inclhack.def (undefine_null): Don't generate \r characters.
+ Prettify a little.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-08-27 Richard Earnshaw <rearnsha@arm.com>
+
+ * lib1funcs.asm (L_ieee754_sp): New. Include ieee754-sf.S.
+ (L_ieee754_dp): New. Include ieee754-df.S.
+ * arm/ieee754-sf.S: Rework to allow interworking, calling from Thumb,
+ and compilation in apcs-26 mode.
+ * arm/ieee754-df.S: Likewise.
+ * t-arm-elf (DPBIT, FPBIT, fp-bit.c dp-bit.c): Delete rules
+ (LIB1ASMFUNCS): Add _ieee754_sp and _ieee754_dp targets.
+
+2003-08-27 Nicolas Pitre <nico@cam.org>
+
+ * arm/ieee754-sf.S: New.
+ * arm/ieee754-df.S: New.
+
+2003-08-27 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_expect_jump): Save pending_stack_adjust
+ and restore it if returning NULL.
+
+2003-08-27 Richard Sandiford <rsandifo@redhat.com>
+
+ * calls.c (initialize_argument_information): If an argument has no
+ stack space associated with it, and BLOCK_REG_PADDING is defined,
+ use it to decide at which end the argument should be padded.
+ * function.c (assign_parms): Allocate BLKmode stack slots.
+ * config/mips/mips-protos.h (mips_pad_arg_upward): Declare.
+ (mips_pad_reg_upward): Declare.
+ * config/mips/mips.h (PAD_VARARGS_DOWN): Use FUNCTION_ARG_PADDING.
+ (CUMULATIVE_ARGS): Remove num_adjusts and adjusts.
+ (FUNCTION_ARG_PADDING): Use mips_pad_arg_upward.
+ (BLOCK_REG_PADDING): Use mips_pad_reg_upward.
+ * config/mips/mips.c (struct mips_arg_info): Remove struct_p.
+ (mips_expand_call): Remove code for generating structure shifts.
+ (mips_arg_info): Don't set struct_p. Don't set fpr_p for non-float
+ types unless using the EABI.
+ (function_arg_advance): Don't generate shift instructions.
+ (function_arg): Don't return them. Don't short-circuit the
+ check for double structure chunks for DFmode arguments.
+ (mips_pad_arg_upward, mips_pad_reg_upward): New functions.
+ (mips_expand_prologue): Remove code to emit structure shifts.
+ * config/mips/irix6-libc-compat.c: Remove workarounds for buggy
+ structure passing (inet_ntoa, inet_lnaof, inet_netof). Update
+ comments to say that only structure returns are a problem.
+
+2003-08-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/tests/base/string.h, fixinc/tests/base/sys/regset.h:
+ Fix to match produced versions.
+ * fixinc/inclhack.def (longlong_t): New disabled test, ported
+ from fixinc.svr4.
+ * fixinc/inclhack.def (ptx_pwd_h): New disabled fix, ported
+ from fixinc.ptx.
+ * fixinc/inclhack.def (ptx_sys_mc_param_h): New disabled fix,
+ ported from fixinc.ptx.
+
+2003-08-26 Per Bothner <pbothner@apple.com>
+
+ * cpplib.h (struct cpp_token): Change type of field line to fileline.
+ (cpp_error_with_line): Use fileline for appropriate parameter.
+ * cpphash.h (struct cpp_macro): Change type of field line to fileline.
+ (struct cpp_reader): Likewise for fields line and directive_line.
+ (_cpp_begin_message): Use fileline for appropriate parameter.
+ * cpperror.c (print_location, _cpp_begin_message, cpp_error_with_line,
+ cpp_error): Use fileline for appropriate parameters and variables.
+ (print_location): New local lin, since it is not a fileline.
+
+2003-08-26 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/12002
+ * tree.h (SCALAR_FLOAT_TYPE_P, COMPLEX_FLOAT_TYPE_P): New macros.
+ (FLOAT_TYPE_P): Define in terms of these two new macros.
+ * fold-const.c (fold <PLUS_EXPR>): Don't convert x+x into x*2.0
+ for complex floating point types.
+
+2003-08-26 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (emit_prologue): Don't check literal pool size.
+ * config/s390/s390.h (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Call
+ s390_output_pool_entry.
+
+2003-08-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (svr4_preproc_lint_on,
+ svr4_preproc_lint_off, svr4_preproc_machine): New disabled
+ fixes, ported from fixinc.svr4.
+
+2003-08-26 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/install.texi (Prerequisites): Mention GNU make requirement.
+
+ * Makefile.in (AR_FOR_TARGET): Export it.
+ (AR_CREATE_FOR_TARGET): Likewise.
+ (AR_FLAGS_FOR_TARGET): Likewise.
+ (AR_EXTRACT_FOR_TARGET): Likewise.
+ (AWK): Likewise.
+ (BUILD_PREFIX): Likewise.
+ (BUILD_PREFIX_1): Likewise.
+ (DESTDIR): Likewise.
+ (GCC_FOR_TARGET): Likewise.
+ (INCLUDES): Likewise.
+ (INSTALL_DATA): Likewise.
+ (LIB1ASMSRC): Likewise.
+ (LIBGCC2_CFLAGS): Likewise.
+ (MACHMODE_H): Likewise.
+ (NM_FOR_TARGET): Likewise.
+ (RANLIB_FOR_TARGET): Likewise.
+ (libsubdir): Likewise.
+ (slibdir): Likewise.
+ (ORDINARY_FLAGS_TO_PASS): Remove stuff that we're
+ exporting.
+ (libgcc.a): Don't pass them here.
+ (stmp-multilib): Or here.
+ (install-libgcc): Or here.
+ (install-multilib): Or here.
+ (POSTSTAGE1_FLAGS_TO_PASS): Or here.
+ (stage1_build): Or here.
+
+2003-08-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*llgt_sisi", "*llgt_sisi_split", "*llgt_didi",
+ "*llgt_didi_split", "*llgt_sidi", "*llgt_sidi_split"): New insns.
+
+2003-08-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*fmadddf", "*fmsubdf",
+ "*fmaddsf", "*fmsubsf"): New insns.
+
+2003-08-26 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <MULT_EXPR>): Optimize (C1/X)*C2 into
+ (C1*C2)/X when unsafe math optimizations are allowed.
+ (fold <RDIV_EXPR>): Optimize C1/(X*C2) into (C1/C2)/X with unsafe
+ math optimizations. Minor code clean-ups. Recursively call
+ fold when constructing sub-expressions.
+
+2003-08-26 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_bitop): New function to perform constant
+ folding of ffs, clz, ctz, popcount and parity builtin functions
+ and their long and long long variants (such as ffsl and ffsll).
+ (fold_builtin): fold_builtin_bitop when appropriate.
+ * simplify-rtx.c (simplify_unary_operation): Honor both
+ CLZ_DEFINED_VALUE_AT_ZERO and CTZ_DEFINED_VALUE_AT_ZERO when
+ evaluating clz and ctz at compile-time, for operands wider
+ than HOST_WIDE_INT.
+
+2003-08-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (build_function_call_expr): Don't set
+ TREE_SIDE_EFFECTS here.
+ * expr.c (emit_block_move_via_libcall): Likewise.
+ (clear_storage_via_libcall): Likewise.
+ * tree.c (build): Set TREE_SIDE_EFFECTS for non-const, non-pure
+ CALL_EXPRs.
+
+ * gcse.c (is_too_expensive): New function.
+ (gcse_main, delete_null_pointer_checks, bypass_jumps): Use it.
+
+2003-08-25 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (hppa*-*-hpux11*, ia64*-*-hpux*): Remove
+ commented-out logic to use DCE threads (if present), add
+ support for POSIX threads.
+ * config/ia64/hpux.h: Define CPP_SPEC to set appropriate
+ #defines for -pthread. Add -lpthread to LIB_SPEC when
+ -pthread. In both cases take -mt as a synonym for -pthread
+ for acc compatibility.
+ Define GTHREAD_USE_WEAK to 0.
+ * config/pa/pa-hpux11.h: Likewise for CPP_SPEC and LIB_SPEC.
+ Remove old logic for DCE threads from LIB_SPEC.
+ * config/pa/pa64-hpux.h: Define GTHREAD_USE_WEAK to 0.
+
+2003-08-25 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_mathfn): Rearrange so that we only
+ return 0 for invalid argument types. Instead drop through to a
+ call of expand_call at the bottom of function. If op is SQRT,
+ try attaching a SQRT rtx as the REQ_EQUAL note of the libcall.
+
+2003-08-25 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_expand_tls_address): Properly truncate
+ result when op0 is SImode.
+
+2003-08-25 Nathanael Nerode <neroden@twcny.rr.com>
+
+ * fixinc/inclhack.def (svr4_sighandler_type): New fix, ported
+ from fixinc.svr4.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/sys/signal.h: Regenerate.
+
+2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (simplify_comparison): Re-enable widening of comparisons
+ with non-paradoxical subregs of non-REG expressions.
+
+2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (distribute_notes): Handle REG_ALWAYS_RETURN.
+
+2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (combine_simplify_rtx): Fix RTL sharing bug.
+
+2003-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_maybe_newline_and_indent): New macro.
+ * c-pretty-print.h (c_pretty_printer): Now typedef to the
+ structure. Be consistent with pretty-print.h abd cxx-pretty-print.h
+ (struct c_pretty_print_info): Document. Add new fields.
+ (pp_type_specifier_seq): Rename from pp_c_type_specifier.
+ (pp_direct_abstract_declarator): New macro.
+ (pp_ptr_operator): Likewise.
+ (pp_simple_type_specifier): Likewise.
+ (pp_expression): Likewise.
+ (pp_parameter_list): Rename from pp_parameter_declaration.
+ * c-pretty-print.c (pp_c_whitespace): Now a function.
+ (pp_c_left_paren): Likewise.
+ (pp_c_right_paren): Likewise.
+ (pp_c_dot): Likewise.
+ (pp_c_ampersand): Likewise.
+ (pp_c_arrow): Likewise.
+ (pp_c_semicolon): Likewise.
+ (pp_c_type_cast): New function.
+ (pp_c_space_for_pointer_operator): Likewise.
+ (pp_c_call_argument_list): Likewise.
+ (pp_c_cv_qualifier): Adjust prototype.
+ (pp_c_type_qualifier_list): Likewise.
+ (pp_c_pointer): Likewise. Handle REFERENCE_TYPE here.
+ (pp_c_type_specifier): Rename from pp_c_simple_type_specifier.
+ Adjust to follow standard grammar.
+ (pp_c_specifier_qualifier_list): Adjusr prototype. Handle
+ REFERENCE_TYPE. Tidy.
+ (pp_c_parameter_type_list): Adjust prototype. Tidy.
+ (pp_c_parameter_declaration): Remove.
+ (pp_c_abstract_declarator): Adjust prototype.
+ (pp_c_direct_abstract_declarator): Likewise.
+ (pp_c_type_id): Likewise.
+ (pp_c_storage_class_specifier): Likewise.
+ (pp_c_function_specifier): Likewise.
+ (pp_c_declaration_specifiers): Likewise.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_declaration): Likewise.
+ (pp_c_attributes): Likewise. Tidy.
+ (pp_c_function_definition): Adjust prototype.
+ (pp_c_char): Likewise.
+ (pp_c_string_literal): Likewise.
+ (pp_c_integer_constant): Likewise.
+ (pp_c_character_constant): Likewise.
+ (pp_c_bool_constant): Likewise.
+ (pp_c_enumeration_constant): Likewise.
+ (pp_c_floating_constant): Likewise.
+ (pp_c_constant): Likewise.
+ (pp_c_identifier): Likewise.
+ (pp_c_primary_expression): Likewise. Remove TARGET_EXPR case. Tidy.
+ (pp_c_initializer): Adjust prototype.
+ (pp_c_init_declarator): Likewise.
+ (pp_c_initializer_list): Likewise.
+ (pp_c_id_expression): Likewise.
+ (pp_c_postfix_expression): Likewise.
+ (pp_c_expression_list): Likewise.
+ (pp_c_unary_expression): Likewise.
+ (pp_c_cast_expression): Likewise.
+ (pp_c_multiplicative_expression): Likewise.
+ (pp_c_additive_expression): Likewise.
+ (pp_c_shift_expression): Likewise.
+ (pp_c_relational_expression): Likewise.
+ (pp_c_equality_expression): Likewise.
+ (pp_c_and_expression): Likewise.
+ (pp_c_exclusive_or_expression): Likewise.
+ (pp_c_inclusive_or_expression): Likewise.
+ (pp_c_logical_and_expression): Likewise.
+ (pp_c_logical_or_expression): Likewise.
+ (pp_c_conditional_expression): Likewise.
+ (pp_c_assignment_expression): Likewise.
+ (pp_c_expression): Likewise. Tidy.
+ (pp_c_statement): Likewise. Document.
+ (pp_c_pretty_printer_init): Adjust prototype. Tidy.
+
+ * c-lang.c (c_initialize_diagnostics): Update.
+ * c-common.h (strip_pointer_operator): Declare.
+ * c-common.c (strip_pointer_operator): Define.
+
+2003-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8795
+ * tree.h (build_method_type_directly): Declare.
+ * c-common.c (handle_vector_size_attributes): Handle METHOD_TYPEs.
+ (vector_size_helper): Likewise.
+ * tree.c (build_method_type_directly): New function.
+ (build_method_type): Use it.
+
+2003-08-24 Richard Henderson <rth@redhat.com>
+
+ * config/i386.i386.c (ix86_return_in_memory): Reformat. Return true
+ for 16-byte vector modes if sse not enabled; warn for abi change.
+ (ix86_value_regno): Only return xmm0 for 16-byte vector types.
+
+2003-08-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * rtlanal.c (may_trap_p): Simplify an integer comparison.
+
+2003-08-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (AAB_svr4_replace_byteorder): Enhance
+ comment. Enable for DYNIX/ptx systems (when they switch to
+ regular fixincludes).
+ * fixinc/fixincl.x: Regenerate.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/t-i860: New.
+ * config.gcc (i860-*-sysv4*): Add t-i860 to tmake_file.
+
+2003-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ * c-decl.c (pushdecl): Only put decls which finish_struct will do
+ something about onto incomplete chain.
+ (finish_struct): If not removing type from incomplete
+ list, update prev.
+
+2003-08-20 Jan Hubicka <jh@suse.cz>
+
+ PR target/11369
+ * i386.c (ix86_expand_carry_flag_compare): Validate operand.
+
+ PR target/11031
+ * i386.c (const_0_to_3_operand, const_0_to_7_operand,
+ const_0_to_15_operand, const_0_to_255_operand): New predicates.
+ * i386.h (PREDICATE_CODES): Add these.
+ * i386.c (pinsrw and pextrw patterns): Use them.
+
+ PR target/10984
+ * i386.c (ix86_expand_binop_builtin): Behave sanely for VOIDmodes.
+
+ PR target/8869
+ * expr.c (convert_modes): Deal properly with integer to vector
+ constant conversion.
+
+ PR target/8871
+ * i386.md (zero_extendsidi2*): Add MMX and SSE alternatives.
+
+2003-08-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (LOAD_EXTEND_OP): Remove.
+ * config/s390/s390.md ("movhi"): New expander; old insn renamed to ...
+ ("*movhi"): ... this.
+ ("movqi", "*movqi"): Likewise.
+ ("movqi_64"): Remove.
+ ("*zero_extendhisi2_31"): Change predicate to s_operand.
+
+2003-08-23 Dale Johannesen <dalej@apple.com>
+ * calls.c (emit_library_call_value_1): Fix obvious errors in
+ arguments to emit_group_store.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * calls.c (emit_library_call_value_1): Remove code related
+ to LIBGCC_NEEDS_DOUBLE.
+ * config/stormy16/stormy16.h: Remove mention of LIBGCC_NEEDS_DOUBLE.
+ * doc/tm.texi: Likewise.
+ * system.h: Poison the LIBGCC_NEEDS_DOUBLE macro.
+
+2003-08-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
+
+2003-08-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_setup_incoming_varargs): Handle o32 and o64
+ as well. Put memory references in the varargs alias set.
+ (mips_expand_prologue): Remove varargs handling from here.
+
+2003-08-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_expand_movstr, s390_expand_clrstr,
+ s390_expand_cmpmem, s390_output_constant_pool, s390_build_va_list,
+ s390_function_profiler, s390_output_mi_thunk): Use ISO C syntax
+ for function pointer calls.
+ * config/s390/s390.md ("*negdi2_31"): Likewise.
+
+2003-08-23 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (apply_distributive_law): Correct comment.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.h: Remove comment mentioning LIBGCC_NEEDS_DOUBLE.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.c (i860_build_va_list): Create the va_decl
+ declaration. Document the va_list structure.
+ (i860_va_start): Initialize the va_list structure.
+ (i860_va_arg): Rewrite completely.
+ * config/i860/i860.h (LIBGCC_NEEDS_DOUBLE): Don't define.
+ * config/i860/varargs.asm: Do not allocate or initialize
+ a va_list. Return the address of the register save area.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/iq2000/iq2000.c: Fix comment typos.
+ * config/iq2000/iq2000.md: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/iq2000/iq2000.c: Follow spelling conventions.
+ * config/iq2000/iq2000.h: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.c (output_move_double): Don't set latehalf
+ to zero for CONST_INT (since it could be, e.g., -1).
+
+ * config/i860/i860.h (REMSI3_LIBCALL): Replace this macro...
+ (MODSI3_LIBCALL): ...with this one.
+ (UREMSI3_LIBCALL): Replace this macro...
+ (UMODSI3_LIBCALL): ...with this one.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860-protos.h (output_delay_insn): Remove prototype.
+ (output_delayed_branch): Remove prototype.
+ (single_insn_src_p): Remove prototype.
+ * config/i860/i860.c (single_insn_src_p): Remove function.
+ (output_delayed_branch): Remove function.
+ (output_delay_insn): Remove function.
+ (va_start): Remove unconditional test and dead code, re-format.
+ Fix coding style and spelling problems in various comments.
+ * config/i860/i860.md (UNSPECV_BLOCKAGE): Define constant...
+ (blockage pattern): ...and use it here.
+ (all define_peephole patterns related to delayed branches): Remove.
+ Fix coding style and spelling problems in various comments.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.c: Replace all occurrences of 'GNU CC' with 'GCC'.
+ Remove all uses of the PARAMS macro. Remove superflous prototypes.
+ Convert all function definitions from traditional to ISO C90 syntax.
+ * config/i860/i860-protos.h: Replace all occurrences of 'GNU CC'
+ with 'GCC'. Remove all uses of the PARAMS macro.
+ * config/i860/i860.h: Replace all occurrences of 'GNU CC' with 'GCC'.
+ * config/i860/i860.md: Likewise.
+ * config/i860/sysv4.h: Likewise.
+ * config/i860/varargs.asm: Likewise.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860-protos.h (i860_va_start): Remove 'stdarg_p'
+ argument.
+ (tdesc_section): Add prototype.
+ Update copyright dates.
+ * config/i860/i860.c: Include coretypes.h, tm.h, and toplev.h.
+ (TARGET_ASM_FUNCTION_PROLOGUE): Move definition to end of file.
+ (TARGET_ASM_FUNCTION_EPILOGUE): Likewise.
+ (targetm): Likewise.
+ (i860_output_function_prologue): Substitute HOST_WIDE_INT_PRINT_DEC
+ for '%d' where necessary.
+ (i860_va_start): Remove 'stdarg_p' argument. Make conditional checks
+ on 'stdarg_p' unconditional. Divide current_function_args_info.ints
+ by UNITS_PER_WORD when referencing (likewise for .floats).
+ (I860_SVR4_VARARGS): Rename...
+ (I860_SVR4_VA_LIST): ...to this.
+ Call build() with 't' rather than 'field'.
+ (i860_rtx_costs): New function.
+ (TARGET_RTX_COSTS): Define.
+ (i860_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Define.
+ (i860_file_start): New function.
+ Update copyright dates.
+ * config/i860/i860.h (CPP_PREDEFINES): Remove.
+ (TARGET_CPU_CPP_BUILTINS): Define.
+ (EXPAND_BUILTIN_VA_START): Remove 'stdarg' argument.
+ (CONST_COSTS): Remove (and move code to i860_rtx_costs).
+ (ASM_FILE_START): Remove.
+ (ASM_FILE_START_1): Remove.
+ (ASM_GLOBALIZE_LABEL): Remove.
+ (ASM_OUTPUT_INTERNAL_LABEL): Remove.
+ (ASM_OUTPUT_CASE_LABEL): Replace call of ASM_OUTPUT_INTERNAL_LABEL
+ with targetm.asm_out.internal_label.
+ Update copyright dates.
+ * config/i860/sysv4.h (USER_LABEL_PREFIX): Define.
+ (CPP_PREDEFINES): Remove.
+ (TARGET_OS_CPP_BUILTINS): Define.
+ (GLOBAL_ASM_OP): Define.
+ (ASM_FILE_START): Remove.
+ (TARGET_ASM_FILE_START_FILE_DIRECTIVE): Define.
+ (TARGET_ASM_FILE_START): Define.
+ Update copyright dates.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * gcc/config.gcc (i860-*-sysv4*): Add target.
+ * config/i860/i860-protos.h: New.
+ * config/i860/i860.c: New.
+ * config/i860/i860.h: New.
+ * config/i860/i860.md: New.
+ * config/i860/sysv4.h: New.
+ * config/i860/varargs.asm: New.
+ * config/i860/x-sysv4: New.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/pa/pa.c: Replace 'GNU CC' with 'GCC'.
+ Remove all uses of PARAMS macro.
+ Convert all function definitions to ISO C90 syntax.
+ * config/pa/elf.h: Replace 'GNU CC' with 'GCC'.
+ * config/pa/fptr.c: Likewise.
+ * config/pa/lib2funcs.asm: Likewise.
+ * config/pa/long_double.h: Likewise.
+ * config/pa/milli64.S: Likewise.
+ * config/pa/pa-64.h: Likewise.
+ * config/pa/pa-hpux.h: Likewise.
+ * config/pa/pa-hpux10.h: Likewise.
+ * config/pa/pa-hpux11.h: Likewise.
+ * config/pa/pa-linux.h: Likewise.
+ * config/pa/pa-modes.def: Likewise.
+ * config/pa/pa-osf.h: Likewise.
+ * config/pa/pa-pro-end.h: Likewise.
+ * config/pa/pa.md: Likewise.
+ * config/pa/pa32-linux.h: Likewise.
+ * config/pa/pa64-linux.h: Likewise.
+ * config/pa/pa64-hpux.h: Likewise.
+ * config/pa/pa64-regs.h: Likewise.
+ * config/pa/quadlib.c: Likewise.
+ * config/pa/rtems.h: Likewise.
+ * config/pa/pa-protos.h: Replace 'GNU CC' with 'GCC' and remove
+ all uses of the PARAMS macro.
+ * config/pa/pa.h: Likewise.
+ * config/pa/som.h: Likewise.
+
+ * config/iq2000/iq2000.c: Replace 'GNU CC' with 'GCC'.
+ Remove all uses of PARAMS macro.
+ Convert all function definitions to ISO C90 syntax.
+ * config/iq2000-protos.h: Replace 'GNU CC' with 'GCC'.
+ Remove all uses of PARAMS macro.
+ * config/iq2000.h: Remove all uses of PARAMS macro.
+ * config/iq2000/iq2000.md: Replace 'GNU CC' with 'GCC'.
+
+2003-08-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_output_pool_entry): Declare.
+ * config/s390/s390.c (gen_consttable): Remove.
+ (s390_dump_pool): Use UNSPECV_POOL_ENTRY for pool entry insns.
+ (s390_output_pool_entry): New function.
+ * config/s390/s390.md (UNSPECV_POOL_QI, UNSPECV_POOL_HI,
+ UNSPECV_POOL_SI, UNSPECV_POOL_DI, UNSPECV_POOL_TI,
+ UNSPECV_POOL_SF, UNSPECV_POOL_DF): Remove, replace by ...
+ (UNSPECV_POOL_ENTRY): ... this new constant.
+ ("consttable_qi", "consttable_hi", "consttable_si", "consttable_di",
+ "consttable_ti", "consttable_sf", "consttable_df"): Remove ...
+ ("*pool_entry"): ... and replace by this new insn.
+ ("literal_pool_31"): Do not emit anchor label if pool empty.
+
+ * config/s390/s390.c (struct machine_function): Add save_return_addr_p.
+ (s390_optimize_prolog): Save RETURN_REGNUM if save_return_addr_p.
+ (s390_fixup_clobbered_return_reg): Remove.
+ (s390_reorg): Don't call s390_fixup_clobbered_return_reg.
+ (s390_return_addr_rtx): Always retrieve return address from save area
+ slot. Use save_return_addr_p to force slot to be filled.
+ (s390_emit_prologue): Remove has_hard_reg_initial_val test.
+
+2003-08-22 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (MASK_FIX_SB1, TARGET_FIX_SB1): New defines.
+ (TARGET_SWITCHES): Add -mfix-sb1 and -mno-fix-sb1.
+ * config/mips/mips.md (divdf3, divsf3, sqrtdf2, sqrtsf2): Work
+ around SB-1 errata if TARGET_FIX_SB1 is set.
+ (recip.d insn, recip.s insn, rsqrt.d insn, rsqrt.s insn): Likewise.
+ * doc/invoke.texi: Document MIPS -mfix-sb1 and -mno-fix-sb1.
+
+2003-08-22 Roger Sayle <roger@eyesopen.com>
+
+ * hashtable.c (ht_expand): Avoid calculating rehash for the common
+ case that the first probe hits an empty hash table slot.
+
+2003-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/hpux.h (SUPPORTS_INIT_PRIORITY): Define to 0.
+
+2003-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/ia64.md (*ptr_extend_plus_1): Rename to ...
+ (ptr_extend_plus_imm): ... this.
+ * config/ia64/ia64.c (addp4_optimize_ok): Do not disable addp4
+ optimization in C++.
+ (ia64_output_mi_thunk): Support ILP32 mode.
+
+2003-08-22 Bernardo Innocenti <bernie@develer.com>
+
+ * gcc/config/m68k/m68k.c (m68k_coff_asm_named_section): remove unused
+ function.
+ * gcc/config/m68k/m68k.c (-m68k_svr3_asm_out_constructor): likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.c (const_int_1_operand): Simplify an
+ integer comparison.
+
+2003-08-22 Alan Modra <amodra@bigpond.net.au>
+
+ * config/fp-bit.c: Specify config/ dir for include of fp-bit.h.
+ * config/rs6000/ppc64-fp.c: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cfgcleanup.c: Fix comment typos.
+ * emit-rtl.c: Likewise.
+ * optabs.c: Likewise.
+ * ra-build.c: Likewise.
+ * rtlanal.c: Likewise.
+ * tree.h: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c: Fix comment formatting.
+ * cfgrtl.c: Likewise.
+ * combine.c: Likewise.
+ * convert.c: Likewise.
+ * dominance.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * expmed.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcov.c: Likewise.
+ * genattrtab.c: Likewise.
+ * ggc-common.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * regmove.c: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtin-attrs.def: Fix comment formatting.
+ * c-pretty-print.c: Likewise.
+ * diagnostic.h: Likewise.
+ * langhooks.h: Likewise.
+ * recog.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * tree.def: Likewise.
+
+2003-08-22 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k-protos.h: Convert to ISO C90.
+ * config/m68k/m68k.c: Likewise.
+
+2003-08-21 Bernardo Innocenti <bernie@develer.com>
+ Paul Dale <pauli@snapgear.com>
+ Peter Barada <peter@baradas.org>
+
+ * config/m68k/m68k.c (m68k_rtx_costs): Adjust mul/div costs for
+ ColdFire cores.
+
+2003-08-21 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (INCLUDES): Remove -I$(srcdir)/config.
+ * config.gcc (*-*-openbsd): Don't set tm_file.
+ (alpha*-*-openbsd, arm*-*-coff*, arm*-wince-pe*,
+ arm-*-pe*, avr-*-*, h8300-*-rtems*, h8300-*-elf*,
+ h8300-*-*, hppa*-*-osf*, hppa*-*-bsd*, hppa*-*-hpux*,
+ i370-*-opened*, i370-*-mvs*, i370-*-linux*, i?86-*-openbsd*,
+ i?86-*-lynxos, i?86-*-nto-qnx*, iq2000*-*-elf*, m68000-hp-hpux*,
+ m68k-hp-hpux*, m68k-*-aout*, m68k-*-coff*, m68020-*-elf*,
+ m68k-*-elf*, m68k*-*-netbsd*, m68k*-*-openbsd*, m68k-*-sysv4*,
+ m68k-*-linux*, m68k-*-rtems*, mcore-*-pe*, mips*-*-netbsd*,
+ mips*-*-openbsd*, rs6000-*-lynxos*, sh*-*-elf*, sh*-*-ka,
+ sh-*-rtemself, sparc-*-openbsd*, strongarm-*-pe, vax-*-openbsd*,
+ xscale-*-coff): Use explicit and complete lists of target headers
+ to include. Move definitions to tm_defines where appropriate.
+ (hppa*-*-openbsd*, powerpc-*-openbsd*): Comment out stanza for
+ not-yet-contributed configuration.
+
+ * config/lynx.h, config/alpha/openbsd.h, config/arm/coff.h
+ * config/avr/avr.h, config/frv/frv.h, config/h8300/elf.h
+ * config/i370/linux.h, config/i370/mvs.h, config/i370/oe.h
+ * config/i386/nto.h, config/iq2000/iq2000.h,
+ * config/m68k/coff.h, config/m68k/hp310.h, config/m68k/hp320.h
+ * config/m68k/linux.h, config/m68k/m68k-aout.h
+ * config/m68k/m68k-none.h, config/m68k/m68kv4.h
+ * config/m68k/netbsd.h, config/m68k/openbsd.h
+ * config/m68k/sgs.h, config/mcore/mcore-pe.h,
+ * config/mips/netbsd.h, config/mips/openbsd.h, config/pa/pa.h,
+ * config/rs6000/lynx.h, config/sh/embed-elf.h, config/sparc/openbsd.h:
+ Remove includes of other target config headers, and
+ definitions of macros moved to tm_defines lists. Add #undefs
+ where now necessary to prevent redefinition warnings.
+
+ * config/h8300/coff.h: New file split out of...
+ * config/h8300/elf.h: ...here.
+ * config/m68k/hp320base.h: New file split out of...
+ * config/m68k/hp320.h: ...here.
+ * config/rs6000/lynxbase.h: New file split out of...
+ * config/rs6000/lynx.h: ...here.
+
+ * config/m68k/hp310g.h, config/m68k/hp320g.h, config/m68k/hpux7.h
+ * config/m68k/m68k-coff.h, config/mips/openbsd-be.h: Delete file.
+
+ * config/sol2.h: Remove #if 0-ed #include of sys/mman.h.
+ * config/m68k/m68kelf.h: Remove commented out #include of m68k/sgs.h.
+ * config/mcore/mcore.h: Don't include hwint.h nor machmode.h.
+ Remove unnecessary #ifndef.
+ * config/s390/s390.h: Prefix #include of s390/fixdfdi.h
+ [under IN_LIBGCC2] with config/.
+
+2003-08-21 Per Bothner <pbothner@apple.com>
+
+ * cppfiles.c (stack_file): Correctly pass return_at_eof parameter
+ to cpp_push_buffer.
+ * cpplex.c (_cpp_get_fresh_line): Don't buffer->prev - handled
+ by return_at_eof check. Always call _cpp_pop_buffer at end.
+
+2003-08-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/11805
+ * config/h8300/h8300.md (two anonymous patterns): Remove.
+
+2003-08-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MUST_PASS_IN_STACK): Remove BLKmode clause.
+ * config/mips/mips.c (function_arg_pass_by_reference): Never return
+ true for n32 & n64.
+
+2003-08-21 Josef Zlomek <zlomekj@suse.cz>
+
+ * fold-const.c (fold): Fix bug in (A & C) == D where D & ~C != 0
+ and similarly in (A | C) == D where C & ~D != 0.
+
+2003-08-20 Geoffrey Keating <geoffk@apple.com>
+
+ PR 8180
+ * configure.in: When testing with_libs and with_headers, treat
+ 'no' as unset. Based on a patch by Dan Kegel <dank@kegel.com>.
+ * configure: Regenerate.
+
+2003-08-20 Peter Barada <peter@baradas.org>
+
+ * longlong.h (umul_ppmm): Add ColdFire support.
+
+2003-08-20 Peter Barada <peter@baradas.org>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k-none.h: Introduce new ColdFire archs.
+ * config/m68k/m68k.h: Likewise.
+ * config/m68k/lb1sf68.asm: Rename __mcf5200__ to __mcoldfire__.
+ * config/m68k/coff.h: Rename TARGET_5200 to TARGET_COLDFIRE.
+ * config/m68k/linux.h: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/m68k/m68k.md: Likewise.
+ * config/m68k/m68kelf.h: Likewise.
+ * config/m68k/netbsd-elf.h: Likewise.
+ * config/m68k/t-m68kelf: Add multilib targets for new ColdFire archs.
+
+2003-08-20 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c: Strip away code depending on NO_ADDSUB_Q definition.
+ * config/m68k/m68k.md: Likewise.
+
+2003-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR java/11996
+ Revert this change:
+ 2003-08-19 Mark Mitchell <mark@codesourcery.com>
+ * c-common.c (c_common_signed_or_unsigned_type): Correctly handle
+ types with precisions other than those given by native machine
+ modes.
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.md (anonymous define_insn): remove obsolete code
+ selected by FSGLMUL_USE_S and FSGLDIV_USE_S
+ * config/m68k/m68k.c (output_move_himode): remove SGS_NO_LI check
+ * config/m68k/m68k.md (anonymous define_insn): Likewise
+ * config/m68k/m68k.md (anonymous define_insn): remove ISI_OV check
+ * config/m68k/m68k.c (standard_68881_constant_p): remove obsolete
+ code selected by NO_ASM_FMOVECR
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (output_move_const_into_data_reg,
+ output_move_himode): unify MOTOROLA/MIT handling of moveq
+ * config/m68k/m68k.md (movsi_const0, anonymous define_insn):
+ Likewise
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): use %U in
+ label name
+ * config/m68k/m68k.c (m68k_output_function_epilogue): replace
+ HOST_WIDE_INT_PRINT_DEC with %wd
+
+2003-08-20 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/freebsd.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Handle
+ redefine warning.
+
+2003-08-20 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11984
+ * fold-const.c (fold <PLUS_EXPR>): Check for integer constant
+ operands before calling tree_int_cst_lt when performing associative
+ transformations.
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * tree.h (IS_EXPR_CODE_CLASS): Also include 'r' and 's'.
+ (EXPR_CHECK): Don't check for 'r' or 's' if we're
+ checking IS_EXPR_CODE_CLASS.
+ * calls.c (calls_function_1): Likewise.
+ * fold-const.c (fold): Likewise.
+ * tree.c (iterative_hash_expr): Likewise.
+ * tree-inline.c (walk_tree, copy_tree_r): Likewise.
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_mi_thunk): delete obsolete code
+ depending on MOTOROLA_BSR
+ * config/m68k/m68k.md (anonymous define_insn): Likewise
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * builtins.c (expand_builtin_mathfn): Use get_callee_fndecl.
+ (expand_builtin_mathfn2, expand_builtin, builtin_mathfn_code,
+ fold_trunc_transparent_mathfn, fold_builtin): Likewise.
+ * dojump.c (do_jump): Likewise.
+ * fold-const.c (operand_equal_p, fold): Likewise.
+ (tree_expr_nonnegative_p): Likewise.
+
+ * stor-layout.c (do_type_align): Only copy DECL_USER_ALIGN from
+ TYPE_USER_ALIGN for FIELD_DECLs.
+
+ * attribs.c (decl_attributes): Rebuild the function pointer type after
+ changing the target type.
+ * tree.c (get_qualified_type): Also check that the attributes match.
+
+2003-08-19 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in (STAGESTUFF): Move cc1obj$(exeext) from here ...
+ * objc/config-lang.in (stagestuff): ... to here.
+
+2003-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11946
+ * convert.c (convert_to_integer): Use CONVERT_EXPR (instead of
+ NOP_EXPR) when necessary.
+ * c-common.c (c_common_signed_or_unsigned_type): Correctly handle
+ types with precisions other than those given by native machine
+ modes.
+
+2003-08-19 Geoffrey Keating <geoffk@apple.com>
+
+ * cpppch.c (cpp_valid_state): Re-add warning about PCH not used
+ because some macro is defined.
+
+ * config/darwin.h (LINK_COMMAND_SPEC): Add -arch and -arch_only
+ options.
+ * config/i386/darwin.h (ASM_SPEC): New.
+ (SUBTARGET_EXTRA_SPECS): New.
+ * config/rs6000/darwin.h (ASM_SPEC): New.
+ (SUBTARGET_EXTRA_SPECS): New.
+ * configure.in: Don't set CROSS or SYSTEM_HEADER_DIR when building
+ a cross-compiler between two different processors on Darwin.
+ * configure: Regenerate.
+
+2003-08-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c: Fix comment typos.
+ * c-common.c: Likewise.
+ * c-decl.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * cfgbuild.c: Likewise.
+ * cfglayout.c: Likewise.
+ * cfgloopanal.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cppfiles.c: Likewise.
+ * dwarfout.c: Likewise.
+ * expr.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcse.c: Likewise.
+ * ggc-page.c: Likewise.
+ * haifa-sched.c: Likewise.
+ * pretty-print.c: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+ * value-prof.c: Likewise.
+
+2003-08-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c: Follow spelling conventions.
+ * cppfiles.c: Likewise.
+
+2003-08-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.c: Fix comment formatting.
+ * c-common.h: Likewise.
+ * c-decl.c: Likewise.
+ * cppinit.c: Likewise.
+ * cpplib.h: Likewise.
+ * emit-rtl.c: Likewise.
+ * input.h: Likewise.
+ * line-map.h: Likewise.
+ * opts.c: Likewise.
+ * opts.h: Likewise.
+ * simplify-rtx.c: Likewise.
+
+2003-08-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * unwind-c.c: Add libgcc-style exception.
+ * unwind-dw2.c: Likewise.
+ * unwind-pe.h: Likewise.
+ * unwind-sjlj.c: Likewise.
+ * unwind.inc: Likewise.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/5582 PR c++/10538
+ * langhooks-def.h (lhd_decl_uninit): Declare.
+ (LANG_HOOKS_DECL_UNINIT): New macro.
+ (LANG_HOOKS_INITIALIZER): Adjust.
+ * langhooks.h (struct lang_hooks): Add new field
+ decl_uninit.
+ * langhooks.c (lhd_decl_uninit): Define.
+ * c-common.c (c_decl_uninit_1): New function.
+ (c_decl_uninit): New function.
+ (warn_init_self): Define.
+ * c-common.h (c_decl_uninit): Declare.
+ (warn_init_self): Declare.
+ * c.opt: Introduce -Winit-self.
+ * c-opts.c (c_common_handle_options): Set warn_init_self.
+ * c-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+ * objc/objc-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+ * function.c (uninitialized_vars_warning): Call the language hook.
+ * doc/invoke.texi: Document -Winit-self.
+
+2003-08-19 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md: Adjust SI-mode "trap_if" instruction
+ to use better predicates and constraints. Define new
+ instruction to handle "trap_if" with DI-mode arguments.
+ (conditional_trap): FAIL if trap code is not 0.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Change the
+ strstr with $pb to a strcompare with "<pic base>"
+ (ix86_output_addr_diff_elt): Output the real pic base.
+
+2003-08-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * langhooks-def.h (LANG_HOOKS_INITIALIZE_DIAGNOSTICS): Fix spelling.
+ (LANG_HOOKS_INITIALIZER): Correct.
+ * c-lang.c: Likewise.
+
+2003-08-19 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_mark_needed_node): Call notice_global_symbol.
+ (cgraph_varpool_mark_needed_node): Likewise.
+ * cgraph.h (notice_global_symbol): Declare
+ * varasm.c (notice_global_symbol): Break out from ...
+ (assemble_start_function): ... here; update for variables.
+ (assemble_variable): Use notice_global_symbol.
+
+2003-08-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_va_arg): If EABI_FLOAT_VARARGS_P,
+ expect SFmode and DFmode arguments to be passed in FPRs,
+ regardless of the underlying type.
+
+2003-08-19 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/11924
+ * config/mips/mips.c (INTERNAL_SYMBOL_P): New macro.
+ (mips_classify_symbol, m16_usym8_4, m16_usym5_4): Use it.
+
+2003-08-18 Matt Kraai <kraai@alumni.cmu.edu>
+
+ PR c/11207
+ * c-typeck.c (set_init_index): Check for negative index.
+
+2003-08-18 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/crti.asm (_init, _fini): Add alternate code for new
+ call0 ABI.
+ * config/xtensa/crtn.asm (_init, _fini): Likewise.
+ * config/xtensa/lib1funcs.asm (__mulsi3, __udivsi3, __divsi3,
+ __umodsi3, __modsi3): Likewise.
+ * config/xtensa/t-xtensa (crti.o, crtn.o): Add $(GCC_CFLAGS) and
+ $(INCLUDES).
+
+2003-08-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md ("*nabssf2_gpr"): New.
+
+2003-08-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Quote C code in braces. Remove use of
+ fake const0_rtx operands. Remove double backslashes. Use \;.
+ Remove workarounds for bogus warnings.
+
+2003-08-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (muldf3, mulsf3): Don't call a gen_* function.
+ (muldf3_internal, muldf3_r4300): Select based on TARGET_4300_MUL_FIX
+ rather than TARGET_MIPS4300.
+ (mulsf3_internal, mulsf3_r4300): Likewise.
+
+2003-08-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Renumber unspecs. Clean up comments.
+
+2003-08-17 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (associative_constant_p): New function to test
+ whether an RTX expression is an immediate constant.
+ (simplify_associative_operation): New function to perform some
+ reassociation optimizations of associative binary expressions.
+ (simplify_binary_operation): Use simplify_associative_operation
+ to simplify PLUS, MULT, AND, IOR, XOR, SMIN, SMAX, UMIN and UMAX.
+ Floating point expressions are only reassociated when unsafe
+ math optimizations are permitted.
+
+2003-08-17 Andreas Jaeger <aj@suse.de>
+
+ * config/alpha/alpha.md: Remove usage of PARAMS.
+
+ * config/i386/cygwin.h: Convert K&R prototypes to ISO C90.
+ * config/i386/i386-interix.h: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/cygming.h: Likewise.
+ * config/i386/cygwin2.c: Likewise.
+ * config/darwin.c: Likewise.
+ * config/darwin-c.c: Likewise.
+ * config/darwin-protos.h: Likewise.
+ * config/darwin.h: Likewise.
+ * config/s390/s390-protos.h: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/ia64/ia64.c: Likewse
+ * config/ia64/ia64-protos.h: Likewise.
+ * config/ia64/ia64-c.c: Likewise.
+
+2003-08-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/sparc/sparc.c: Convert to ISO C.
+
+ * config/sparc/sparc-protos.h: Don't use the PARAMS macro.
+ * config/sparc/sparc.c: Likewise.
+
+2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11512
+ * stmt.c (expand_expr_stmt_value): Don't warn about any void
+ typed expression.
+
+2003-08-16 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_fntype_regparm): Rename from ...
+ (ix86_function_regparm): ... this one; add fastcall and local
+ functions.
+ (ix86_function_ok_for_sibcall): Update.
+ (ix86_return_pops_args): Likewise.
+ (init_cumulative_args): Likewise.
+ (x86_can_output_mi_thunk): Likewise.
+ (function_arg): Fix formating.
+ (x86_this_parameter): Fix fastcall.
+ (x86_output_mi_thunk): Likewise.
+
+ * cgraph.c (cgraph_mark_needed_node): Do not mark functions without
+ body as reachable; mark nested functions as needed too.
+ (dump_cgraph): Do not output global.calls.
+ * cgraph.h (cgraph_global_info): Kill.
+ * cgraphunit.c (cgraph_finalize_function): Enqueue needed functions.
+ (record_call_1): Speedup.
+ (cgraph_analyze_function): Break out from ...; compute inlining
+ parameters.
+ (cgraph_finalize_compilation_unit): ... here.
+ (cgraph_mark_inline): Kill computation of calls.
+ (cgraph_decide_inlining): Do not compute most of initial values.
+
+2003-08-14 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_expr_p): MULT_EXPRs and RDIV_EXPRs are easy
+ to negate if either operand is easy to negate, if we don't care
+ about sign-dependent rounding.
+ (negate_expr): Make the logic to negate a REAL_CST explicit.
+ Attempt to negate a MULT_EXPR or RDIV_EXPR by negating an operand
+ that's easy to negate, if we don't honor sign-dependent rounding.
+ (fold <MULT_EXPR>): Optimize -A * B as A * -B if B is easy to
+ negate, and the symmetric A * -B as -A * B if A is easy to negate.
+ (fold <RDIV_EXPR>): Likewise, optimize -A/B and C/-D as A/-B and
+ -C/D if B and C are cheap to negate. Add an explicit rule to
+ optimize X/-1.0 as -X when we don't care about signaling NaNs.
+
+2003-08-14 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (tm_file): Rename tm_include_list.
+ (tm_p_file): Rename tm_p_include_list.
+ (build_xm_file): Rename build_xm_include_list.
+ (host_xm_file): Rename host_xm_include_list.
+ (xm_file): Rename xm_include_list.
+ (xm_file_list): Add to be substituted.
+ (cs-config.h, cs-bconfig.h, cs-tconfig.h, cs-tm.h, cs-tm_p.h):
+ Update to match.
+ (bt-load.o): Add missing dependency on $(TM_H).
+ * configure.in: Prefix value of EXTRA_MODES_FILE with config/.
+ For each of tm_file, tm_p_file, xm_file, host_xm_file, and
+ build_xm_file, generate both *_file_list and *_include_list
+ values from it. (xm_file_list was formerly not being generated.)
+ In *_include_list, prefix the names of all headers found in
+ $(srcdir)/config with config/. In each loop, consider only
+ the special case files that can actually appear in that list.
+ AC_SUBST all *_file_list and all *_include_list variables; do
+ not AC_SUBST the plain *_file variables.
+ * configure: Regenerate.
+
+2003-08-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfg.c (dump_edge_info): Add name of loop_exit edge flag.
+
+2003-08-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_adjust_insn_length): Delete adjustment for delay slot in
+ direct calls.
+ (attr_length_call): Include it here. Improve length estimate for
+ local calls.
+ (output_call): Use targetm.binds_local_p.
+
+2003-08-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (CASE_MATHFN): New helper macro.
+ (mathfn_built_in): Simplify and sort.
+
+ * protoize.c (substr): Delete, callers changed to `strstr'.
+
+2003-08-13 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (iq2000*-*-elf*): Don't set xm_file.
+ * config/iq2000/xm-iq2000.h: Delete file.
+
+2003-08-13 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (walk_type): Process a subobject before processing
+ the pointer that points to the subobject.
+
+2003-08-13 Per Bothner <pbothner@apple.com>
+
+ * regclass.c (init_reg_modes): Make non-static.
+ Rename to init_reg_modes_once per new naming convention.
+ (init_regs): Don't call init_reg_modes here.
+ * emit-rtl.c (init_emit_once): Call init_reg_modes_once here instead.
+ * rtl.h (init_reg_modes_once): New declaration.
+ * toplev.c (backend_init): Call init_regs after init_emit_once.
+
+2003-08-13 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (DBX_REGISTER_NUMBER): Define so to map a
+ special index for MD_FALLBACK_FRAME_STATE_FOR to itself.
+
+2003-08-13 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_get_pr_initial_val): Always wrap in unspec for TARGET_SH1.
+ * sh.md (load_ra): Change insn predicate to TARGET_SH1.
+
+2003-08-13 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.md (ctrsi, ctrdi): Reenable
+ handling of decrement-and-branch farther than 32 bits.
+
+2003-08-12 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (make_compare_target): Move test to ...
+ * aclocal.m4 (gcc_AC_PROG_CMP_IGNORE_INITIAL): here.
+ * configure: Regenerate.
+
+2003-08-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/iris6.h: Convert to C90 prototypes.
+ * config/mips/irix6-libc-compat.c: Likewise.
+ * config/mips/mips-protos.h: Likewise.
+ * config/mips/mips.c: Likewise.
+
+2003-08-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ fixinc/inclhack.def (svr4_krnl): Rename from svr4_kernel. Enable
+ for selected machines. Comment heavily.
+ fixinc/fixincl.x: Rebuild.
+ fixinc/tests/base/fs/rfs/rf_cache.h: New file.
+
+2003-08-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h: Tweak various comments.
+ * config/mips/mips.c: Likewise.
+
+2003-08-11 James E Wilson <wilson@tuliptree.org>
+
+ PR optimization/11319
+ PR target/10021
+ * alias.c (find_base_value, case REG): Return 0 not src if no base
+ found.
+
+2003-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcse.c (gmalloc): Fix last change.
+
+2003-08-11 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_binary_operation): Replace calls to
+ gen_rtx_NEG and gen_rtx_NOT with calls to simplify_gen_unary,
+ and calls to gen_rtx_PLUS, gen_rtx_MULT, gen_rtx_LSHIFTRT,
+ gen_rtx_ASHIFT and gen_rtx_AND with calls to simplify_gen_binary.
+
+2003-08-11 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr): If an ABS_EXPR has a complex type, abort.
+ * c-typeck.c (build_unary_op): COMPLEX_TYPE is not a valid
+ typecode for an ABS_EXPR.
+
+ * doc/c-tree.texi: Document ABS_EXPR.
+
+2003-08-11 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold): Optimize any associative floating point
+ operator with -funsafe-math-optimizations, not just MULT_EXPR.
+
+2003-08-11 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/lib1funcs.asm (__udivdi3): Add .type and .size
+ information in SHmedia case too.
+ (__divdi3, __umoddi3, __moddi3, __init_trampoline, __ic_invalidate):
+ Likewise.
+ (__set_fpscr): Use an access via GOT for PIC case.
+
+2003-08-11 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (intermodule): Make switch test more portable.
+ * configure: Regenerate.
+
+2003-08-11 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in (cleanstrap): Pass BOOT_CFLAGS to bootstrap.
+ (restrap): Likewise.
+
+2003-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcse.c (gmalloc): Argument is a size_t. Add ATTRIBUTE_MALLOC.
+ (grealloc): Size argument is a size_t.
+ (gcalloc): New function. Use throughout in lieu of
+ gmalloc/memset.
+
+ * config/avr/avr.c (avr_init_once): Use xcalloc in lieu of
+ xmalloc/memset.
+ * config/ia64/ia64.c (ia64_reorg): Likewise.
+ * conflict.c (conflict_graph_new): Likewise.
+ * fixinc/fixincl.c (run_compiles): Likewise.
+ * genattrtab.c (optimize_attrs): Likewise.
+ * genrecog.c (new_decision): Likewise.
+ * haifa-sched.c (schedule_block): Likewise.
+ * hashtable.c (ht_create): Likewise.
+
+2003-08-11 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib2funcs.S: Fix whitespace.
+ * config/xtensa/xtensa.md (all insns and expanders): Use brace block
+ syntax where appropriate. Remove unnecessary backslash escapes.
+ Reformat comments and fix some code formatting.
+ (extendqisi2): Rearrange conditional.
+ (*btrue, *bfalse, *ubtrue, *ubfalse, *bittrue, *bitfalse, *masktrue,
+ *maskfalse, movsicc_internal0, movsfcc_internal0): Call abort instead
+ of fatal_insn.
+
+2003-08-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c: Various formatting fixes.
+ (override_options): Resync -mtune handling with gas.
+ (mips_issue_rate): Rearrange like mips_use_dfa_pipeline_interface.
+ * config/mips/mips.h: More formatting fixes.
+ (mips_abi): Move declaration.
+ * config/mips/mips.md (exception_receiver): Add mode to
+ unspec_volatile.
+
+2003-08-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (spe_init_builtins): Handle evsplati and
+ evsplatfi here.
+ (bdesc_1arg): Remove evsplati and evsplatfi.
+
+2003-08-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * dwarf2asm.c (dw2_output_indirect_constant_1): Take user_label_prefix
+ into account.
+
+2003-08-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_strcat): Optimize constant strings.
+
+2003-08-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.c (pp_base_indent): Rename from pp_indent.
+ * c-pretty-print.h (pp_c_pretty_print_flag)s: New datatype.
+ (struct c_pretty_print_info): Add more fields.
+ (pp_c_left_paren): Move to c-pretty-print.c.
+ (pp_c_right_paren): Likewise.
+ (pp_c_left_brace): Likewise.
+ (pp_c_right_brace): Likewise.
+ (pp_c_left_bracket): Likewise.
+ (pp_c_right_bracket): Likewise.
+ (pp_c_declarator): Declare.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_specifier_qualifier_list): Likewise.
+ (pp_c_type_id): Likewise.
+ * c-pretty-print.c (pp_c_cv_qualifier): Change prootype. Rework..
+ (pp_c_type_qualifier_list): New.
+ (pp_c_pointer): Likewise.
+ (pp_c_parameter_type_list): Likewise.
+ (pp_c_function_definition): Likewise.
+ (pp_c_id_expression): Likewise.
+ (pp_c_simple_type_specifier): Tidy.
+ (pp_c_unary_expression): Likewise.
+ (pp_c_expression): Likewise.
+ (pp_c_pretty_printer_init): Likewise.
+ (pp_c_specifier_qualifier_list): Rework..
+ (pp_c_abstract_declarator): Likewise.
+ (pp_c_postfix_expression): Likewise.
+ (pp_c_primary_expression): Likewise.
+ (pp_c_cast_expression): Likewise.
+ (pp_c_direct_abstract_declarator): Likewise.
+ (pp_c_storage_class_specifier): Likewise.
+ (pp_c_function_specifier): Likewise.
+ (pp_c_declaration_specifiers): Likewise.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_declaration): Likewise.
+ (pp_c_statement): Likewise.
+ (pp_c_integer_constant): Rename from pp_c_integer_literal.
+ (pp_c_character_constant): Rename from pp_c_character_literal.
+ (pp_c_bool_constant): Rename from pp_c_bool_literal.
+ (pp_c_enumeration_constant): Rename from pp_c_enumerator.
+ (pp_c_floating_constant): Rename from pp_c_real_literal.
+ (pp_c_constant): Rename from pp_c_literal.
+ * c-lang.c: Include diagnostic.h and c-pretty-print.h
+ (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): Define.
+ (c_initialize_diagnostics): New.
+ * Makefile.in (c-lang.o): Update dependency.
+
+2003-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-typeck.c (digest_init): Add conversion for VECTOR_TYPEs.
+
+2003-08-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_no_mips16_string): Remove.
+ (override_options): Don't handle -mips16 as part of -mipsN.
+ * config/mips/mips.h (mips_no_mips16_string): Remove declaration.
+ (TARGET_SWITCHES): Add -mips16 and -mno-mips16 entries.
+ (TARGET_OPTIONS): Remove -mno-mips16.
+
+2003-08-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (coprocessor_operand): Remove declaration.
+ (coprocessor2_operand): Likewise.
+ * config/mips/mips.c (STAB_CODE_TYPE): Remove.
+ (lookup_name): Remove declaration.
+ (abort_with_insn): Remove. Replace all uses with fatal_insn.
+ (mips16, mips_abicalls): Remove.
+ (mips_char_to_class): Remove initialiser: all entries are NO_REGS.
+ (arith32_operand, large_int, true_reg_or_0_operand): Remove.
+ (coprocessor_operand, coprocessor2_operand): Remove.
+ (override_options): Don't set mips16 or mips_abicalls.
+ (print_operand): Don't expect SIGN_EXTEND operands.
+ (mips_secondary_reload_class): Likewise.
+ (mips_output_conditional_branch): Remove disabled long-branch code.
+ * config/mips/mips.h (call_used_regs): Remove declaration.
+ (may_call_alloca): Likewise.
+ (mips_cpu_attr, mips_abicalls_type, mips_abicalls_attr): Remove.
+ (mips_abicalls, mips16): Remove declarations.
+ (ASM_FINAL_SPEC, LIB_SPEC): Remove.
+ (CC1_SPEC): Remove outdated comment.
+ (MIPS_VERSION, MACHINE_TYPE): Remove.
+ (TARGET_VERSION_INTERNAL, TARGET_VERSION): Remove.
+ (PC_REGNUM, STACK_POINTER_OFFSET): Remove disabled definitions.
+ (STRUCT_VALUE_RETURN_REGNUM, STACK_DYNAMIC_OFFSET): Likewise.
+ (PUSH_ROUNDING): Likewise.
+ (ASSEMBLER_SCRATCH_REGNUM): Remove.
+ * config/mips/mips.md: Replace mips_cpu_attr with mips_tune
+ and mips16 with TARGET_MIPS16.
+
+2003-08-09 Per Bothner <pbothner@apple.com>
+
+ * cppinit.c (cpp_read_main_file): Split out source-independent
+ initialization to separate function ...
+ (cpp_post_options): New function.
+ * cppfiles.c (cpp_stack_file): Rename public name to ...
+ (_cpp_stack_file): New internal function name.
+ * cpplib.h: Update accordingly.
+ * cppinit.c: (cpp_create_reader): Initialize cpp_readers line here.
+ (cpp_read_main_file): Don't initialize line here.
+ * c-opts.c (c_common_post_options): Call cpp_post_options.
+ (c_common_parse_file): Call cpp_read_main_file, not cpp_stack_file.
+ * fix-header.c (read_scan_file): Call cpp_post_options.
+
+2003-08-09 Per Bothner <per@bothner.com>
+
+ * c-decl.c (SCOPE_LIST_APPEND): Remove bogus line continuation.
+
+2003-08-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_asm_output_mi_thunk): Fix typo.
+
+2003-08-09 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/11839
+ * cppfiles.c (open_file): Handle ENOTDIR.
+
+2003-08-09 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/11699
+ * config/mips/mips.c (override_options): Reject -mabi=eabi -mabicalls.
+
+2003-08-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md (extzv, extv, insv): Fix operand limit checks. Fail if
+ source/destination is not a register operand.
+
+2003-08-08 Richard Henderson <rth@redhat.com>
+
+ PR target/11535
+ * config/ia64/ia64.c (ia64_initial_elimination_offset): Remove
+ RETURN_ADDRESS_POINTER_REGNUM.
+ (ia64_expand_prologue): Don't frob it.
+ (ia64_output_function_epilogue): Likewise.
+ (ia64_return_addr_rtx): New.
+ (ia64_split_return_addr_rtx): New.
+ * config/ia64/ia64-protos.h: Update.
+ * config/ia64/ia64.h (FIRST_PSEUDO_REGISTER): Decrement.
+ (RETURN_ADDRESS_POINTER_REGNUM): Remove.
+ (GENERAL_REGNO_P): Don't check it.
+ (AR_*_REGNUM): Renumber.
+ (FIXED_REGISTERS): Remove RETURN_ADDRESS_POINTER_REGNUM.
+ (CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS): Likewise.
+ (REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Likewise.
+ (ELIMINABLE_REGS, REGISTER_NAMES): Likewise.
+ (RETURN_ADDR_RTX): Use ia64_return_addr_rtx.
+ * config/ia64/ia64.md (UNSPEC_RET_ADDR): New.
+ (movdi_ret_addr): New.
+
+2003-08-08 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc (powerpc-*-darwin*): Don't build a soft-float multilib.
+
+2003-08-08 Roger Sayle <roger@eyesopen.com>
+
+ * tree.h (get_identifier) Define a macro form of get_identifier
+ that calls get_identifier_with_length when the string is constant.
+ (get_identifier_with_length): Change type of second argument to
+ size_t in prototype.
+ * stringpool.c (get_identifier): Undefine the macro before giving
+ the function definition.
+ (get_identifier_with_length): Change type of second argument to
+ size_t in function definition.
+ * hashtable.c (calc_hash): Change type of second argument to size_t.
+ (ht_lookup): Change type of third argument to size_t. Reorganize
+ to speed-up the cases where the hash table slot is empty, or the
+ first probe matches (i.e. there isn't a collision).
+ * hashtable.h (ht_lookup): Adjust function prototype.
+
+2003-08-08 Bernardo Innocenti <bernie@develer.com>
+
+ PR target/9697
+ PR target/11777
+ * longlong.h (count_leading_zeros): Exclude on __mcpu32__.
+
+2003-08-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: Add debug switches.
+ * flags.h (use_gnu_debug_info_extensions): Boolify.
+ * opts.c (write_symbols, debug_info_level,
+ use_gnu_debug_info_extensions): Move from toplev.c.
+ (set_debug_level): New.
+ (common_handle_options): Handle debug switches.
+ (print_help): Display target options directly.
+ * toplev.c (debug_hooks): Don't initialize.
+ (write_symbols, debug_info_level,
+ use_gnu_debug_info_extensions): Move to opts.c.
+ (debug_args, display_help, decode_g_option): Remove.
+ (process_options): Set no debug if level zero here,
+ and no-debug-hooks. Error here if impossible debug format selected.
+ * toplev.h (display_help, decode_g_option): Remove.
+
+2003-08-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * tree.c (get_file_function_name_long): Fix size of alloca() area.
+
+2003-08-08 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (gcc_cv_prog_cmp_skip): Flipflop make_compare_target
+ and gcc_cv_prog_cmp_skip.
+ * configure: Regenerate.
+
+2003-08-08 Stan Cox <scox@redhat.com>
+
+ * config/iq2000: New port.
+ * config.gcc (iq2000-*-elf): Added.
+ * doc/install.texi (Specific): Add iq2000 description.
+
+2003-08-08 Andreas Schwab <schwab@suse.de>
+
+ * configure.in (gcc_cv_as_ia64_ltoffx_ldxmov_relocs): Fix quoting
+ and insert missing empty argument.
+ * configure: Regenerate.
+
+2003-08-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (update_total_code_bytes): Use new macro IN_NAMED_SECTION_P.
+ (attr_length_millicode_call): Likewise.
+ (attr_length_call): Likewise. Revise some maximum insn lengths.
+ (attr_length_indirect_call): Likewise.
+ (output_call): Fix thinko that added extra nop.
+ * pa.h (IN_NAMED_SECTION_P): Define.
+
+ PR c++/11712
+ * pa-hpux.h, pa-hpux10.h, pa-hpux11.h (TARGET_OS_CPP_BUILTINS): Define
+ __STDC_EXT__ when using C++ dialect.
+
+2003-08-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (calc_live_regs): If the return address pointer is live,
+ force pr live.
+ (sh5_schedule_saves): Exclude PR_MEDIA_REG from being a temp register
+ for saves / restores.
+ (sh_expand_epilogue): If sh_media_register_for_return returns a
+ register number, flag the instructions that restores PR_MEDIA_REG
+ as possibly dead.
+ Remove dead update of offset.
+ (sh_get_pr_initial_val): Use UNSPEC_RA if we don't know yet if
+ we can use the result of get_hard_reg_initial_val.
+ * sh.md (UNSPEC_RA): New constant.
+ (movsi_i_lowpart+1): Changed into a define_insn_and_split, named:
+ (load_ra). Handle UNSPEC_RA.
+ (sibcall_media): Use PR_MEDIA_REG.
+
+ * sh.h (CALL_USED_REGISTERS): Include PR_REG and PR_MEDIA_REG.
+ * sh.c (calc_live_regs): Use sh_pr_n_sets to determine if pr
+ needs saving on SHmedia.
+
+2003-08-07 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md: Replace all occurrences of \\t with \t.
+
+2003-08-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * local-alloc.c (combine_regs): Fix comment typo.
+
+2003-08-06 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (builtin_decls): Replace with first_builtin_decl
+ and last_builtin_decl.
+ (c_init_decl_processing): Initialize both.
+ (c_reset_state): Iterate from first_builtin_decl to
+ last_builtin_decl inclusive to reintroduce builtins.
+
+2003-08-06 David Mosberger <davidm@hpl.hp.com>
+
+ * doc/extend.texi (Function Attributes): Document the IA-64 version
+ of the "model" attribute.
+
+ * config/ia64/ia64.h (SYMBOL_FLAG_SMALL_ADDR): New macro.
+ (SYMBOL_REF_SMALL_ADDR_P): Ditto.
+ (PREDICATE_CODES): Mention "small_addr_symbolic_operand".
+
+ * config/ia64/ia64.c (ia64_handle_model_attribute): New function.
+ (ia64_encode_section_info): Likewise.
+ (ia64_attribute_table): Add "model" attribute.
+ (TARGET_ENCODE_SECTION_INFO): Define.
+ (small_addr_symbolic_operand): New function.
+ (got_symbolic_operand): Return 0 for a symbolref to an object
+ in the small address area.
+ (enum ia64_addr_area): New type.
+ (small_ident1): New variable.
+ (small_ident2): Likewise.
+ (init_idents): New function.
+ (ia64_get_addr_area): Likewise.
+ (ia64_encode_addr_area): Likewise.
+ (ia64_encode_section_info): Likewise.
+ (ia64_expand_load_address): For symbolic references to objects in
+ the small-address-area, load the address via gen_rtx_SET() (which,
+ eventually, will expand into "addl").
+
+2003-08-06 Per Bothner <pbothner@apple.com>
+
+ * line-map.h (fileline): New typedef.
+ (struct line_map, linemap_add, linemap_lookup): Use it.
+ * input.h (struct location_s): Comment notes that long-term we want
+ to replace it by fileline.
+
+2003-08-06 J"orn Rennecke <joern.rennecke@superh.com>
+
+ Fix SHcompact exception handling:
+ * sh.c (sh_get_pr_initial_val): If PR is or miight be clobbered
+ by the prologue, return a MEM with return_address_pointer_rtx
+ as address.
+ * sh.h (HARD_REGNO_MODE_OK): PR is OK for SImode.
+ (RETURN_ADDR_OFFSET): Don't define.
+ (SH_DBX_REGISTER_NUMBER): Use SHmedia numbers for SHmedia
+ registers that are visible in compact mode. Show that SHmedia
+ registers still exist in compact mode, even if there are not
+ readily accessible.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Supply DW_EH_PE_indirect
+ if GLOBAL. Use DW_EH_PE_textrel (nominally) for CODE,
+ and DW_EH_PE_pcrel for pic data.
+ (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): If DW_EH_PE_textrel,
+ set SYMBOL_FLAG_FUNCTION in symbol, and actually use
+ DW_EH_PE_pcrel / DW_EH_PE_absptr encoding.
+ (ALLOCATE_INITIAL_VALUE): Put PR on stack if prologue clobbers it.
+ * sh.md (movsi_media-1): New splitter.
+
+2003-08-06 Graeme Peterson <gp@qnx.com>
+
+ * config/i386/nto.h: New.
+ * config/i386/t-nto: New.
+ * config.gcc (i[34567]86-*-nto-qnx*): New.
+
+2003-08-06 Phil Edwards <pme@gcc.gnu.org>
+
+ * doc/install.texi (*-*-solaris2*): Refine configure instructions.
+
+2003-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (load_register_parameters): Arrange for call_fusage to
+ report the whole register as used when shifting to the msb.
+
+2003-08-05 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin): When not optimizing, call the library
+ function for all builtins that have library functions (except alloca).
+
+2003-08-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * c.opt: Introduce -fworking-directory.
+ * doc/cpp.texi, doc/invoke.texi, doc/cppopts.texi: Document it.
+ * c-common.h (flag_working_directory): Declare.
+ * c-common.c (flag_working_directory): Define.
+ * c-opts.c (c_common_handle_options): Set it.
+ (sanitize_cpp_opts): Set...
+ * cpplib.h (struct cpp_options): ... working_directory option.
+ (struct cpp_callbacks): Add dir_change.
+ * cppinit.c (read_original_filename): Call...
+ (read_original_directory): New. Look for # 1 "directory//"
+ and process it.
+ (cpp_read_main_file): Call dir_change callback if working_directory
+ option is set.
+ * gcc.c (cpp_unique_options): Pass -g*.
+ * c-lex.c (cb_dir_change): New.
+ (init_c_lex): Set dir_change callback.
+ * toplev.c (src_pwd): New static variable.
+ (set_src_pwd, get_src_pwd): New functions.
+ * toplev.h (get_src_pwd, set_src_pwd): Declare.
+ * dbxout.c (dbxout_init): Call get_src_pwd() instead of getpwd().
+ * dwarf2out.c (gen_compile_unit_die): Likewise.
+ * dwarfout.c (output_compile_unit_die, dwarfout_init): Likewise.
+
+2003-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_set_line_maximum_length): Make macro.
+ (pp_set_prefix): Likewise.
+ (pp_destroy_prefix): Likewise.
+ (pp_remaining_character_count_for_line): Likewise.
+ (pp_clear_output_area): Likewise.
+ (pp_formatted_text): Likewise.
+ (pp_last_position_in_text): Likewise.
+ (pp_emit_prefix): Likewise.
+ (pp_append_text): Likewise.
+ (pp_flush): Likewise.
+ (pp_format_text): Likewise.
+ (pp_format_verbatim): Likewise.
+ (pp_tree_identifier): Tidy.
+ * pretty-print.c (pp_base_format_text): Rename from pp_format_text.
+ (pp_base_format_verbatim): Rename from pp_format_verbatim.
+ (pp_base_flush): Rename from pp_flush.
+ (pp_base_set_line_maximum_length): Rename from
+ pp_set_line_maximum_length.
+ (pp_base_clear_output_area): Rename from pp_clear_output_area.
+ (pp_base_set_prefix): Rename from pp_set_prefix.
+ (pp_base_destroy_prefix): Rename from pp_destroy_prefix.
+ (pp_base_emit_prefix): Rename from pp_emit_prefix.
+ (pp_base_append_text): Rename from pp_append_text.
+ (pp_base_formatted_text): Rename from pp_formatted_text.
+ (pp_base_last_position_in_text): Rename from pp_last_position_in_text.
+ (pp_base_remaining_character_count_for_line): Rename from
+ pp_remaining_character_count_for_line.
+ * diagnostic.h (diagnostic_format_decoder): Tidy.
+ (diagnostic_flush_buffer): Likewise.
+ * c-pretty-print.h: (pp_c_string_literal): Declare.
+ (pp_c_real_literal): Likewise.
+ (pp_c_integer_literal): Likewise.
+ * c-pretty-print.c (pp_c_char): Use pp_string in lieu of
+ pp_identifier.
+ (pp_c_character_literal): Tidy.
+ (pp_c_string_literal): Make public.
+ (pp_c_bool_literal): Likewise.
+ (pp_c_integer_literal): Likewise.
+ (pp_c_real_literal): Likewise.
+
+ * Makefile.in (C_PRETTY_PRINT_H): New variable.
+ (c-pretty-print.o): Update dependence.
+
+2003-08-05 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (fix_truncdfsi2_macro): Properly restore
+ ".set nomacro" state.
+ (fix_truncsfsi2_macro): Likewise.
+
+2003-08-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree.h (DID_INLINE_FUNC): Remove macro.
+ (DECL_DECLARED_INLINE_P): Move from c-tree.h and cp/cp-tree.h,
+ add tree check for FUNCTION_DECL.
+ (DECL_ESTIMATED_INSNS): Move from c-common.h and java/java-tree.h.
+ (struct tree_decl): Rename inlined_function_flag to
+ declared_inline_flag.
+ * c-common.h (c_lang_decl): Remove.
+ (DECL_ESTIMATED_INSNS): Remove.
+ * c-tree.h (struct lang_decl): Don't include c_lang_decl.
+ (DECL_DECLARED_INLINE_P): Remove.
+ * c-decl.c (grokdeclarator): Update comment. With -finline-functions,
+ do not reset DECL_DECLARED_INLINE_P. Don't use DID_INLINE_FUNC.
+ (finish_function): Make uninlinable a bool. Fixup call to
+ tree_inlinable_function_p() and fix some code style issues.
+ * cgraph.h (disgread_inline_limits): Fix spelling: `disregard'.
+ * cgraph.c (dump_cgraph): Likewise.
+ * cgraphunit.c (cgraph_decide_inlining): Likewise
+ (cgraph_finalize_compilation_unit): Likewise.
+ Also update call to tree_inlinable_function_p().
+ (cgraph_default_inline_p): Don't use DID_INLINE_FUNC. Instead
+ look at DECL_DECLARED_INLINE and reverse logic.
+ * print-tree.c (print_node): Likewise.
+ * toplev.c (rest_of_handle_inlining): Don't use DID_INLINE_FUNC.
+ * tree-inline.h (tree_inlinable_function_p): Make a bool. Update
+ prototype.
+ * tree-inline.c (inlinable_function_p): Split up in this function to
+ check for basic inlining inhibiting conditions, and new
+ limits_allow_inlining() function. Warn if inlining is impossible
+ because the inline candidate calls alloca or uses sjlj exceptions.
+ (limits_allow_inlining): this new function to check if the inlining
+ limits are satisfied. Throttle from currfn_max_inline_insns, not from
+ MAX_INLINE_INSNS_SINGLE. The latter only makes sense if
+ MAX_INLINE_INSNS_AUTO and MAX_INLINE_INSNS_SINGLE are equal.
+ Update prototypes.
+ (tree_inlinable_function_p): Make a bool. Update call to
+ inlinable_function_p
+ (expand_call_inline): Use limits_allow_inlining() when not in
+ unit-at-a-time mode to decide on inlining. Don't use DID_INLINE_FUNC,
+ instead see if the function was declared `inline'.
+
+2003-08-05 Josef Zlomek <zlomekj@suse.cz>
+
+ * gcse.c (try_replace_reg): Fix updating of note.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11771
+ * fold-const.c (negate_expr_p <MINUS_EXPR>): Change to match the
+ logic in negate_expr, i.e. we don't invert (A-B) for floating
+ point types unless flag_unsafe_math_optimizations.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <PLUS_EXPR>): Transform x+x into x*2.0.
+ Optimize x*c+x and x+x*c into x*(c+1) and x*c1+x*c2 into x*(c1+c2)
+ for floating point expressions with -ffast-math.
+ (fold <MULT_EXPR>): Don't transform x*2.0 into x+x.
+ * expmed.c (expand_mult): Wrap long line. Expand x*2.0 as x+x.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * c-common.c (flag_noniso_default_format_attributes): Delete.
+ (built_in_attribute): Don't define/undefine DEF_FN_ATTR.
+ (c_attrs_initialized): Delete.
+ (c_common_nodes_and_builtins): Don't test c_attrs_initialized,
+ always call c_init_attributes.
+ (c_init_attributes): Don't define/undefine DEF_FN_ATTR. Don't
+ set c_attrs_initialized when done.
+ (c_common_insert_default_attributes): Delete.
+ * c-common.h (flag_noniso_default_format_attributes): Delete.
+ (c_coomon_insert_default_attributes): Delete prototype.
+ * c-opts.c (set_std_c89, set_std_c99, set_std_cxx98): Dont set
+ flag_noniso_default_format_attributes.
+
+ * c-decl.c (c_insert_default_attributes): Delete.
+ * c-tree.h (c_insert_default_attributes): Delete prototype.
+
+ * attribs.c (decl_attributes): Don't call insert_default_attributes
+ langhook. Update function description comment.
+ * langhooks.h (lang_hooks): Remove insert_default_attributes field.
+ * langhooks-def.h (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Delete.
+ * c-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't define.
+ * system.h: Poison LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES macro.
+
+ * objc/objc-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't
+ define.
+
+2003-08-04 Richard Sandiford <rsandif@redhat.com>
+
+ * config/mips/mips.c (override_options): Disable -G on targets that
+ have no .section support.
+ (mips_select_section): Use default_select_section for such targets.
+
+2003-08-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (svr4_undeclared_getrnge): Introduce and enable.
+ * fixinc/inclhack.def (static_getrnge): Remove disabled hack.
+ * fixinc/fixincl.x: Rebuild.
+ * fixinc/tests/base/regexp.h: New test.
+
+2003-08-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-ppoutput.c (cb_line_change): Don't skip line changing while
+ parsing macro arguments in the top-level context.
+
+2003-08-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * config.in: Remove HAVE_LSTAT.
+ * configure, configure.in: Don't test for lstat.
+
+2003-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * opts.c (decode_options): Do language-specific initialization for
+ the global diagnostic context.
+ * langhooks-def.h (lhd_initialize_diagnostics): Declare.
+ (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): New macro.
+ (LANG_HOOKS_INITIALIZER): Adjust.
+ * langhooks.h (struct lang_hooks): Add new field
+ initialize_diagnostics.
+ * langhooks.c (lhd_initialize_diagnostics): Define.
+
+2003-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h: Adjust macro definitions.
+ * pretty-print.c (pp_newline): Rename to pp_base_newline.
+ (pp_character): Rename to pp_base_character.
+ (pp_string): Rename to pp_base_string.
+ * c-pretty-print.c (pp_buffer): Move to pretty-print.h
+ (pp_newline): Likewise. Adjust.
+ (pp_c_char): Adjust.
+
+2003-08-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (BUILT_IN_ABS, BUILT_IN_IMAXABS, BUILT_IN_LABS,
+ BUILT_IN_LLABS): Move to miscellaneous section.
+
+2003-08-03 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/11534
+ * cppexp.c (parse_defined): Warn only if -pedantic.
+
+2003-08-03 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (stack_file): Use file path.
+
+2003-08-02 Roger Sayle <roger@eyesopen.com>
+
+ * builtin-types.def (BT_SSIZE): New primitive type.
+ (BT_FN_INT_PTR_CONST_STRING_VALIST_ARG,
+ BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
+ BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR,
+ BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR): New function types.
+ * builtins.def (BUILT_IN_DCGETTEXT, BUILT_IN_DGETTEXT,
+ BUILT_IN_FSCANF, BUILT_IN_GETTEXT, BUILT_IN_STRFMON,
+ BUILT_IN_STRFTIME, BUILT_IN_VFPRINTF, BUILT_IN_VFSCANF): New builtins.
+ * builtin-attrs.def: Remove DEF_FN_ATTR construct and the last
+ few functions that define default attributes using it.
+ * c-common.c (c_common_insert_default_attributes): Do nothing.
+
+ * doc/extend.texi: Document these "new" builtins.
+
+2003-08-02 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (SUBTARGET_LINK_SPEC): Don't set rpath.
+ (LIB_SPEC): Set -lpthread always when -pthread set. Set -lieee
+ when -mieee-fp set and -shared not set.
+ (SH_FALLBACK_FRAME_FLOAT_STATE): Don't define for SH5.
+
+2003-08-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (struct _cpp_file): Rename once_only_next to
+ next_file. Remove import and pragma_once, add once_only.
+ (find_file): Add new file structures to the all_files list.
+ (should_stack_file): Mark #import-ed files once-only, and
+ don't stack them if the file has already been stacked.
+ (_cp_mark_file_once_only): Simplify.
+ * cpphash.h (struct cpp_reader): Rename once_only_files
+ to all_files. Rename saw_pragma_once to seen_once_only.
+ (_cpp_mark_file_once_only): Update prototype.
+ * cpplib.c (do_pragma_once): Update.
+
+2003-08-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (ENOTDIR): Remove.
+ (open_file_in_dir): Rename find_file_in_dir. Handle errors
+ other than ENOENT here.
+ (once_only_file_p): Rename should_stack_file.
+ (find_file, open_file_failed, read_file_guts): Report errors
+ with full path name.
+ (read_file): Move pch handling to should_stack_file.
+ (should_stack_file): Handle PCH and once-only issues, and
+ reading the file.
+ (stack_file): Don't do file reads.
+
+2003-08-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * libgcov.c (gcov_exit): Cleanup and fix.
+ * profile.c (compute_value_histograms): Don't try to read profiles
+ that are not present.
+
+2003-08-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Categorize.
+
+ * builtins.def (BUILT_IN_CABS, BUILT_IN_CABSF, BUILT_IN_CABSL):
+ Mind fp rounding.
+ (BUILT_IN_FFSL): Use DEF_EXT_LIB_BUILTIN.
+
+2003-08-02 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * config.gcc: Enable posix threads by default on darwin.
+
+2003-08-01 Jakub Jelinek <jakub@redhat.com>
+
+ * cfgcleanup.c (outgoing_edges_match): Check REG_EH_REGION notes
+ even if nehedges1 is 0.
+
+2003-08-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/fixfixes.c, fixinc/fixlib.c, fixinc/fixlib.h,
+ fixinc/fixtests.c, fixinc/procopen.c, fixinc/server.c,
+ fixinc/server.h, fixinc/fixincl.c: ANSIfy function prototypes
+ and defintions.
+
+ * fixinc/inclhack.def (broken_cabs): Make matching more generous.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/math.h: Regenerate to match test_text change.
+
+2003-08-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * ggc-common.c (gt_pch_restore): Case MAP_FAILED to void *.
+
+2003-08-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * except.c (sjlj_emit_dispatch_table): Use ptr_mode, not Pmode,
+ for accesses to exc_ptr.
+
+2003-08-01 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/sourcebuild.texi (Front End Directory): Don't make references
+ to libsubdir, it's not part of the interface to frontends.
+ * doc/install.texi (Configuration): Help users read faster by saying
+ that GCC's configure options are the standard autoconf ones.
+ Mention --libdir. Update the default rules for finding the
+ assembler. Don't use libsubdir since we haven't said what it means.
+ (Specific): In the Solaris 7 notes, update the place to put the
+ assembler.
+ * doc/invoke.texi: Update lib/gcc-lib to lib/gcc.
+ * doc/cpp.texi (Search Path): Actually, the search path
+ depends on libdir, which can relocate with cpp.
+ * doc/tm.texi (Driver): Don't document STANDARD_EXEC_PREFIX, it's
+ now a private interface between the Makefile and the driver.
+
+2003-08-01 Richard Henderson <rth@redhat.com>
+
+ * system.h: Poison ASM_SIMPLIFY_DWARF_ADDR.
+
+ * varasm.c (lookup_constant_def): New function.
+ * rtl.h (lookup_constant_def): Declare it.
+ * dwarf2out.c (loc_descriptor_from_tree): Use it.
+ Use targetm.delegitimize_address, not ASM_SIMPLIFY_DWARF_ADDR.
+
+2003-08-01 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (gettags, pushdecl_function_level): Delete.
+ (last_function_parm_vars): Rename last_function_parm_others.
+ (current_function_parm_vars): Rename current_function_parm_others.
+ (struct c_scope): Rewrite comment explaining this data structure.
+ Add names_last, blocks_last, parms_last fields. Rename
+ incomplete_list to incomplete.
+ (SCOPE_LIST_APPEND, SCOPE_LIST_CONCAT): New macros.
+ (poplevel): Ignore second argument. No need to nreverse
+ anything. Restructure such that each list is processed
+ exactly once. Use 'const location_t *locus' syntactic sugar
+ variable where useful. Issue unused variable warnings
+ ourselves, do not rely on function.c.
+ (insert_block, pushdecl, bind_label): Use SCOPE_LIST_APPEND.
+ (pushdecl_top_level): Likewise. Don't call duplicate_decls.
+ (implicitly_declare): decl cannot be error_mark_node.
+ (undeclared_variable): Manipulate scope structure directly.
+ (c_make_fname_decl): Likewise.
+ (getdecls, c_init_decl_processing): Fix comment.
+ (mark_forward_parm_decls): Use SCOPE_LIST_CONCAT. No need
+ for 'last' variable.
+ (grokparms): No need to nreverse parms list.
+ (store_parm_decls_newstyle): Set up the parms_last and
+ names_last fields of the new scope too.
+ (store_parm_decls_oldstyle): Can assume DECL_WEAK is not set
+ on parms to begin with; check this under ENABLE_CHECKING. Set
+ up parms_last.
+ (check_for_loop_decls): Refer directly to current_scope->tags.
+ Use consistent quote style in diagnostics.
+ (c_write_global_declarations): The names list is not backward.
+
+ * c-common.h: Don't prototype gettags.
+ * c-parse.in: Call poplevel with second argument 0 always.
+
+2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Resort builtins.
+
+2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (DEF_GCC_BUILTIN, DEF_LIB_BUILTIN,
+ DEF_EXT_LIB_BUILTIN, DEF_C99_BUILTIN, DEF_C99_C90RES_BUILTIN):
+ Prepend "__builtin_" onto NAME with string concatenation. Remove
+ explicit "__builtin_" from each macro call.
+
+ Reformat entire file.
+
+2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (ATTR_MATHFN_ERRNO, ATTR_MATHFN_FPROUNDING,
+ ATTR_MATHFN_FPROUNDING_ERRNO): New macros. Use throughout.
+
+2003-08-01 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.c (s390_select_ccmode): Do not attempt to use CCL,
+ CCL1, or CCL2 modes with floating point operations.
+
+ * config/s390/s390.md ("*addsf3_cc", "*addsf3_cconly", "*adddf3_cc",
+ "*adddf3_cconly", "*subsf3_cc", "*subsf3_cconly", "*subdf3_cc",
+ "*subdf3_cconly"): New insns.
+ ("*negabssi2", "*negabsdi2", "*negabsdf2", "*negabssf2"): Likewise.
+
+2003-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Refine dependencies.
+ * c-opts.c (c_common_handle_option): Do nothing for -Wimport.
+ * c.opt: Update help for -Wimport.
+ * cppfiles.c: Include hashtab.h. Update comments.
+ (stack_file): Read the file before updating dependencies.
+ (once_only_file_p): Be smarter about marking once-only files.
+ (_cpp_mark_file_once_only): Correct the check for existence on
+ the list.
+ (open_file_failed): Use name not path, which is NULL.
+ * cpphash.h: Don't include hashtab.h.
+ (struct _cpp_file): Remove.
+ (struct cpp_reader): Update.
+ * cppinit.c (cpp_create_reader): Don't initialize warn_import.
+ * cpplib.h (struct cpp_options): Remove warn_import.
+ (cpp_simplify_path): Remove.
+
+2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11295
+ * doc/extend.texi (Statement Expressions): Document C++ semantics.
+
+2003-07-31 SUGIOKA Toshinobu <sugioka@itonet.co.jp>
+
+ * config.gcc (sh-*-linux*): Do not override sh/t-linux with sh/t-le.
+
+2003-07-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def: Use `LONGDOUBLE' instead of `LONG_DOUBLE'
+ throughout.
+ * builtins.def: Likewise.
+
+2003-07-31 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in (bubblestrap): Don't require a previous full
+ bootstrap.
+
+ * expr.c (mostly_zeros_p): No longer static.
+ * tree.h: Declare it.
+ * stmt.c (resolve_asm_operand_names): Don't copy the pattern
+ unless we need to do substitutions.
+
+2003-07-31 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <MULT_EXPR>): Optimize both x*pow(x,c) and
+ pow(x,c)*x as pow(x,c+1) for constant values c. Optimize x*x
+ as pow(x,2.0) when the latter will be expanded back into x*x.
+ (fold <RDIV_EXPR>): Optimize pow(x,c)/x as pow(x,c-1).
+ * builtins.c (expand_builtin_pow): Ignore flag_errno_math as
+ pow can never set errno when used with an integer exponent.
+ Always use expand_powi when exponent is -1, 0, 1 or 2.
+ (fold_builtin): Don't rewrite pow(x,2.0) as x*x nor pow(x,-2.0)
+ as 1.0/(x*x). This avoids unbounded recursion as we now prefer
+ the pow forms of these expressions.
+
+2003-07-31 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (libexecdir): New.
+ (libsubdir): Use gcc instead of gcc-lib.
+ (libexecsubdir): New.
+ (ORDINARY_FLAGS_TO_PASS): Add libexecsubdir.
+ (DRIVER_DEFINES): Add STANDARD_LIBEXEC_PREFIX, use gcc instead of
+ gcc-lib.
+ (installdirs): Make libexecsubdir.
+ (install-common): Put executables in libexecsubdir.
+ (itoolsdir): Use libexecsubdir.
+ (itoolsdatadir): New.
+ (install-mkheaders): Separate data files and executables.
+ (install-collect2): Put executables in libexecsubdir.
+ (uninstall): Remove libexecsubdir.
+ * mkheaders.in: Update for new arrangement of files.
+ (libexecdir): New.
+ (libexecsubdir): New.
+ (itoolsdir): Use libexecsubdir.
+ (itoolsdatadir): New.
+ * gcc.c (gcc_libexec_prefix): New.
+ (STANDARD_LIBEXEC_PREFIX): Use gcc instead of gcc-lib.
+ (standard_exec_prefix_1): Use libexec.
+ (standard_exec_prefix_2): New.
+ (standard_libexec_prefix): New.
+ (process_command): Update for new arrangement of files. Compute
+ gcc_libexec_prefix. Update for change from gcc-lib to gcc.
+
+2003-07-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * inclhack.def (stdio_va_list): Avoid bogus replacement which
+ triggers on Interix.
+ * fixincl.x: Regenerate.
+
+2003-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Disallow TLS
+ SYMBOL_REFs not inside UNSPEC even in PLUS rtx.
+
+2003-07-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * dwarf2out.c (loc_descriptor_from_tree, case CONSTRUCTOR): New case.
+
+2003-07-31 Per Bothner <pbothner@apple.com>
+
+ * opts.c (in_fnames, num_in_fnames): Moved here from c-opts.
+ (add_input_filename): New function.
+ (handle_options): Call add_input_filename directly instead of
+ with a lang hook.
+ * opts.h (in_fnames, num_in_fnames): Moved here.
+ (add_input_filename): Declare.
+ * c-decl.c: Need to #include opts.h.
+ * Makefile.in (c-decl.o): Also depends on opts.h.
+ * c-opts.c (in_fnames, num_in_fnames): Moved to opts.c.
+ (c_common_handle_filename): Replaced by add_input_filename.
+ * c-common.h (in_fnames, num_in_fnames, c_common_handle_filename):
+ Remove.
+ * langhooks.h (struct lang_hooks): Remove handle_filename hook.
+ * langhooks-def.h (LANG_HOOKS_HANDLE_FILENAME): Remove macro.
+ (LANG_HOOKS_INITIALIZER): Remove use of LANG_HOOKS_HANDLE_FILENAME.
+ * c-lang.c (LANG_HOOKS_HANDLE_FILENAME): Remove macro.
+
+2003-07-31 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * combine.c (try_combine): Set JUMP_LABEL for newly created
+ unconditional jump.
+
+2003-07-31 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * fold-const.c (fold): Fold some comparisons of bit operations.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (create_edge): Fix typo.
+ * i386.c (pic_symbolic_operand): Reorder tests.
+
+2003-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/gcov.texi (Invoking Gcov): Describe output name mangling
+ more fully.
+ (Gcov Data Files): Update.
+
+2003-07-31 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (alpha*-dec-osf[45]*): Enable POSIX thread support by
+ default.
+
+ * gthr-posix.c: New file.
+ * gthr-posix.h: Define _REENTRANT if missing.
+ Make _LIBOBJC #pragma weak visible with _LIBOBJC_WEAK.
+
+ * config/alpha/t-osf4 (SHLIB_LINK): Hide dummy functions provided
+ by gthr-posix.o.
+ * config/alpha/t-osf-pthread: New file.
+
+ * fixinc/inclhack.def (alpha_pthread): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/pthread.h [ALPHA_PTHREAD_CHECK]: New testcase.
+
+ * doc/install.texi (alpha*-dec-osf*): Remove --enable-threads
+ warning.
+ Fixes PR bootstrap/9330.
+
+2003-07-31 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_ld_hidden): Also disable on mips-sgi-irix5*
+ without GNU ld.
+ Update comment.
+ * configure: Regenerate.
+
+2003-07-31 Vladimir Makarov <vmakarov@redhat.com>
+
+ * sched-deps.c (sched_analyze_2): Prevent interblock move of CC0
+ setter.
+
+2003-07-30 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def: Alphabetize.
+
+2003-07-30 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/c-tree.texi: Normalize spellings of "lowercase" and
+ "uppercase".
+ * doc/cpp.texi: Likewise.
+ * doc/md.texi: Likewise.
+ * doc/rtl.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-07-30 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * objc/Make-lang.in (objc.stage1, objc.stage2, objc.stage3)
+ (objc.stage4, objc.stageprofile, objc.stagefeedback): Remove moves
+ of cc1obj.
+
+2003-07-30 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (SIZE_TYPE, PTRDIFF_TYPE): Undef these
+ macros before defining them.
+
+2003-07-31 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md (UNSPEC_ROUND, UNSPEC_SETHIGH,
+ UNSPECV_BLOCKAGE): New constants.
+ ("*sethighqisi", "*sethighhisi", "*sethiqidi_64", "*sethiqidi_31",
+ "*extractqi", "*extracthi", "*extendqidi2" splitter, "*extendqisi2"
+ splitter, "fix_truncdfdi2_ieee", "fix_truncdfsi2_ieee",
+ "fix_truncsfdi2", "fix_truncsfsi2", "blockage"): Use them.
+
+ (all insns and expanders): Write output control string as brace block
+ where appropriate. Remove \-escapes for doublequote characters.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (insert_store): Fix typo in previous patch.
+
+2003-07-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (stack_file, open_file_failed): Use path for deps.
+
+2003-07-30 Andi Kleen <ak@muc.de>
+
+ * loop.c (check_dbra_loop): Allow LTU in the loop condition.
+
+2003-07-30 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * combine.c (distribute_notes): Cancel REG_VALUE_PROFILE notes.
+ * gcov-io.h (GCOV_FIRST_VALUE_COUNTER, GCOV_LAST_VALUE_COUNTER,
+ GCOV_N_VALUE_COUNTERS): New.
+ * profile.c (compute_value_histograms): New static function.
+ (branch_prob): Read back the value histograms.
+ * rtl.c (reg_note_name): Add name for REG_VALUE_PROFILE note.
+ * rtl.h (enum reg_note): Add REG_VALUE_PROFILE note.
+ * value-prof.c: Add comment on reading the profile.
+ * value-prof.h (COUNTER_FOR_HIST_TYPE, HIST_TYPE_FOR_COUNTER): New.
+ * doc/invoke.texi (-fprofile-values): Document behavior with
+ -fbranch-probabilities.
+
+2003-07-30 David Edelsohn <edelsohn@gnu.org>
+
+ * longlong.h (PowerPC umul_ppmm): Do not test __vxworks__.
+
+2003-07-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (EH_RETURN_HANDLER_RTX): Compute offset
+ symbolically.
+
+2003-07-30 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (insert_store): Ignore fake edges.
+
+ * c-common.c (flag_vtable_gc): Kill.
+ * c-common.g (flag_vtable_gc): Kill.
+ * c-opts (c_common_handle_option): Kill.
+ * c.opt (fvtable-gc): Kill.
+ * final.c (final_scan_insn): Do not call assemble_vtable_entry.
+ * output.h (assemble_vtable_entry, assemble_vtable_inherit): Kill.
+ * varasm.c (assemble_vtable_entry, assemble_vtable_inherit): Kill.
+
+ * invoke.texi (-ftable-gc): Kill documentation.
+
+ * tree-inline.c (inlinable_function_p): Don't set DECL_UNINLINABLE
+ just because function body is missing.
+
+ * i386.c (pic_symbolic_operand): Properly detect RIP relative unspecs.
+
+2003-07-30 Ranjit Mathew <rmathew@hotmail.com>
+
+ * unwind-sjlj.c: Fix typo in file description.
+
+2003-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (load_register_parameters): When shifting reg sized values
+ to the msb, move the value to a reg first.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * cppfiles.c (stack_file): Leave filename as "" rather than "<stdin>".
+ * line-map.h (linemap_add): Update comments.
+ * line-map.c (linemap_add): Update comments, interpret zero-length
+ filename as "<stdin>".
+
+2003-07-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * mkinstalldirs: Import autoconf 2.57 / automake 1.7 version.
+
+2003-07-29 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (last_function_parm_vars, current_function_parm_vars):
+ New static variables.
+ (struct c_scope): Add parms and warned_forward_parm_decls
+ fields; remove parm_order.
+ (storedecls, storetags): Delete.
+ (poplevel): Also clear bindings on the parms chain.
+ (pushdecl): Handle forward declarations of parameters, and
+ chain PARM_DECLs on the parms list, not the names list.
+ (lookup_name_current_level): Check for PARM_DECLs on the parms
+ list too.
+ (push_parm_decl): Don't update parm_order.
+ (clear_parm_order): Rename mark_forward_parm_decls. Issue the
+ warning, only once per parameter list, and set TREE_ASM_WRITTEN
+ on the decls here. Then move the forward decls to the names list.
+ (grokparms): Set last_function_parm_vars.
+ (get_parm_info): Don't use gettags or getdecls. No need to
+ extract non-parms from the parms list, or reorganize the parms
+ list. Feed nonparms back in the TREE_TYPE of the list node
+ returned. Issue only one error per parameter list for "void"
+ appearing more than once in said parameter list. Collapse
+ parmlist_tags_warning into this function to avoid double scan
+ of tags list.
+ (start_function): Set current_function_parm_vars.
+ (store_parm_decls_newstyle): Bypass pushdecl, manipulate scope
+ directly. Get non-parms from current_function_parm_vars; no
+ need to extract them from the parms chain. Properly bind tags
+ in the new scope.
+ (store_parm_decls_oldstyle): No need to extract non-parameters
+ from the parms chain, nor to store them back afterward. Move
+ declaration to top of function, restructure code reordering
+ DECL_ARGUMENTS.
+ (store_parm_decls): No need to save and restore warn_shadow.
+ * c-parse.in: Don't call parmlist_tags_warning nor
+ clear_parm_order. Call mark_forward_parm_decls when forward
+ parm decls are encountered.
+ * c-tree.h: Prototype mark_forward_parm_decls; not
+ clear_parm_order or parmlist_tags_warning.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.c (allow_pch): Remove.
+ * c-common.h (allow_pch): Remove.
+ (c_common_no_more_pch): Declare.
+ * c-lex.c (c_lex): Call c_common_no_more_pch when appropriate.
+ * c-pch.c: Include hosthooks.h.
+ (c_common_valid_pch): Don't check allow_pch.
+ (c_common_read_pch): Clear valid_pch to prevent reading PCH files.
+ (c_common_no_more_pch): New.
+ * ggc-common.c: Include hosthooks.h.
+ (gt_pch_save): Call gt_pch_get_address.
+ (gt_pch_restore): Call gt_pch_use_address.
+ * hooks.c (hook_voidp_size_t_null): New.
+ (hook_bool_voidp_size_t_false): New.
+ * hooks.h (hook_voidp_size_t_null): New.
+ (hook_bool_voidp_size_t_false): New.
+ * hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): New.
+ (HOST_HOOKS_GT_PCH_USE_ADDRESS): New.
+ (HOST_HOOKS_INITIALIZER): Add HOST_HOOKS_GT_PCH_GET_ADDRESS,
+ HOST_HOOKS_GT_PCH_USE_ADDRESS.
+ * hosthooks.h (struct host_hooks): Add gt_pch_get_address,
+ gt_pch_use_address.
+ * doc/hostconfig.texi (Host Common): Document
+ HOST_HOOKS_GT_PCH_GET_ADDRESS, HOST_HOOKS_GT_PCH_USE_ADDRESS.
+ * Makefile.in (c-pch.o): Depend on hosthooks.h.
+ (ggc-common.o): Likewise.
+
+ * config/rs6000/host-darwin.c (HOST_HOOKS_GT_PCH_GET_ADDRESS): Define.
+ (HOST_HOOKS_GT_PCH_USE_ADDRESS): Define.
+ (pch_address_space): New.
+ (darwin_rs6000_gt_pch_get_address): New.
+ (darwin_rs6000_gt_pch_use_address): New.
+
+2003-07-29 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/11569
+ PR preprocessor/11649
+ * Makefile.in (LIBCPP_DEPS): Add HASHTAB_H.
+ * cppfiles.c: Completely rewritten.
+ * c-incpath.c (free_path, remove_duplicates, heads, tails, add_path):
+ struct cpp_path is now struct cpp_dir.
+ (remove_duplicates): Don't simplify path names.
+ * c-opts.c (c_common_parse_file): cpp_read_next_file renamed
+ cpp_stack_file.
+ * cpphash.h: Include hashtab.h.
+ (_cpp_file): Declare.
+ (struct cpp_buffer): struct include_file is now struct _cpp_file,
+ and struct cpp_path is now struct cpp_dir. Rename members.
+ (struct cpp_reader): Similarly. New members once_only_files,
+ file_hash, file_hash_entries, quote_ignores_source_dir,
+ no_search_path, saw_pragma_once. Remove all_include_files and
+ max_include_len. Make some members bool.
+ (_cpp_mark_only_only): Renamed from _cpp_never_reread.
+ (_cpp_stack_file): Renamed from _cpp_read_file.
+ (_cpp_stack_include): Renamed from _cpp_execute_include.
+ (_cpp_init_files): Renamed from _cpp_init_includes.
+ (_cpp_cleanup_files): Renamed from _cpp_cleanup_includes.
+ * cppinit.c (cpp_create_reader): Initialize no_search_path. Update.
+ (cpp_read_next_file): Rename and move to cppfiles.c.
+ (cpp_read_main_file): Update.
+ * cpplib.c (run_directive): Update for renamed members.
+ (do_include_common, _cpp_pop_buffer): Update.
+ (do_import): Undeprecate #import.
+ (do_pragma_once): Undeprecate. Use _cpp_mark_file_once_only.
+ * cpplib.h: Remove file_name_map_list.
+ (cpp_options): Remove map_list.
+ (cpp_dir): Rename from cpp_path. New datatype for name_map.
+ (cpp_set_include_chains, cpp_stack_file, cpp_included): Update.
+
+2003-07-29 Phil Edwards <pme@gcc.gnu.org>
+
+ * Makefile.in: Make stamp-objdir safe for parallel builds.
+
+2003-07-29 Phil Edwards <pme@gcc.gnu.org>
+
+ * Makefile.in (stmp-docobjdir): New target; ensure $docobjdir exists.
+ (info): Depend on stmp-docobjdir.
+
+2003-07-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure: Regenerate.
+
+2003-07-29 Jan Hubicka <jh@suse.cz>
+
+ PR C++/11131
+ * tree-inline.c (expand_call_inline): Always call inlinable_function_p
+ in !unit-at-a-time mode.
+
+2003-07-28 Geoffrey Keating <geoffk@apple.com>
+
+ * c-decl.c (c_expand_body_1): Use C_DECL_FILE_SCOPE to detect
+ main function.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11667
+ * c-common.c (shorten_compare): Take into account differences
+ between C and C++ representation for enumeration types.
+ * tree.h (set_min_and_max_values_for_integral_type): Declare.
+ * stor-layout.c (set_min_and_max_values_for_integral_type): New
+ function, broken out from ...
+ (fixup_signed_type): ... here and ...
+ (fixup_unsigned_type): ... here.
+
+2003-07-28 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c: Update commentary, adjust blank lines throughout.
+ (struct c_scope): Fix indentation. Reorder members so
+ outer-context pointers come first, booleans last.
+ (duplicate_decls, define_label): Use a 'locus' variable for
+ diagnostic locations in a few more places.
+ (warn_if_shadowing): Un-split a conditional that fits on one line.
+ (c_init_decl_processing): No need to clear current_scope and
+ current_function_scope.
+ (start_decl): Merge if/else if statements with same action.
+ (push_parm_decl): Rename old_immediate_size_expand to use
+ save_foo convention; save/restore around entire function.
+ (grokdeclarator): Remove unnecessary braces.
+
+2003-07-28 Hans-Peter Nilsson <hp@bitrange.com>
+ Michael Culbertson <Michael.J.Culbertson@wheaton.edu>
+
+ * c-parse.in (lineno_stmt_decl_or_labels_ending_decl): Also warn
+ when warn_declaration_after_statement. Call pedwarn_c90, not
+ pedwarn. Correct message: it's "ISO C90", not "ISO C89".
+ * c-common.c (warn_declaration_after_statement): Define.
+ * c-common.h (warn_declaration_after_statement): Declare.
+ * c.opt (Wdeclaration-after-statement): New.
+ * c-errors.c (pedwarn_c90): New function.
+ * c-opts.c (c_common_handle_option) <case
+ OPT_Wdeclaration_after_statement>: New.
+ * c-tree.h (pedwarn_c90): Declare.
+ * doc/invoke.texi (Option Summary): Document
+ -Wdeclaration-after-statement.
+ (Warning Options): Ditto.
+
+2003-07-28 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (memory attribute) Avoid accessing uninitialized memory
+ for ishift1 type instructions.
+
+2003-07-28 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.in (--enable-checking): Add fold category.
+ (ENABLE_FOLD_CHECKING): Define if requested.
+ * configure: Rebuilt.
+ * config.in: Rebuilt.
+ * doc/install.texi: Document it.
+ * fold-const.c: Include md5.h.
+ [ENABLE_FOLD_CHECKING] (fold): Define to fold_1.
+ [ENABLE_FOLD_CHECKING] (fold, fold_checksum_tree, fold_check_failed,
+ print_fold_checksum): New functions.
+
+ * fold-const.c (fold): Never modify argument passed to fold, instead
+ change a copy and return it.
+ * convert.c (convert_to_integer): Likewise.
+
+2003-07-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/fixinc.svr4: Remove dead code. Remove now-unnecessary
+ cleanup of junk after #else and #endif directives. Collapse repeated
+ clauses into for statment.
+
+ * fixinc/fixincl.sh: GNU C -> GCC. Add usage comment.
+
+2003-07-27 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (struct c_scope): Remove keep_if_subblocks field.
+ (keep_next_if_subblocks): Rename next_is_function_body.
+ (pushlevel): Adjust commentary. Always set ->keep on the
+ outermost level of a function. Don't set ->keep_if_subblocks.
+ (poplevel): Adjust commentary. Don't look at ->keep_if_subblocks.
+ (store_parm_decls): Adjust to match.
+ (finish_function): Adjust to match.
+ Call poplevel with all three arguments zero.
+
+ * c-decl.c (store_parm_decls_newstyle, store_parm_decls_oldstyle):
+ New functions split out of store_parm_decls.
+ Avoid unnecessary work. Use local variables consistently.
+ (store_parm_decls): Likewise.
+
+ (finish_function): No need to set functionbody flag on call to
+ poplevel.
+ (struct language_function): Remove scope field.
+ (c_push_function_context, c_pop_function_context): No need to
+ save and restore current_scope.
+
+2003-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/extend.texi (Deprecated Features): Implicit typename is
+ gone. Default args on types is going.
+
+2003-07-26 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * Makefile.in (ifcvt.o): Depend on target.h
+ * ifcvt.c (target.h): Include.
+ (if_convert): Don't call mark_loop_exit_edges if we can't
+ modify jumps.
+
+2003-07-26 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Testing): Adjust required versions of DejaGnu.
+
+2003-07-26 Richard Henderson <rth@redhat.com>
+
+ PR inline-asm/11676
+ * cse.c (count_reg_usage): Handle asm_operands properly.
+
+2003-07-26 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (DEF_FALLBACK_BUILTIN): Delete.
+ (DEF_EXT_FALLBACK_BUILTIN): Delete.
+ (BUILT_IN_BZERO, BUILT_IN_BCOPY, BUILT_IN_BCMP): Declare using
+ the regular DEF_EXT_LIB_BUILTIN macro.
+ (BUILT_IN_FPUTC, BUILT_IN_FPUTS, BUILT_IN_FWRITE): Declare using
+ the regular DEF_LIB_BUILTIN macro.
+ (BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTS_UNLOCKED,
+ BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS_UNLOCKED,
+ BUILT_IN_FWRITE_UNLOCKED): Declare using the regular
+ DEF_EXT_LIB_BUILTIN macro.
+
+ * c-decl.c (duplicate_decls): Remove code to handle builtin
+ functions prototyped without an argument list.
+
+2003-07-26 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c: Revert 2003-07-08 change.
+ (i386_pe_section_type_flags): Remove error_with_decl here too.
+
+2003-07-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * config/arm/pe.c (arm_mark_dllimport): Don't use xxx_with_decl.
+ * config/mcore/mcore.c (mcore_mark_dllimport): Likewise.
+ * config/v850/v850.c (v850_handle_data_area_attribute): Likewise.
+ (v850_handle_data_area_attribute): Likewise.
+
+2003-07-26 Geoffrey Keating <geoffk@apple.com>
+
+ * varasm.c (output_constant_def_contents): Use
+ ASM_DECLARE_CONSTANT_NAME if defined.
+ * doc/tm.texi (Label Output): Document ASM_DECLARE_CONSTANT_NAME.
+ * config/darwin.h (ASM_DECLARE_OBJECT_NAME): Ensure zero-sized
+ objects get at least one byte to prevent assembler problems.
+ (ASM_DECLARE_CONSTANT_NAME): New.
+
+ * Makefile.in (libbackend.o): Remove options_.h.
+ (mostlyclean): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Don't
+ insert a label at the end of an function under Mach-O.
+
+ * c-decl.c (c_static_assembler_name): Remove TREE_STATIC test.
+
+2003-07-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (is_ev64_opaque_type): Only check pointer
+ equality.
+ (spe_init_builtins): Declare __ev64_opaque__ as a builtin type.
+
+ * config/rs6000/spe.h: Remove __ev64_opaque__ definition.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * doc/passes.texi (Passes): Mention pretty-printing and
+ diagnostic files.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/extend.texi (Function Attributes): GNU C++ does now allow
+ unused parameter decls.
+ (Attribute Syntax): GNU C++ does not allow label attributes to be
+ after the ':'.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * objc/objc-act.c (objc_check_decl): Don't use xxx_with_decl.
+ (objc_declare_class): Likewise.
+ (error_with_ivar): Likewise.
+ (start_class): Likewise.
+ (warn_with_method): Likewise.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove pedwarn_with_decl, warning_with_decl and error_with_decl
+ from GCC.
+ * calls.c (try_to_integrate): Don't use xxx_with_decl.
+ (expand_call): Likewise.
+ * dwarfout.c (output_reg_number): Likewise.
+ * expr.c (expand_expr): Likewise.
+ * function.c (assign_temp): Likewise.
+ (uninitialized_vars_warning): Likewise.
+ (setjmp_args_warning): Likewise.
+ (expand_function_end): Likewise.
+ * stmt.c (fixup_gotos): Likewise.
+ (warn_about_unused_variables): Likewise.
+ (expand_end_bindings): Likewise.
+ * stor-layout.c (layout_decl): Likewise.
+ (place_field): Likewise.
+ * toplev.c (check_global_declarations): Likewise.
+ (rest_of_handle_inlining): Likewise.
+ (default_tree_printer): New function.
+ (general_init): Initialize diagnostic machinery before routing
+ signals to the ICE machinery. Set default tree printer.
+ * toplev.h (pedwarn_with_decl): Remove declaration.
+ (warning_with_decl): Likewise.
+ (error_with_decl): Likewise.
+ (pedwarn): Remove attribute for the time being.
+ * tree-inline.c (expand_call_inline): Don't use xxx_with_decl.
+ * varasm.c (named_section): Likewise.
+ (make_decl_rtl): Likewise.
+ (assemble_variable): Likewise.
+ (merge_weak): Likewise.
+ (declare_weak): Likewise.
+
+ * diagnostic.h: Move non-diagnostic stuff into pretty-print.h.
+ * diagnostic.c: Move non-diagnostic stuff into pretty-print.c.
+ (format_with_decl): Remove.
+ (diagnostic_for_decl): Likewise.
+ (pedwarn_with_decl): Likewise.
+ (warning_with_decl): Likewise.
+ (error_with_decl): Likewise.
+ (diagnostic_initialize): Adjust.
+ (diagnostic_count_diagnostic): Likewise.
+ (announce_function): Likewise.
+ (lhd_print_error_function): Likewise.
+ (diagnostic_report_current_module): Likewise.
+ (default_diagnostic_starter): Likewise.
+ (diagnostic_report_diagnostic): Likewise.
+ (default_diagnostic_finalizer): Likewise.
+ (verbatim): Likewise.
+ (error): Likewise.
+ (warning): Likewise.
+ * opts.c (common_handle_option): Likewise.
+ * pretty-print.c: New file.
+ * c-pretty-print.h (pp_base): Override.
+ * c-pretty-print.c: Adjust use of macros throughout.
+ (pp_buffer): New macro.
+ (pp_newline): Likewise.
+ * c-objc-common.c (c_tree_printer): Adjust prototype. Tidy.
+ * Makefile.in (DIAGNOSTIC_H): New variable.
+ (c-errors.o): Use it.
+ (c-objc-common.o): Likewise.
+ (c-common.o): Likewise.
+ (c-opts.o): Likewise.
+ (c-format.o): Likewise.
+ (diagnostic.o): Likewise.
+ (opts.o): Likewise.
+ (toplev.o): Likewise.
+ (rtl-error.o): Likewise.
+ (dwarf2out.o): Likewise.
+ (jump.o): Likewise.
+ (pretty-print.o): New rule.
+
+2003-07-24 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (BUILT_IN_PRINTF, BUILT_IN_FPRINTF): Changed from
+ front-end builtins to normal builtins, using DEF_LIB_BUILTIN.
+ (BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_FPRINTF_UNLOCKED): Changed
+ from front-end to normal builtins, using DEF_EXT_LIB_BUILTIN.
+ (DEF_FRONT_END_LIB_BUILTIN): Delete.
+ (DEF_EXT_FRONT_END_LIB_BUILTIN): Delete.
+ (BUILT_IN_FWRITE_UNLOCKED): Wrap long line.
+
+ * builtins.c (build_string_literal): New function to construct
+ a char* pointer to a string literal.
+ (expand_builtin_fputs): Change 2nd argument from "int ignore" to
+ "rtx target" to be consistent with other expand_builtin_* functions.
+ Change 3rd argument from "int unlocked" to "bool unlocked".
+ (expand_builtin_printf): Rewrite of c_expand_builtin_printf from
+ c-common.c to avoid front-end dependencies. Optimize printf("")
+ as a no-op when the result isn't required. Handle embedded NULs
+ in format string.
+ (expand_builtin_fprintf): A rewrite of c_expand_builtin_fprintf
+ from c-common.c to avoid front-end dependencies. Likewise, optimize
+ fprintf(fp,"") as a no-op when the result isn't required, evaluating
+ fp for side-effects. Handle embedded NULs in format string.
+ (expand_builtin_sprintf): Fix typo.
+ (expand_builtin): Don't expand BUILT_IN_FPRINT{,_UNLOCKED} when not
+ optimizing. Adjust calls of expand_builtin_fputs to match the API
+ change. Expand BUILT_IN_PRINTF and BUILT_IN_PRINTF_UNLOCKED using
+ expand_builtin_printf. Likewise, expand BUILT_IN_FPRINTF_UNLOCKED
+ and BUILT_IN_FPRINTF using expand_builtin_fprintf.
+
+ * c-common.c (is_valid_printf_arglist): Delete.
+ (c_expand_builtin): Delete.
+ (c_expand_builtin_printf): Moved to builtins.c. Delete.
+ (c_expand_builtin_fprintf): Moved to builtins.c. Delete.
+ (c_expand_expr): No longer treat CALL_EXPRs specially.
+ (CALLED_AS_BUILT_IN): Delete.
+
+2003-07-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/11631
+ * gcse.c (store_motion): Connect infinite loops to exit.
+
+2003-07-24 Jason Merrill <jason@redhat.com>
+
+ * tree.h (boolean_type_node): Move from C/C++/Java frontends.
+ (boolean_true_node, boolean_false_node): Likewise.
+ (enum tree_index): Add TI_BOOLEAN_{TYPE,FALSE,TRUE}.
+ * tree.c (build_common_tree_nodes): Init boolean_type_node.
+ (build_common_tree_nodes_2): Init boolean_{true,false}_node.
+ * stor-layout.c (set_sizetype): Handle an early BOOLEAN_TYPE.
+ * c-common.h (truthvalue_type_node): Renamed from boolean_type_node.
+ (truthvalue_true_node): Renamed from boolean_true_node.
+ (truthvalue_false_node): Renamed from boolean_false_node.
+ * c-decl.c: Just set truthvalue_* to integer_*.
+ * c-*.[ch]: s/boolean/truthvalue/. s/c_bool/boolean/.
+
+2003-07-24 Roger Sayle <roger@eyesopen.com>
+
+ * c-decl.c (match_builtin_function_types): New subroutine of
+ duplicate_decls to test whether a redeclaration of a builtin
+ function is suitably close, i.e. the return type and all of
+ the argument types have the same modes as the builtin expects.
+ (duplicate_decls): Fuzzy type matching for builtin functions
+ moved to match_builtin_function_types.
+
+2003-07-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (duplicate_loop_to_header_edge): Update irreducible
+ flag correctly.
+
+2003-07-24 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c: Search-and-replace change 'binding level' to
+ 'scope' in commentary.
+ (struct binding_level): Now struct c_scope.
+ (current_binding_level): Now current_scope.
+ (free_binding_level): Now scope_freelist.
+ (current_function_level): Now current_function_scope.
+ (global_binding_level): Now global_scope.
+ (make_binding_level): Now make_scope.
+ (pop_binding_level): Now pop_scope.
+
+2003-07-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (libgcc_visibility): Add missing whitespace.
+
+2003-07-24 Richard Henderson <rth@redhat.com>
+
+ * libgcc-std.ver (GCC_3.3.1): Export __gcc_personality_sj0,
+ __gcc_personality_v0.
+
+2003-07-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Makefile.in: Replace pwd by ${PWD_COMMAND}.
+
+2003-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/invoke.texi (-fprofile-arcs, -ftest-coverage): Update
+ documentation missed from my 2003-07-09 patch.
+
+2003-07-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * aclocal.m4 (_gcc_COMPUTE_GAS_VERSION): Set patch level to 0 if
+ it's not provided.
+ * configure: Rebuild.
+
+2003-07-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c/10602
+ * c-typeck.c (type_lists_compatible_p): Do not compare
+ arguments if one of them is an error_mark_node
+
+2003-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Save fp regs inline
+ if current_function_calls_eh_return.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/c-tree.texi (OFFSET_TYPE): Update description.
+
+2003-07-23 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/crti.asm (_init, _fini): Increase frame size to 64.
+ * config/xtensa/lib1funcs.asm (__mulsi3, __udivsi3, __divsi3,
+ __umodsi3, __modsi3): Increase frame size to 32.
+
+2003-07-23 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/host-darwin.c: ANSIfy, update comment for sigaltstack
+ prototype.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/c-tree.texi (Types): Update documentation for OFFSET_TYPE.
+
+ PR optimization/10679
+ * tree-inline.c (inlinable_function_p): Honor MIN_INLINE_INSNS.
+
+2003-07-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/11607 and PR target/11516
+ * pa.md (extzv, extv, insv): Revert latter half of last patch.
+
+2003-07-22 Mark Mitchell <mark@codesourcery.com>
+
+ * fold-const.c (force_fit_type): Handle OFFSET_TYPE.
+ * varasam.c (output_constant): Likewise.
+
+2003-07-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Fix comment formatting.
+ * c-common.c: Likewise.
+ * c-decl.c: Likewise.
+ * c-opts.c: Likewise.
+ * combine.c: Likewise.
+ * cpplib.c: Likewise.
+ * diagnostic.c: Likewise.
+ * dojump.c: Likewise.
+ * final.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcc.c: Likewise.
+ * gcse.c: Likewise.
+ * ggc-page.c: Likewise.
+ * jump.c: Likewise.
+ * loop.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * recog.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+
+2003-07-22 Per Bothner <pbothner@apple.com>
+
+ * line-map.c (add_line_map): Handle invalid LEAVE request.
+ Fixes PR preprocessor/11361.
+
+2003-07-22 Per Bothner <pbothner@apple.com>
+
+ * diagnostic.c.(diagnostic_report_current_module): Update to match
+ 2003-06-05 changes to push_srcloc and pop_srcloc.
+
+2003-07-22 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/trouble.texi: Better document two-stage name lookup.
+
+2003-07-22 Eric Christopher <echristo@redhat.com>
+
+ * config/s390.c (s390_valid_pointer_mode): New.
+ (TARGET_VALID_POINTER_MODE): Use.
+ (s390_emit_prologue): Add tpf profiling hooks.
+ (s390_emit_epilogue): Ditto.
+ * config/s390.h (MASK_TPF): New.
+ (TARGET_TPF): Use.
+ (POINTERS_EXTEND_UNSIGNED): Define.
+ * config/s390.md (ptr_extend): New pattern.
+
+2003-07-22 Zack Weinberg <zack@codesourcery.com>
+
+ * hashtable.c (approx_sqrt): Make static.
+ * hashtable.h: Don't prototype approx_sqrt.
+ * line-map.c (init_line_maps): Rename linemap_init.
+ (free_line_maps): Rename linemap_free.
+ (add_line_map): Rename linemap_add.
+ (lookup_line): Rename linemap_lookup.
+ (print_containing_files): Rename linemap_print_containing_files.
+ * linemap.h: Update to match.
+
+ * cpperror.c, cppinit.c, cpplib.c, cppmacro.c: Update calls to
+ linemap routines to use new names.
+
+2003-07-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-common.c (handle_packed_attribute): Don't pack a struct via a
+ typedef. Propagate packedness from a main variant.
+
+2003-07-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in (install-common): Add dependency on installdirs.
+
+2003-07-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-common.c (c_common_type_for_mode): Return integer types for
+ pointer modes.
+
+2003-07-22 Geoffrey Keating <geoffk@apple.com>
+
+ * c-decl.c (start_decl): Don't call maybe_apply_pragma_weak here.
+ (finish_decl): Call maybe_apply_pragma_weak here.
+ (grokdeclarator): Check that DECL_ASSEMBLER_NAME isn't set before
+ TREE_PUBLIC and TREE_STATIC are decided.
+ (start_function): Move call to maybe_apply_pragma_weak. Check that
+ DECL_ASSEMBLER_NAME isn't set too early.
+
+ * cpplex.c (_cpp_process_line_notes): Mention option name in
+ trigraphs warning.
+
+2003-07-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (if_then_else_cond): Simplify the comparison of
+ rtx against -1, 0, and 1.
+ * loop.c (check_dbra_loop): Likewise.
+ * optabs.c (emit_conditional_move): Likewise.
+ (emit_conditional_add): Likewise.
+ * config/i386/i386.md (*movsi_or): Likewise.
+ (*movdi_or_rex6): Likewise.
+
+2003-07-22 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Remove redundant if.
+
+2003-07-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (open_file_pch): Don't put unused entries in the
+ splay tree. Remove dead code.
+
+2003-07-21 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.h (num_in_fnames): Declare.
+ (c_static_assembler_name): Move from here...
+ * c-tree.h (c_static_assembler_name): ... to here.
+ * c-opts.c: Don't include langhooks-def.h.
+ (c_static_assembler_name): Move to c-decl.c.
+ (num_in_fnames): Make externally visible.
+ * c-decl.c: Include langhooks-def.h.
+ (c_static_assembler_name): Move from c-opts.c.
+ * Makefile.in (c-decl.o): Add $(LANGHOOKS_DEF_H).
+ (c-opts.o): Remove $(LANGHOOKS_DEF_H).
+
+ * c-pragma.c (maybe_apply_pragma_weak): Don't get DECL_ASSEMBLER_NAME
+ when it's not needed.
+
+2003-07-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.h (machine_function): Add ra_need_lr.
+ * config/rs6000/rs6000.c (rs6000_return_addr): Set it.
+ (rs6000_emit_prologue): Save FPRs inline if set.
+
+2003-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/ia64/ia64.md (prefetch): Support predicate.
+
+2003-07-21 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgcleanup.c (merge_blocks_move_successor_nojumps): Use tablejump_p.
+ * rtlanal.c (tablejump_p): Use next_active_insn for finding the jump
+ table.
+
+2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11536
+ * unroll.c (loop_iterations): Do not replace a register holding
+ the final value by its equivalent before the loop if it is not
+ invariant.
+
+2003-07-21 Dave Fluri <dave.fluri@onlink.net>
+
+ * doc/extend.texi: Fixes to spelling, grammar, and diction.
+
+2003-07-21 Ben Elliston <bje@wasabisystems.com>
+
+ * doc/invoke.texi (Optimize Options): Replace "it's" with "its".
+ (V850 Options): Spelling fixes.
+
+2003-07-20 Lisa M. Goldstein <opus@gnu.org>
+
+ * doc/invoke.texi: Fixes to style, grammar and diction.
+
+2003-07-20 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (BUILT_IN_ALLOCA): Remove "#if SMALL_STACK" form.
+ * system.h (SMALL_STACK): Poison obsolete target macro.
+ * doc/tm.texi (SMALL_STACK): Remove target macro documentation.
+
+2003-07-20 Phil Edwards <pme@gcc.gnu.org>
+
+ * configure.in: Cache the results of testing for cmp's capabilities.
+ * configure: Regenerate.
+
+2003-07-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/11279
+ * dwarf2out.c (gen_enumeration_type_die): Remember that
+ enumerators can be unsigned.
+
+2003-07-19 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (named_labels, shadowed_labels, label_level_chain)
+ (push_label_level, pop_label_level): Kill.
+ (struct binding_level): Rename level_chain to outer.
+ Add outer_function field. Change parm_flag, function_body,
+ keep, keep_if_subblocks to 1-bit bitfields of type bool.
+ (current_function_level): New variable.
+ (keep_next_level_flag, keep_next_if_subblocks): Change type to bool.
+ (keep_next_level, declare_parm_level, warn_if_shadowing):
+ Update to match.
+ (struct language_function): Kill named_labels, shadowed_labels fields.
+ (c_init_decl_processing, start_function, c_push__function_context)
+ (c_pop_function_context): No need to muck with named_labels nor
+ shadowed_labels.
+
+ (make_binding_level): No need to clear the structure here.
+ (pop_binding_level): Always operate on current_binding_level.
+ Update current_function_level if necessary.
+ (pushlevel): Don't clear named_labels. Update current_function_level
+ if necessary. Use "true" and "false" where appropriate.
+ (poplevel): Diagnose labels defined but not used, or vice
+ versa, and clear out label-meanings leaving scope, while
+ walking down the decls list, for all binding levels.
+ Handle LABEL_DECLs appearing in the shadowed list.
+ pop_binding_level takes no arguments.
+ (pushdecl_function_level): Use current_function_level.
+
+ (make_label, bind_label): New static functions.
+ (declare_label): New exported function.
+ (lookup_label, define_label): Rewritten for new data structure.
+ (shadow_label): Kill.
+
+ * c-tree.h: Prototype declare_label; don't prototype
+ push_label_level, pop_label_level, nor shadow_label.
+ * c-parse.in: Remove all calls to push_label_level and
+ pop_label_level. Use declare_label for __label__ decls.
+
+ * doc/extend.texi: Clarify that __label__ can be used to
+ declare labels with local scope in any nested block, not
+ just statement expressions. Cross-reference nested functions
+ section from local labels section.
+
+2003-07-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * sched-rgn.c (find_rgns): Initialize current_edge correctly.
+
+2003-07-19 Phil Edwards <pme@gcc.gnu.org>
+
+ * doc/makefile.texi (restrap, profiledbootstrap): Document targets.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fixinc/fixfixes.c fixinc/fixincl.c fixinc/fixlib.c
+ fixinc/server.c objc/objc-act.c: Remove unnecessary casts.
+
+2003-07-19 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (legitimize_pic_address): Access local symbols
+ relative to the GOT instead of relative to the literal pool base.
+ (s390_output_symbolic_const): Handle new GOT-relative accesses.
+ * config/s390/s390.md ("call"): Access local functions and PLT stubs
+ relative to the GOT instead of relative to the literal pool base.
+ ("call_value"): Likewise.
+ ("call_value_tls"): Likewise.
+
+ * config/s390/s390.c (s390_chunkify_start): Remove pool anchor
+ reloading. Support LTREL_BASE / LTREL_OFFSET construct.
+ (s390_chunkify_finish): Likewise.
+ (s390_chunkify_cancel): Likewise.
+ (s390_reorg): Adapt caller.
+ (find_base_register_in_addr,
+ find_base_register_ref, replace_base_register_ref): Delete.
+ (find_ltrel_base, replace_ltrel_base): New functions.
+ (find_constant_pool_ref): Handle LTREL_BASE unspecs.
+ (s390_decompose_address): Handle LTREL_BASE unspecs. Optimize
+ base vs. index register usage.
+ (struct constant_pool): Remove 'anchor'.
+ (s390_add_anchor): Delete.
+ (s390_dump_pool): Remove anchor handling.
+ * config/s390/s390.md ("reload_anchor"): Remove.
+
+ * config/s390/s390.c (s390_split_branches): Use LTREL_BASE/OFFSET.
+ (s390_load_got): New function. Use LTREL_BASE/OFFSET.
+ (s390_emit_prologue): Use it.
+ * config/s390/s390.md ("builtin_longjmp", "builtin_setjmp_setup",
+ "builtin_setjmp_receiver"): Cleanup. Use s390_load_got. Do not
+ hard-code register 14.
+ * config/s390/s390-protos.h (s390_load_got): Declare.
+
+ * config/s390/s390.c (NR_C_MODES, constant_modes, gen_consttable):
+ Support TImode constants.
+ * config/s390/s390.md ("consttable_ti"): New.
+ ("consttable_si", "consttable_di"): Handle TLS symbols correctly.
+
+ * config/s390/s390.md (UNSPEC_LTREL_OFFSET, UNSPEC_LTREL_BASE,
+ UNSPEC_GOTENT, UNSPEC_GOT, UNSPEC_GOTOFF, UNSPEC_PLT, UNSPEC_PLTOFF,
+ UNSPEC_RELOAD_BASE, UNSPECV_POOL, UNSPECV_POOL_START, UNSPECV_POOL_END,
+ UNSPECV_POOL_QI, UNSPECV_POOL_HI, UNSPECV_POOL_SI, UNSPECV_POOL_DI,
+ UNSPECV_POOL_TI, UNSPECV_POOL_SF, UNSPECV_POOL_DF, UNSPECV_MAIN_POOL):
+ New symbolic constants.
+ ("consttable_qi", "consttable_hi", "consttable_si", "consttable_di",
+ "consttable_sf", "consttable_df", "pool_start_31", "pool_end_31",
+ "pool_start_64", "pool_end_64", "reload_base_31", "reload_base_64",
+ "pool", "literal_pool_31", "literal_pool_64"): Cleanup. Use
+ symbolic UNSPEC values.
+ * config/s390/s390.c (larl_operand, s390_short_displacement,
+ bras_sym_operand, s390_cannot_force_const_mem,
+ s390_delegitimize_address, s390_decompose_address,
+ legitimize_pic_address, s390_output_symbolic_const,
+ s390_function_profiler): Use symbolic UNSPEC values.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alias.c alloc-pool.c bitmap.c bitmap.h bt-load.c builtins.c
+ c-common.c c-decl.c c-incpath.c c-lex.c c-opts.c c-parse.in
+ c-pragma.c c-typeck.c calls.c cfg.c cfganal.c cfgloop.c cfgrtl.c
+ collect2.c combine.c conflict.c coverage.c cppexp.c cppfiles.c
+ cpphash.c cppinit.c cpplex.c cpplib.c cppmacro.c cppspec.c
+ cpptrad.c cse.c cselib.c dbxout.c defaults.h df.c dominance.c
+ dwarf2out.c dwarfout.c emit-rtl.c except.c expmed.c expr.c final.c
+ fix-header.c flow.c fold-const.c function.c gcc.c gccspec.c gcov.c
+ gcse.c genattr.c genattrtab.c genautomata.c genconditions.c
+ genemit.c genextract.c genoutput.c genrecog.c gensupport.c
+ ggc-page.c ggc-simple.c global.c graph.c haifa-sched.c hashtable.c
+ integrate.c jump.c langhooks.c lcm.c line-map.c local-alloc.c
+ loop.c mips-tdump.c mips-tfile.c mkdeps.c optabs.c params.c
+ postreload.c prefix.c print-tree.c protoize.c ra-build.c
+ ra-colorize.c ra-rewrite.c ra.c recog.c reg-stack.c regclass.c
+ regmove.c regrename.c reload.c reload1.c reorg.c resource.c
+ sbitmap.c sched-deps.c sched-rgn.c sched-vis.c sdbout.c
+ simplify-rtx.c ssa-ccp.c ssa.c stmt.c stor-layout.c timevar.c
+ tlink.c toplev.c tree-dump.c tree.c unroll.c unwind-dw2-fde.c
+ varasm.c varray.c vmsdbgout.c xcoffout.c: Remove unnecessary
+ casts.
+
+2003-07-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pragma.c (apply_pragma_weak): Don't use warning_with_decl.
+ * toplev.h (warning): Remove attribute.
+
+2003-07-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-decl.c (c_finish_incomplete_decl): Don't use xxx_with_decl.
+ (pop_label_level): Likewise.
+ (duplicate_decls): Likewise.
+ (implicitly_declare): Likewise.
+ (shadow_label): Likewise.
+ (start_decl): Likewise.
+ (finish_decl): Likewise.
+ (grokdeclarator): Likewise.
+ (get_parm_info): Likewise.
+ (detect_field_duplicates): Likewise.
+ (finish_struct): Likewise.
+ (start_function): Likewise.
+ (store_parm_decls): Likewise.
+ (finish_function): Likewise.
+ (c_expand_body_1): Likewise.
+ (check_for_loop_decls): Likewise.
+ (merge_translation_unit_decls): Likewise.
+
+2003-07-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: Document --param.
+ * opts.c (columns, undocumented_msg): New.
+ (print_help): Get number of columns from environment. Print
+ --param help. Tweak newline handling.
+ (print_param_help): New.
+ (print_filtered_help): Better handling of duplicates. Complain
+ about undocumented switches.
+ (print_switch): New.
+ (wrap_help): Improve wrapping, use COLUMNS.
+ * opts.sh: Ignore comments in records.
+ * params.def: Fix typos and remove trailing periods.
+ * toplev.c (display_help): Don't dump --param help.
+ * doc/sourcebuild.texi: Update.
+
+2003-07-18 Richard Henderson <rth@redhat.com>
+
+ PR target/11556
+ * optabs.c (prepare_operand): Fail gracefully instead of abort
+ if the predicate doesn't satisfy.
+ (gen_cond_trap): Allow prepare_operand to fail.
+
+2003-07-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-common.c: Don't undefine GCC_DIAG_STYLE.
+ (fname_decl): Don't use xxx_with_decl.
+ (c_add_case_label): Likewise.
+ (handle_section_attribute): Likewise.
+ (handle_alias_attribute): Likewise.
+ (handle_no_instrument_function_attribute): Likewise.
+ (handle_no_limit_stack_attribute): Likewise.
+ * c-objc-common.c (c_tree_printer): Print IDENTIFIER_NODEs.
+ * c-format.c (gcc_cdiag_char_table): Add '%E' format-specifier.
+
+2003-07-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (ifcvt.o): Add cfgloop.h.
+ * basic-block.h (EDGE_LOOP_EXIT): New flag.
+ * cfgrtl.c (rtl_verify_flow_info_1): Handle it correctly.
+ * ifcvt.c: Include cfgloop.h.
+ (mark_loop_exit_edges): New static function.
+ (if_convert): Call it.
+ (find_if_header): Ignore branches out of loops.
+
+2003-07-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison): Don't share rtx when converting
+ (ne (and (not X) 1) 0) to (eq (and X 1) 0).
+
+2003-07-18 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix.h (AGGREGATE_PADDING_FIXED): Define.
+ (AGGREGATES_PAD_UPWARD_ALWAYS): Define.
+ (MUST_PASS_IN_STACK): Define.
+ (BLOCK_REG_PADDING): Define.
+
+2003-07-18 Richard Henderson <rth@redhat.com>
+
+ * cfgrtl.c (force_nonfallthru_and_redirect): Use tablejump_p
+ to skip the addr_vec.
+
+2003-07-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * combine.c (combinable_i3pat): Don't forbid occurrences of
+ i2dest or i1dest in inner_dest if inner_dest is a mem.
+
+2003-07-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_remove_node): Clear the hash table slot.
+
+2003-07-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/11087
+ * loop.c (basic_induction_var): Check if convert_modes emitted any
+ instructions. Remove them and return 0 if so.
+
+2003-07-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11083
+ * toplev.c (rest_of_handle_addresof): Rename into
+ rest_of_handle_addressof. Delete unreachable blocks
+ if dead edges were purged after the addressof pass.
+
+2003-07-18 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in, configure, configure.in: Remove handling of
+ lang-options.h and options_.h.
+ * toplev.c (struct lang_opt, documented_lang_options): Remove.
+ (display_help): Don't use documented_lang_options.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (pushdecl_function_level): Make static, return nothing.
+ (kept_level_p): Fold into poplevel.
+ (undeclared_variable): Moved here from c-typeck.c. Export.
+ * c-tree.h (KEEP_YES, KEEP_NO, KEEP_MAYBE): New #defines.
+ (undeclared_variable): Prototype here. Don't prototype
+ kept_level_p nor pushdecl_function_level.
+ * c-parse.in: Change first argument to poplevel from
+ "kept_level_p()" to "KEEP_MAYBE".
+ * c-typeck.c (undeclared_variable): Moved to c-decl.c.
+
+2003-07-17 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_rtx): Use simplify_gen_binary to swap
+ commutative operands instead of modifying the RTL in-place.
+
+2003-07-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR optimization/11557
+ * calls.c (flags_from_decl_or_type): Do not set ECF_LIBCALL_BLOCK
+ unless we know which function is being called.
+
+2003-07-17 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (fold_rtx): Use swap_commutative_operands_p to determine
+ whether to reorder the operands of a commutative binary operator.
+
+2003-07-17 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (const_binop): Avoid performing the FP operation at
+ compile-time, if either operand is NaN and we honor signaling NaNs,
+ or if we're dividing by zero and either flag_trapping_math is set
+ or the desired mode doesn't support infinities.
+ (fold_initializer): New function to fold an expression ignoring any
+ potential run-time exceptions or traps.
+ * tree.h (fold_initializer): Prototype here.
+ * c-typeck.c (build_binary_op): Move to the end of the file so
+ that intializer_stack is in scope. If constructing an initializer,
+ i.e. when initializer_stack is not NULL, use fold_initializer to
+ fold expressions.
+ * simplify-rtx.c (simplify_binary_operation): Likewise, avoid
+ performing FP operations at compile-time, if they would raise an
+ exception at run-time.
+
+2003-07-17 Geoffrey Keating <geoffk@apple.com>
+
+ PR 11498
+ * Makefile.in (c-opts.o): Add $(LANGHOOKS_DEF_H).
+ (langhooks.o): Add $(GGC_H), gt-langhooks.h.
+ (GTFILES): Add langhooks.c.
+ (gt-langhooks.h): New.
+ * c-common.h (c_static_assembler_name): Prototype.
+ * c-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Define.
+ * objc/objc-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Define.
+ * c-opts.c: Include langhooks-def.h.
+ (c_static_assembler_name): New.
+ * langhooks.c: Include ggc.h. Include gt-langhooks.h.
+ (var_labelno): New.
+ (lhd_set_decl_assembler_name): Give static objects with context
+ unique names.
+ * varasm.c (var_labelno): Delete.
+ (make_decl_rtl): Don't change the assembler name once it's set.
+
+ * c-opts.c (this_input_filename): New.
+ (finish_options): Take new parameter, name of file being compiled.
+ Update callers. Set this_input_filename.
+ (push_command_line_include): Use this_input_filename not
+ main_input_filename.
+
+2003-07-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Depend .pot generation on options.c.
+ * po/exgettext: Add an extra_files variable containing additional
+ files to scan.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * objc/objc-lang.c: Override LANG_HOOKS_WRITE_GLOBALS to
+ c_write_global_declarations.
+
+ * c-decl.c: Fix typos in several comments. Remove all
+ #if 0 blocks; reindent as needed. Remove unused argument
+ to declare_parm_level; all callers changed.
+ * c-parse.in: Update calls to declare_parm_level. Avoid
+ issuing a double warning in some circumstances.
+ * c-typeck.c: Update calls to declare_parm_level.
+ * c-tree.h: Update prototype of declare_parm_level.
+
+ * c-pragma.c (apply_pragma_weak): Don't complain about a
+ redundant #pragma weak.
+
+ * objc/objc-act.c (forward_declare_categories,
+ build_selector_reference_decl, build_class_reference_decl,
+ build_objc_string_decl, synth_forward_declarations,
+ build_protocol_reference): Set TREE_PUBLIC on synthetic
+ forward decl to 0, consistent with eventual definition.
+ Correct comments to match.
+
+ * fixinc/inclhack.def (solaris_mutex_init_2): Escape braces
+ in regexp that don't form a range expression.
+ * fixinc/fixincl.def: Regenerate.
+
+2003-07-17 Richard Henderson <rth@redhat.com>
+
+ PR target/10907
+ * config/ia64/ia64.c (ia64_epilogue_uses): GP is live at end
+ even with !TARGET_CONST_GP.
+ (ia64_function_ok_for_sibcall): Reject non-local functions.
+
+2003-07-17 Steven Bosscher <steven@gcc.gnu.org>
+
+ * c-common.c (c_estimate_num_insns_1): Don't handle
+ METHOD_CALL_EXPR.
+ * expr.c (safe_from_p): Likewise.
+ * gengtype.c (adjust_field_tree_exp): Likewise.
+ * stmt.c (warn_if_unused_value): Likewise
+ * tree.c (first_rtl_op): Likewise.
+ * tree.def: Don't define METHOD_CALL_EXPR.
+ * java/lang.c (java_estimate_num_insns_1): Don't handle
+ METHOD_CALL_EXPR.
+
+2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR other/11466
+ * doc/invoke.texi (SPARC Options): Document "-mlittle-endian"
+ and its restrictions for the SPARC64 port.
+ Move the entry of "-mimpure-text" before that of "-mv8".
+
+2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Phil Edwards <phil@jaj.com>
+
+ * doc/install.texi (*-*-solaris2*): Document the step-by-step
+ procedure to bootstrap and install.
+ Document the preference for the legacy Sun tools in /usr/bin
+ over the POSIX tools in /usr/xpg4/bin for the build process.
+
+2003-07-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * c.opt: Document Uncodumented; use it. Document ObjC options.
+ * opts.c (print_filtered_help): Skip undocumented switches.
+ * opts.h (CL_UNDOCUMENTED): New.
+ * opts.sh: Handle Undocumented.
+ * toplev.c (documented_lang_options): Prevent its becoming empty.
+objc:
+ * lang-options.h: Remove.
+
+2003-07-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * loop.c (check_ext_dependent_givs): Pass const struct loop *
+ instead of struct loop_info * as argument. Accept BIVs with
+ increment +/- 1 provided there is a friendly exit test against
+ a loop-invariant value.
+ (strength_reduce): Adapt call to check_ext_dependent_givs.
+
+2003-07-16 J"orn Rennecke <joern.rennecke@superh.com>
+ Con Bradley <con.bradley@superh.com>
+
+ * sh-protos.h (sh_get_pr_initial_val): Declare.
+ * sh.c (regno_reg_class): Make its elements type enum reg_class.
+ (output_stack_adjust): Remove emit_fn argument. Add epilogue_p
+ and live_regs_mask arguments. Changed all callers.
+ (save_schedule_s): New structure.
+ (save_schedule): New typedef.
+ (scavenge_reg, sh5_schedule_saves, sh5_schedule_saves): New functions.
+ (calc_live_regs): For TARGET_SHMEDIA, use leaf_function_p.
+ In interrupts handlers, also save registers that are usually
+ partially saved, and make sure there is at least one general purpose
+ register saved if a target register needs saving.
+ Add casts in comparisons to avoid warnings.
+ (sh_media_register_for_return): return -1 for interrupt handlers.
+ (MAX_SAVED_REGS, MAX_TEMPS): New defines.
+ (sh_expand_prologue): Use sh5_schedule_saves. Check that any temp
+ registers used are available.
+ Set RTX_FRAME_RELATED_P where appropriate.
+ Add an REG_FRAME_RELATED_EXPR for r0 + offset addressing.
+ (sh_expand_epilogue, sh_set_return_address): Use sh5_schedule_saves.
+ (initial_elimination_offset): Likewise.
+ * sh.h (DWARF_CIE_DATA_ALIGNMENT): Set to -4.
+ (LOCAL_ALIGNMENT, GENERAL_REGISTER_P): Add casts to avoid warnings.
+ (FP_REGISTER_P): Add casts to fix broken handling of unsigned REGNO.
+ (XD_REGISTER_P, TARGET_REGISTER_P): Likewise.
+ (HARD_REGNO_CALL_PART_CLOBBERED): Also yield nonzero for r15,
+ and for target registers.
+ (RETURN_IN_MEMORY): Add parentheses to avoid warnings.
+ (regno_reg_class): Make its elements type enum reg_class.
+ (CONSTRAINT_LEN): Don't use isdigit.
+ (FUNCTION_ARG_REGNO_P): Add casts to avoid warnings.
+ (FUNCTION_ARG): Add parentheses to avoid warnings.
+ (RETURN_ADDR_RTX): Use sh_get_pr_initial_val.
+ (RETURN_ADDR_OFFSET): Define to -1 for TARGET_SH5.
+ (SH_DBX_REGISTER_NUMBER): Add casts to avoid warnings.
+ (EH_RETURN_DATA_REGNO): Use unsigned constants to avoid warnings.
+ * sh.md (xordi3+1): Remove unused variable regno.
+ (return_media): Check that tr0 is available before using it.
+
+2003-07-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * c.opt: Document more options.
+
+2003-07-16 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (subst): Also handle (subreg (const_double ...)) case
+ if created by a substitution, by using the original inner mode.
+
+2003-07-16 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_replace_rtx): Convert constant comparisons
+ to MODE_FLOAT constants if FLOAT_STORE_FLAG_VALUE is defined.
+ (simplify_rtx): Likewise. Simplify (lo_sum (high X) X) as X.
+
+2003-07-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * doc/install.texi (--without-headers): New.
+
+ Partial Fix PR/10129
+ * config/darwin.c (machopic_function_base_name): Only Return "<pic base>".
+ (machopic_output_function_base_name): New; print the true pic label.
+ (machopic_classify_ident): Pic Base is always a defined data.
+ * config/darwin.h (ASM_OUTPUT_LABELREF): Support the pic base label.
+ * config/darwin-proto.h (machopic_output_function_base_name): Prototype.
+
+ * gcse.c (gcse_constant_p): COMPARE of the same registers is a constant
+ if they are not floating point registers.
+
+ PR c/10962
+ * ggc.h: Add header guards.
+ * c-decl.c (finish_struct): Sort fields if
+ number greater than 15 and there are no
+ anonymous structs/unions.
+ * c-common.h: Include ggc.h.
+ (sorted_fields_type): New struct.
+ (field_decl_cmp): New prototype.
+ (resort_sorted_fields): New prototype.
+ (DECL_DECLARES_TYPE_NON_TEMPLATE_P): New macro.
+ * c-tree.h: (lang_type): Use pointer to sorted_fields_type
+ as s, removing other fields.
+ * c-typeck.c (lookup_field): Use s in lang_type.
+ These were mostly moved from cp/class.c:
+ * c-common.c (field_decl_cmp): New static function.
+ (field_decl_cmp): New function.
+ (resort_sorted_fields): New function.
+
+2003-07-16 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.c (machopic_select_section): Use decl_readonly_section
+ to do most of the work.
+
+2003-07-16 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix-protos.h: Convert prototypes to ISO C90.
+ * config/mmix/mmix.c: Convert functions to ISO C90.
+ (mmix_eh_return_handler_rtx, mmix_output_shifted_value): Tweak
+ formatting.
+ (mmix_get_hard_reg_initial_val): Tweak section head comment.
+
+2003-07-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * c-pragma.h (HANDLE_PRAGMA_WEAK): Always define to SUPPORTS_WEAK.
+
+2003-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * unwind-dw2.c (MD_FROB_UPDATE_CONTEXT): Define.
+ (uw_update_context_1): Use it.
+ * config/rs6000/rs6000.c (insn_after_throw): Remove.
+ (rs6000_aix_emit_builtin_unwind_init): Save $r2 to its location
+ in parent frame if _Unwind_* called directly instead of through
+ .plt.
+ (rs6000_emit_eh_toc_restore): Remove.
+ (rs6000_emit_prologue): Update stack pointer before doing any saving
+ if current_function_calls_eh_return. Generate unwind info for $r2.
+ (rs6000_emit_epilogue): Restore stack pointer after doing all
+ restoring if current_function_calls_eh_return. Restore $r2.
+ * config/rs6000/rs6000-protos.h (rs6000_emit_eh_toc_restore): Remove.
+ * config/rs6000/rs6000.md (eh_return): Remove call to
+ rs6000_emit_eh_toc_restore.
+ * config/rs6000/linux64.h (MD_FROB_UPDATE_CONTEXT): Define.
+ * config/rs6000/aix.h (MD_FROB_UPDATE_CONTEXT): Define.
+
+2003-07-15 Jakub Jelinek <jakub@redhat.com>
+
+ * expr.c (emit_block_move): Don't move anything if size is const 0.
+ (clear_storage): Test against const0_rtx instead of comparing INTVAL
+ against 0.
+
+2003-07-15 David S. Miller <davem@redhat.com>
+
+ * config/sparc/sparc.c (sparc_nonflat_function_epilogue): Only
+ emit nop if the last real insn is CALL_INSN.
+
+2003-07-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/xm-mingw32.h (HOST_BIT_BUCKET): Define
+ as "nul".
+ * config/i386/xm-mingw32.h: Change GNU CC to GCC.
+
+2003-07-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (associated_type): Artificial methods are not
+ affected by the import/export status of their class unless they are
+ COMDAT.
+ (i386_pe_dllimport_p): Do not mark artificial methods as dllimport.
+
+ * config/i386/winnt.c: Fix GCC copyright comment.
+
+2003-07-16 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ PR c++/11531
+ * diagnostic.c (diagnostic_report_diagnostic): Don't ICE if we're
+ not recursing on hard error.
+ (diagnostic_for_decl): Likewise.
+ * diagnostic.def: Rearrange.
+
+2003-07-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes):
+ If DWARF_FRAME_RETURN_COLUMN doesn't have a register mode, use Pmode.
+
+2003-07-15 J"orn Rennecke <joern.rennecke@superh.com>
+ Richard Henderson <rth@redhat.com>
+
+ * unwind-dw2.c (_Unwind_GetGR): Use dwarf_reg_size_table
+ to decide if to access a _Unwind_Ptr or a _Unwind_Word.
+ (_Unwind_SetGR): Likewise.
+ (_Unwind_GetPtr, _Unwind_SetSpColumn): New functions.
+ (Unwind_SpTmp): New typedef.
+ (uw_update_context_1): Use _Unwind_SetSpColumn and _Unwind_GetPtr.
+ (uw_update_context): Use _Unwind_GetPtr.
+ (init_dwarf_reg_size_table): Move above uw_init_context_1.
+ (uw_init_context_1): Initialize dwarf_reg_size_table if necessary.
+ Use _Unwind_SetSpColumn.
+ (uw_install_context_1): Don't initialize dwarf_reg_size_table.
+ Use _Unwind_GetPtr.
+
+2003-07-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * c.opt: Document more options.
+ * toplev.c (documented_lang_options): Remove all local help strings.
+
+2003-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/11473
+ * dbxout.c (dbxout_type): Use TYPE_SIZE to determine the sizes of
+ base classes.
+
+2003-07-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/10795
+ * config/i386/i386.c (ix86_expand_carry_flag_compare): Don't
+ swap comparison operands if doing so would generate an
+ unrecognizable insn.
+
+2003-07-15 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11320
+ * sched-int.h (struct deps) [reg_conditional_sets]: New field.
+ (struct sched_info) [compute_jump_reg_dependencies]: New prototype.
+ * sched-deps.c (sched_analyze_insn) [JUMP_INSN]: Update call to
+ current_sched_info->compute_jump_reg_dependencies. Record which
+ registers are used and which registers are set by the jump.
+ Clear deps->reg_conditional_sets after a barrier.
+ Set deps->reg_conditional_sets if the insn is a COND_EXEC.
+ Clear deps->reg_conditional_sets if the insn is not a COND_EXEC.
+ (init_deps): Initialize reg_conditional_sets.
+ (free_deps): Clear reg_conditional_sets.
+ * sched-ebb.c (compute_jump_reg_dependencies): New prototype.
+ Mark registers live on entry of the fallthrough block and conditionally
+ set as set by the jump. Mark registers live on entry of non-fallthrough
+ blocks as used by the jump.
+ * sched-rgn.c (compute_jump_reg_dependencies): New prototype.
+ Mark new parameters as unused.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Resync MIPS -march documentation.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R9000): New processor_type.
+ (TARGET_MIPS9000, TUNE_MIPS9000): New macros.
+ (GENERATE_MULT3_SI): True for TARGET_MIPS9000.
+ * config/mips/mips.c (mips_cpu_info_table): Add rm9000 entry.
+ (mips_rtx_costs): Adjust integer multiplication costs for the rm9000.
+ (mips_issue_rate): Handle PROCESSOR_R9000.
+ (mips_use_dfa_pipeline_interface): Likewise.
+ * config/mips/9000.md: New file.
+ * config/mips/mips.md: Include it.
+ (define_attr cpu): Add r9000.
+ (mulsi3_mult3): Use "mul" for rm9000 code.
+
+2003-07-15 Stan Cox <scox@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R7000): New processor_type.
+ (TARGET_MIPS7000, TUNE_MIPS7000): New macros.
+ (GENERATE_MULT3_SI): True for TARGET_MIPS7000.
+ * config/mips/mips.c (mips_cpu_info_table): Add rm7000 entry.
+ (mips_rtx_costs): Adjust integer multiplication costs for the rm7000.
+ (mips_issue_rate): Handle PROCESSOR_R7000.
+ (mips_use_dfa_pipeline_interface): Likewise.
+ * config/mips/7000.md: New file.
+ * config/mips/mips.md: Include it.
+ (define_attr cpu): Add r7000.
+ (mulsi3_mult3): Use "mul" for rm7000 code.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (define_attr type): Add condmove. Use it for
+ the conditional move patterns.
+ * config/mips/5400.md (ir_vr54_move): Rename to ir_vr54_condmove.
+ Check for condmove type.
+ (ir_vr54_arith): Add move type.
+ * config/mips/5500.md (ir_vr55_move, ir_vr55_arith): Likewise.
+ * config/mips/sr71k.md (ir_sr70_move, ir_sr70_arith): Likewise.
+
+2003-07-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (print_help): Remove.
+ (c_common_handle_option): Don't handle --help.
+ * c.opt: Document some options.
+ (--help): Remove.
+ * opts.c (print_filtered_help): New.
+ (print_help): Use it.
+
+2003-07-14 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.c (c_common_type_for_mode): Handle V4DFmode.
+ * tree.c: (build_common_tree_nodes_2): Likewise.
+ * tree.h (enum tree_index): Add TI_V4DF_TYPE.
+ (V4DF_type_node): New.
+
+ * c-opts.c (push_command_line_include): Don't free deferred_opts,
+ we'll need it.
+ (finish_options): Reset init_cursor.
+
+2003-07-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c (expand_assignment): Remove an unused argument
+ SUGGEST_REG.
+ * expr.h: Update the prototype.
+ * function.c: Update the callers.
+ * stmt.c: Likewise.
+
+2003-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/11098
+ * integrate.c (copy_decl_for_inlining): Do not mark copied decls
+ as DECL_ABSTRACT.
+
+2003-07-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (avoid_bool_define, avoid_bool_type): Bypass
+ with __cplusplus, not "we must use the C++ compiler's type"
+ * fixinc/inclhack.def (void_null): Note that Interix needs this.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-07-14 Geoffrey Keating <geoffk@apple.com>
+
+ * unwind-dw2-fde-darwin.c (live_image_destructor): Get seen_objects
+ and unseen_objects from the global data before calling
+ __deregister_frame_info_bases.
+ (examine_objects): Insert objects into the seen_objects list,
+ not unseen_objects.
+ (_Unwind_Find_FDE): Always unlock the global object lists, even if
+ we couldn't allocate a data structure to put in it.
+
+ * objc/objc-act.h (CLASS_SUPER_NAME): Add a little typechecking.
+ (TYPE_PROTOCOL_LIST): Share use of type.context with C frontend.
+ (SET_TYPE_PROTOCOL_LIST): New.
+ * objc/objc-act.c (get_static_reference): Use SET_TYPE_PROTOCOL_LIST.
+ (get_object_reference): Likewise.
+
+2003-07-14 Jan Hubicka <jh@suse.cz>
+
+ * cfglayout.c (locator_file): Break out from ....
+ (insn_file): ... here.
+ (locator_line): Break out from ....
+ (insn_line): ... here.
+ * rtl.h (locator_file, locator_line): Declare.
+ (final_start_function): Set proper line/file info.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.c (pp_c_unary_expression): A CONVERT_EXPR is
+ handled by pp_c_cast_expression.
+
+2003-07-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_prologue): Use a single insn to
+ allocate 32768 bytes of stack. Use addition rather than subtraction
+ when a single insn is enough.
+ * config/mips/mips.md: Remove insns and splitters for subtracting
+ constants.
+ (subsi3): Only accept register operands.
+ (subsi3_internal): Likewise. Use for TARGET_MIPS16 as well.
+ (subdi3_internal_3, subsi3_internal_2): Likewise.
+ (casesi): Use expand_binop to subtract the lower bound.
+
+2003-07-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_in_small_data_p): Don't handle
+ TARGET_MIPS16 specially.
+
+2003-07-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/elf.h (ASM_OUTPUT_ALIGNED_BSS): Use
+ mips_output_aligned_bss.
+ * config/mips/linux.h: Likewise.
+ * config/mips/mips-protos.h (mips_output_aligned_bss): Declare.
+ * config/mips/mips.c (mips_output_aligned_bss): New function.
+
+ * config/mips/elf.h (DBX_DEBUGGING_INFO): Delete.
+ * config/mips/elf64.h: Likewise.
+
+ * config/mips/elf.h (ASM_DECLARE_OBJECT_NAME): Use
+ mips_declare_object_name.
+ (ASM_FINISH_DECLARE_OBJECT): Likewise mips_finish_declare_object.
+ * config/mips/elf64.h: As for elf.h.
+ * config/mips/iris6.h: Likewise.
+ * config/mips/linux.h (ASM_DECLARE_OBJECT_NAME): As for elf.h.
+ * config/mips/mips.h (ASM_DECLARE_OBJECT_NAME): Remove unnecessary
+ do...while (0) block.
+ * config/mips/mips-protos.h (mips_declare_object_name): Declare.
+ (mips_finish_declare_object): Declare.
+ * config/mips/mips.c (mips_declare_object_name): New function.
+ (mips_finish_declare_object): New function.
+
+ * config/mips/elf.h (SBSS_SECTION_ASM_OP): Delete.
+ * config/mips/linux.h: Likewise.
+
+ * config/mips/mips.c (inside_function): Delete.
+ (file_in_function_warning, ignore_line_number): Delete.
+ (mips_output_filename): Don't warn about changing filenames within
+ a function.
+ (mips_output_lineno): Update accordingly.
+ (mips_output_function_prologue): Don't reset the deleted variables.
+ * config/mips/mips.h (inside_function): Delete.
+ (file_in_function_warning, ignore_line_number): Delete.
+
+ * config/mips/elf.h (OBJECT_FORMAT_COFF, EXTENDED_COFF): Remove undefs.
+ * config/mips/elf64.h: Likewise.
+ * config/mips/openbsd.h: Likewise.
+ * config/mips/iris5.h (OBJECT_FORMAT_COFF): Remove undefs.
+ * config/mips/linux.h: Likewise.
+ * config/mips/mips.h (OBJECT_FORMAT_COFF, EXTENDED_COFF): Delete.
+ (CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB, MIPS_UNMARK_STAB): Delete.
+
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Add mips/sdb.h
+ to the list of include files when using gas.
+ (mips*el-*-openbsd*, mips*-*-openbsd*): Add mips/sdb.h unconditionally.
+ * config/mips/elf.h: Remove #undef SDB_DEBUGGING_INFO.
+ * config/mips/elf64.h: Likewise.
+ * config/mips/iris5.h: Likewise.
+ * config/mips/linux.h: Likewise.
+ * config/mips/iris5gas.h (SDB_DEBUGGING_INFO): Remove definition.
+ * config/mips/mips.h (PREFERRED_DEBUGGING_TYPE): Likewise.
+ (SDB_DEBUGGING_INFO, sdb*, SDB_ALLOW_*, PUT_SDB*): Move to...
+ * config/mips/sdb.h: ...this new file.
+
+2003-07-14 Douglas Rupp <rupp@gnat.com>
+
+ * fixinc/server.c (server_setup): Don't use non-POSIX NULL first
+ argument to getcwd; use fixed buffer instead.
+
+2003-07-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Treat OpenBSD normally.
+ * fixinc/fixinc.wrap: Delete.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * ggc-page.c (extra_order_size_table): Insns have 9 slots. Regs
+ don't have 2.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * ggc-page.c (struct globals): Add new fields to keep track of the
+ total allocated memory and overhead.
+ (ggc_print_statistics): Print them.
+ (ggc_alloc): Keep track of the total allocated memory and the
+ overhead.
+
+ * tree.c (dump_tree_statistics): Increase spacing.
+ (enum tree_node_kind): Move to ...
+ * tree.h (enum tree_node_kind): ... here.
+ (tree_node_counts, tree_node_sizes): Declare.
+
+2003-07-14 James A. Morrison <ja2morri@student.math.uwaterloo.ca>
+
+ * doc/include/texinfo.tex: Upgrade to texinfo 4.6.
+
+2003-07-14 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR optimization/11440
+ * gcse.c (try_replace_reg): Don't attach notes to ZERO_EXTRACT or
+ SIGN_EXTRACT SETs.
+
+2003-07-14 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/tm.texi (BLOCK_REG_PADDING): Describe.
+ * expr.h (struct locate_and_pad_arg_data): Add where_pad.
+ (emit_group_load, emit_group_store): Adjust declarations.
+ Remove most occurrences of #ifdef TREE_CODE.
+ * expr.c (emit_group_load): Add "type" param, and use
+ BLOCK_REG_PADDING to determine need for a shift. Optimize non-
+ aligned accesses if !SLOW_UNALIGNED_ACCESS.
+ (emit_group_store): Likewise.
+ (emit_push_insn, expand_assignment, store_expr, expand_expr): Adjust
+ emit_group_load and emit_group_store calls.
+ * calls.c (store_unaligned_arguments_into_pseudos): Tidy. Use
+ BLOCK_REG_PADDING to determine whether we need endian_correction.
+ (load_register_parameters): Localize vars. Handle shifting of
+ small values to the correct end of regs. Adjust emit_group_load
+ call.
+ (expand_call, emit_library_call_value_1): Adjust emit_group_load
+ and emit_group_store calls.
+ * function.c (assign_parms): Set mem alignment for stack slots.
+ Adjust emit_group_store call. Store values at the "wrong" end
+ of regs to the stack. Use BLOCK_REG_PADDING.
+ (locate_and_pad_parm): Save where_pad.
+ (expand_function_end): Adjust emit_group_load call.
+ * stmt.c (expand_value_return): Adjust emit_group_load call.
+ * Makefile.in (calls.o): Depend on $(OPTABS_H).
+ * config/rs6000/linux64.h (TARGET_LITTLE_ENDIAN): Redefine as 0.
+ (AGGREGATE_PADDING_FIXED, AGGREGATES_PAD_UPWARD_ALWAYS): Define.
+ (MUST_PASS_IN_STACK): Define.
+ (BLOCK_REG_PADDING): Define.
+ * config/rs6000/rs6000.h (struct rs6000_args): Remove orig_nargs.
+ (PAD_VARARGS_DOWN): Define in terms of FUNCTION_ARG_PADDING.
+ * config/rs6000/rs6000.c (init_cumulative_args): Don't set orig_nargs.
+ (function_arg_padding): !AGGREGATE_PADDING_FIXED compatibility code.
+ Act on AGGREGATES_PAD_UPWARD_ALWAYS.
+
+2003-07-13 Aaron W. LaFramboise <awlaframboise@aol.com>
+
+ * config/i386/gthr-win32.c (__GTHREAD_HIDE_WIN32API): Define to 1.
+
+2003-07-13 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr, case COMPONENT_REF): If reg, copy OP0 to MEM
+ both if OFFSET specified and if result BLKmode for ARRAY_RANGE_REF.
+
+2003-07-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR other/11123
+ * toplev.c: Don't cut off option names.
+
+2003-07-13 Andreas Jaeger <aj@suse.de>
+
+ * c-decl.c (link_hash_hash): Avoid warning about casting pointer
+ to integer of different size.
+
+2003-07-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison): Convert (ne (and (not X) 1) 0)
+ to (eq (and X 1) 0).
+
+2003-07-13 Andreas Jaeger <aj@suse.de>
+
+ * config.gcc: Add pmmintrin.h for x86_64-*-*.
+
+2003-07-13 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (LIBCPP_DEPS): Remove coretypes.h and $(TM_H).
+ (hashtable.o, line-map.o, mkdeps.o): Likewise, from dependency
+ list. Move these all together down by cpplib.
+
+ * cpplib.h: Don't refer to MAX_WCHAR_TYPE_SIZE when determining
+ definition of CPPCHAR_SIGNED_T.
+
+ * cppcharset.c, cpperror.c, cppexp.c, cppfiles.c, cpphash.c, cppinit.c
+ * cpplex.c, cpplib.c, cppmacro.c, cpppch.c, cpptrad.c, hashtable.c
+ * line-map.c, mkdeps.c: Don't include coretypes.h or tm.h.
+
+ * cpphash.c (_cpp_init_hashtable): Don't use gcc_obstack_init.
+ * cppinit.c (cpp_create_reader): Likewise.
+
+ * cpphash.h (scan_out_logical_line): Rename _cpp_scan_out_logical_line.
+ * cpptrad.c: Likewise. All callers changed.
+ * cpplib.c: All callers changed.
+ * c-ppoutput.c: Replace 'uchar' with 'unsigned char' throughout.
+ * hashtable.h: Define GTY(x) to nothing here too.
+
+2003-07-13 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (compute_record_mode): Remove very obsolete test
+ that forces BLKmode for records with fields crossing word boundary.
+
+2003-07-13 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in: Remove orphan reference to acconfig.h.
+
+2003-07-13 Andreas Jaeger <aj@suse.de>
+
+ * cgraphunit.c: Convert prototypes to ISO C90.
+
+2003-07-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (avoid_wchar_t_type): Use __cplusplus bypass
+ (for OpenBSD).
+ * fixinc/fixincl.x: Rebuild.
+
+2003-07-12 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Always define HAVE_AS_GOTOFF_IN_DATA for
+ i?86-*-*. Use correct name of cache variable.
+ * configure: Regenerate.
+
+2003-07-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c: Fix comment typos.
+ * config/alpha/alpha.md: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/lib1funcs.asm: Likewise.
+ * config/avr/avr.md: Likewise.
+ * config/arm/README-interworking: Fix typos.
+
+2003-07-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-format.c: Fix comment formatting.
+ * c-typeck.c: Likewise.
+ * coverage.c: Likewise.
+ * cppcharset.c: Likewise.
+ * cpplib.c: Likewise.
+ * dbxout.c: Likewise.
+ * gcov-io.h: Likewise.
+ * toplev.c: Likewise.
+
+2003-07-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (alpha_sbrk): Note that OpenBSD needs this
+ fix.
+
+2003-07-12 Zack Weinberg <zack@codesourcery.com>
+
+ * aclocal.m4 (gcc_AC_CHECK_TYPE): Clone of AC_CHECK_TYPE,
+ uses three-argument AC_DEFINE so no acconfig.h entries are
+ needed.
+ (_gcc_COMPUTE_GAS_VERSION): Also provide gcc_cv_gas_vers
+ which contains the GAS version number as a scaled integer.
+ (gcc_GAS_VERSION_GTE_IFELSE): Use gcc_cv_gas_vers. Add
+ ability to check for ELF assembler.
+ (gcc_GAS_CHECK_FEATURE): New macro.
+ * configure.in: Use gcc_AC_CHECK_TYPE. Rewrite all
+ assembler feature checks using gcc_GAS_CHECK_FEATURE.
+ Use three-argument AC_DEFINE everywhere.
+ * acconfig.h: Deleted.
+ * config.in, configure: Regenerate.
+
+2003-07-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (struct_sockaddr): Avoid "fixing" sockaddr_in
+ (on OpenBSD).
+ * fixinc/fixincl.x: Regenerate.
+
+ * fixinc/inclhack.def (gnu_types): Improve comment.
+
+2003-07-12 Andreas Jaeger <aj@suse.de>
+
+ * fp-test.c (main): Use ISO C90 prototype.
+
+ * version.c: Remove unneded include of ansidecl.h.
+
+ * cgraph.h: Convert prototypes to ISO C90.
+ * cgraph.c: Likewise.
+ * fix-header.c: Likewise.
+ * ra.h: Likewise.
+ * protoize.c: Likewise.
+
+2003-07-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_inlined_into, cgraph_inlined_calees): Fix
+ warning.
+
+2003-07-12 Jan Hubicka <jh@suse.cz>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * cgraph.c (cgraph_max_uid): New global variable.
+ (cgraph_node): Set uid field.
+ (create_edge): Keep inline flags consistent.
+ (dump_cgraph): Dump more info.
+ * cgraph.h (struct cgraph_local_info): Remove inline_many and
+ can_inline_once; add inlinable, disgread_inline_limits, and self_insn
+ (struct cgraph_global_info): Add insns, calls, cloned_times,
+ will_be_output.
+ (struct cgraph_node): Add uid.
+ (struct cgraph_edge): Add inline_call.
+ (cgraph_max_uid, cgraph_inline_p): Declare.
+ * cgraph.c: Include params.h and fibheap.h
+ (cgraph_mark_functions_to_inline_once): Kill.
+ (INSNS_PER_CALL): New constant.
+ (ncalls_inlined, nfunctions_inlined, initial_insns, overall_insns): New
+ static variables.
+ (cgraph_finalize_function): Do not analyze inlining.
+ (cgraph_finalize_compilation_unit): Set inlining attributes.
+ (cgraph_mark_functions_to_output): More consistency checks.
+ (cgraph_optimize_function): Set current_function_decl to NULL.
+ (cgraph_expand_function): Use new inline flags.
+ (cgraph_postorder): Expand from cgraph_expand_functions.
+ (INLINED_TIMES, SET_INLINED_TIMES): New macros.
+ (cgraph_inlined_into, cgraph_inlined_callees,
+ cgraph_estimate_size_after_inlining, cgraph_estimate_growth,
+ cgraph_mark_inline, cgraph_check_inline_limits,
+ cgraph_default_inline_p, cgraph_decide_inling_of_small_functions,
+ cgraph_decide_inlining, cgraph_inline_p): New functions.
+ * params.def (PARAM_LARGE_FUNCTION_INSNS, PARAM_LARGE_FUNCTION_GROWTH,
+ PARAM_INLINE_UNIT_GROWTH): New parameters.
+ * tree-inline.c (struct inline_data): New field current_decl.
+ (expand_call_inline): Avoid forward declarations; use
+ inlinable_function_p.
+ (optimize_inline_calls): Set id.current_decl.
+
+2003-07-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * configure.in: Remove wrongly added definition of
+ local_prefix.
+ * configure: Regenerate.
+
+2003-07-11 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * rtl.def (NOTE): Do not use padding.
+
+2003-07-11 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ * doc/install.tex: Update required binutils for i?86-*-linux*
+
+2003-07-11 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (stage1_build): Force OBJS-onestep=OBJS.
+
+2003-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * varasm.c (make_decl_rtl): Treat decls with a DECL_CONTEXT of
+ TRANSLATION_UNIT_DECL as top_level.
+
+2003-07-11 Jakub Jelinek <jakub@redhat.com>
+
+ * optabs.c (prepare_cmp_insn): Try cmpmemM first if it exists,
+ then fall back to cmpstrM.
+ * builtins.c (expand_builtin_memcmp): Likewise.
+ * config/s390/s390-protos.h (s390_expand_cmpstr): Rename to...
+ (s390_expand_cmpmem): ... this.
+ * config/s390/s390.md (cmpmemdi, cmpmemsi, cmpmem_short_64,
+ cmpmem_short_31, cmpmem_long_64, cmpmem_long_31): Renamed
+ from cmpstr* patterns. Rename call to s390_expand_cmpstr
+ to s390_expand_cmpmem.
+ * config/s390/s390.c (s390_expand_cmpstr): Rename to...
+ (s390_expand_cmpstr): ... this. Rename cmpstr* instructions
+ to cmpmem*.
+ * config/i370/i370.md (cmpmemsi, cmpmemsi_1): Renamed from
+ cmpstr* patterns.
+ * doc/md.texi (cmpstrM): Describe as String compare insn, not
+ Block compare insn.
+ (cmpmemM): Add.
+
+2003-07-11 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/freebsd.h (SET_ASM_OP): Remove.
+ (SUBTARGET_OVERRIDE_OPTIONS): Handle TARGET_64BIT case.
+ (ASM_COMMENT_START, ASM_APP_ON, ASM_APP_OFF, DBX_REGISTER_NUMBER
+ MCOUNT_NAME, SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE_SIZE): Whitespace.
+
+2003-07-11 Richard Henderson <rth@redhat.com>
+
+ * function.c (assign_parms): Don't recombine complex args if
+ fnargs is unchanged from orig_fnargs.
+ (split_complex_args): Return args without complex before copying.
+ Re-layout the modified parameters.
+
+2003-07-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * regclass.c (choose_hard_reg_mode): Add third argument.
+ Changed all callers.
+ * rtl.h (choose_hard_reg_mode): Update declaration.
+ * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes):
+ Take HARD_REGNO_CALL_PART_CLOBBERED into account.
+
+2003-07-11 Geoffrey Keating <geoffk@apple.com>
+
+ * c-decl.c (finish_decl): Handle 'used' here...
+ * cgraphunit.c (cgraph_finalize_function): ... and here ...
+ * c-common.c: (handle_used_attribute): ... not here.
+
+ * configure.in (onstep): Support --enable-intermodule.
+ * Makefile.in (OBJS-common): New.
+ (OBJS-md): New.
+ (OBJS-archive): New.
+ (OBJS): Build from OBJS-common, OBJS-md, OBJS-archive.
+ (OBJS-onestep): New.
+ (libbackend.a): Support @onestep@.
+ (libbackend.o): New.
+ * configure: Regenerate.
+
+ * c-common.h (c_reset_state): New prototype.
+ (c_parse_file): New prototype.
+ (finish_file): Move prototype from c-tree.h.
+ * c-decl.c: Include <hashtab.h>.
+ (builtin_decls): New.
+ (current_file_decl): New.
+ (duplicate_decls): Add extra parameter. Change all callers. Don't
+ output duplicate common symbols.
+ (link_hash_hash): New.
+ (link_hash_eq): New.
+ (poplevel): Handle popping of the top level.
+ (warn_if_shadowing): Handle TRANSLATION_UNIT_DECL.
+ (pushdecl): Set DECL_CONTEXT to TRANSLATION_UNIT_DECL if appropriate.
+ (pushdecl_top_level): Likewise.
+ (redeclaration_error_message): Handle TRANSLATION_UNIT_DECL.
+ (c_init_decl_processing): Create TRANSLATION_UNIT_DECL.
+ (finish_decl): Handle TRANSLATION_UNIT_DECL.
+ (merge_translation_unit_decls): New.
+ (c_write_global_declarations): New.
+ (c_reset_state): New.
+ (implicitly_declare): Handle TRANSLATION_UNIT_DECL.
+ * c-lang.c (LANG_HOOKS_WRITE_GLOBALS): New.
+ * c-objc-common.c (c_cannot_inline_tree_fn): Handle
+ TRANSLATION_UNIT_DECL.
+ (c_objc_common_finish_file): Call merge_translation_unit_decls.
+ * c-opts.c (in_fnames): Rename from in_fname.
+ (c_common_decode_option): Handle multiple input filenames.
+ (c_common_post_options): Likewise.
+ (c_common_parse_file): Likewise; also, call c_parse_file rather than
+ yyparse.
+ * c-parse.in: Move cleanup code to c_parse_file.
+ (free_parser_stacks): Move contents to c_parse_file.
+ (c_parse_file): New.
+ * c-tree.h (union lang_tree_node): Chain along TYPE_NEXT_VARIANT
+ for integer types.
+ (C_DECL_FILE_SCOPE): New.
+ (finish_file): Move prototype to c-common.h.
+ (merge_translation_unit_decls): New prototype.
+ (comptypes): Add extra parameter to prototype.
+ (c_write_global_declarations): New prototype.
+ * c-typeck.c (tagged_types_tu_compatible_p): New.
+ (function_types_compatible_p): Add extra parameter, change all callers.
+ (type_lists_compatible_p): Likewise.
+ (comptypes): Likewise.
+ (struct tagged_tu_seen): New.
+ (tagged_tu_seen_base): New.
+ (build_unary_op): Handle TRANSLATION_UNIT_DECL.
+ (c_mark_addressable): Remove #if 0 code.
+ * calls.c (special_function_p): Handle TRANSLATION_UNIT_DECL, add
+ comment explaining why it shouldn't have to.
+ * cgraph.h (struct cgraph_node): Add chain_next and chain_prev GTY
+ options.
+ * cppinit.c (cpp_read_next_file): New.
+ (cpp_read_main_file): Use it.
+ * cpplib.c (undefine_macros): New.
+ (cpp_undef_all): New.
+ * cpplib.h (cpp_read_next_file): Prototype.
+ (cpp_undef_all): Prototype.
+ * langhooks-def.h (write_global_declarations): Remove prototype.
+ * toplev.h (write_global_declarations): Add prototype.
+ * tree.c (decl_type_context): Use switch statement, handle
+ TRANSLATION_UNIT_DECL.
+ * tree.def: Update documentation for TRANSLATION_UNIT_DECL.
+ (TRANSLATION_UNIT_DECL): New kind of tree.
+ * tree.h: Update documentation for TRANSLATION_UNIT_DECL.
+ * Makefile.in (c-decl.o): Add $(HASHTAB_H) to dependencies.
+ * doc/invoke.texi: Make attempt to document new functionality.
+
+ 2003-05-19 Per Bothner <bothner@apple.com>
+
+ * gcc.c (combine_inputs): New.
+ (process_command): Set combine_inputs.
+ (do_spec_1): Handle combine_inputs.
+ (main): Likewise.
+
+2003-07-10 James E Wilson <wilson@tuliptree.org>
+
+ PR optimization/9745
+ * loop.c (loop_iv_add_mult_emit_before): Call loop_regs_update before
+ loop_insn_emit_before.
+ (loop_iv_add_mult_sink, loop_iv_add_mult_hoist): Likewise.
+
+2003-07-10 Zack Weinberg <zack@codesourcery.com>
+
+ * cppcharset.c: Fix comment.
+ (iconv_close [!HAVE_ICONV]): #define to (void)0 to prevent warning.
+ (EILSEQ): #define to EINVAL if not already defined.
+ (convert_using_iconv): #if out when !HAVE_ICONV.
+ (init_iconv_desc): Handle !HAVE_ICONV here...
+ (cpp_init_iconv): ...not here.
+
+2003-07-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: More --help messages.
+ * opts.c (print_help): Use puts().
+ * toplev.c (f_options): Remove help text.
+ (display_help): Don't dump f_options.
+
+2003-07-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Drop reference to unsupported alpha-*-interix*.
+ Move i?86-*-interix* to the don't-fix list.
+ * fixinc/fixinc.interix: Delete with extreme prejudice.
+
+2003-07-10 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ PR bootstrap/10758
+ * doc/install.texi: Document requirements for ia64-*-hpux* target.
+
+2003-07-10 Roger Sayle <roger@eyesopen.com>
+
+ * config/ia64/hpux.h (TARGET_C99_FUNCTIONS): Define.
+
+2003-07-10 Zack Weinberg <zack@codesourcery.com>
+
+ * cppcharset.c (one_utf8_to_cppchar, one_cppchar_to_utf8,
+ one_utf8_to_utf32, one_utf32_to_utf8, one_utf8_to_utf16,
+ one_utf16_to_utf8, conversion_loop, convert_utf8_utf16,
+ convert_utf8_utf32, convert_utf16_utf8, convert_utf32_utf8,
+ convert_no_conversion, convert_using_iconv): New functions.
+ (APPLY_CONVERSION): New macro.
+ (struct conversion, conversion_tab): New data structure.
+ (init_iconv_desc): Check conversion_tab for a custom conversion
+ primitive before trying to use iconv.
+ (convert_cset): Deleted.
+ (cpp_init_iconv): Use UTF- terminology, not UCS-.
+ (_cpp_destroy_iconv): Update to match.
+ (_cpp_valid_ucn): We don't need iconv to implement UCNs.
+ (convert_ucn): Use one_cppchar_to_utf8 and APPLY_CONVERSION.
+ (convert_escape, cpp_interpret_string): Use APPLY_CONVERSION.
+ (_cpp_interpret_string_notranslate): New function, moved here
+ from cpplib.c.
+
+ * cpphash.h (convert_f, struct cset_converter): New types.
+ (struct cpp_reader): narrow_cset_desc and wide_cset_desc
+ are now struct cset_converter, not bare iconv_t.
+ Update prototypes.
+ * cpplib.c (interpret_string_notranslate): Moved to cppcharset.c;
+ all callers changed.
+
+2003-07-10 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in (options.h): Depend on Makefile. Add move-if-change
+ to opts.sh command line.
+ * opts.sh: Write to temporary files with a move-if-change at the end.
+
+2003-07-10 Denis Chertykov <denisc@overta.ru>
+ Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * combine.c (gen_binary): Handle the CLOBBER rtx and
+ don't build a binary operation with it.
+
+2003-07-10 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (load_kills_store, find_loads, store_killed_in_insn,
+ store_killed_after, store_killed_before): Keep track of the correct
+ dependency function to use.
+
+2003-07-10 Steven Bosscher <steven@gcc.gnu.org>
+ * toplev.c (do_compile): Don't try to open dump files before
+ lang_dependent_init initializes dump_base_name.
+
+2003-07-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/arm/arm.c (arm_init_iwmmxt_builtins, arm_expand_builtin):
+ Use ARRAY_SIZE.
+ * config/frv/frv.c (frv_expand_builtin): Likewise.
+ * config/sh/sh.c (sh_media_init_builtins): Likewise.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10032
+ * doc/invoke.texi (C++ Dialect Options): Change documentation of
+ -fpermissive.
+
+2003-07-10 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * tm.texi (RETURN_ADDR_OFFSET): Document.
+
+2003-07-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h: Update documentation.
+ (GCOV_UNSIGNED2STRING): New.
+ (GCOV_TAG_FUNCTION_LENGTH, GCOV_TAG_BLOCKS_LENGTH,
+ GCOV_TAG_ARCS_LENGTH, GCOV_TAG_COUNTER_LENGTH,
+ GCOV_TAG_SUMMARY_LENGTH): Adjust.
+ (GCOV_TAG_BLOCKS_NUM, GCOV_TAG_ARCS_NUM,
+ GCOV_TAG_COUNTER_NUM): New.
+ (GCOV_BLOCK_SIZE): Number of words.
+ (gcov_var): Adjust buffer type.
+ * gcov-io.c (gcov_write_bytes, gcov_read_bytes): Rename to ...
+ (gcov_write_words, gcov_read_words): ... here. Take a 4-byte word
+ count, not byte count.
+ (gcov_open): Adjust overread init.
+ (gcov_allocate, gcov_write_unsigned, gcov_write_counter,
+ gcov_write_string, gcov_write_tag, gcov_write_length,
+ gcov_write_tag_length): Adjust.
+ (gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust.
+ (gcov_sync, gcov_seek): Adjust.
+ * gcov-dump.c (print_usage): Show gcc version only.
+ (dump_file): Use GCOV_UNSIGNED2STRING.
+ (tag_blocks, tag_arcs, tag_counters): Use GCOV_TAG_*_NUM macros.
+ * gcov.c (print_version): Show gcc version only.
+ (read_graph_file): Use GCOV_UNSIGNED2STRING. Use
+ GCOV_TAG_*_NUM macros.
+ (read_count_file): Use GCOV_UNSIGNED2STRING. Use
+ GCOV_TAG_COUNTER_LENGTH.
+ * coverage.c (read_counts_file): Use GCOV_UNSIGNED2STRING.
+ Use GCOV_TAG_COUNTER_NUM.
+ * libgcov.c (gcov_version): Use GCOV_UNSIGNED2STRING.
+ (__gcov_merge_single, __gcov_merge_delta): Use GCOV_CHECK.
+
+2003-07-10 Andreas Schwab <schwab@suse.de>
+
+ * gcov-dump.c (dump_file): Fix missing address operator.
+
+2003-07-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR c/11449
+ * fold-const.c (sign_bit_p): Return EXP if VAL is the sign bit
+ of HOST_WIDE_INT.
+ (fold_single_bit_test): If sign_bit_p() fails, assume that the
+ bit being tested is not a sign bit.
+
+2003-07-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-07-10 Alexandre Oliva <aoliva@redhat.com>
+
+ 2001-12-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/linux.h (LINK_SPEC): Rename the dynamic linker
+ from ld-linux.so.2 to ld.so.1.
+ 2001-11-18 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/linux.h (LINK_SPEC): -lpthread, not -lthread.
+ * config/mn10300/linux.h (LINK_SPEC): Don't handle -Wl,-rpath
+ nor -Wl,-rpath-link.
+ (LIB_SPEC): Add -rpath-link if !static.
+ 2001-08-22 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (mn10300_protect_label): New
+ variable.
+ * config/mn10300/linux.h (PRINT_OPERAND,
+ PRINT_OPERAND_ADDRESS): Set it during their execution.
+ (ASM_OUTPUT_LABELREF): Output `+' before symbol name if
+ mn10300_protect_label is set.
+ * config/mn10300/linux.h (LINK_SPEC): Recognize -Wl,-rpath and
+ -Wl,-rpath-link.
+ (LIB_SPEC, STARTFILE_SPEC): Define.
+ 2001-05-11 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/t-linux (dp-bit.c, fp-bit.c): Don't define
+ FLOAT_BIT_ORDER_MISMATCH.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc (am33_2.0-*-linux*): Added.
+ * config/mn10300/linux.h: New.
+ * config/mn10300/t-linux: New.
+
+2003-07-10 Andreas Jaeger <aj@suse.de>
+
+ * fold-const.c: Properly wrap prototypes.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-06-16 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (mn10300_unspec_int_label_counter):
+ Moved from...
+ * config/mn10300/mn10300.md (GOTaddr2picreg): ... here.
+ * config/mn10300/mn10300.h: GTY-declare it.
+ 2003-06-11 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (mn10300_encode_section_info): Fix
+ prototype. Use incoming RTL argument.
+ 2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (int_label): Move C statements...
+ (GOTaddr2picreg): ... here.
+ 2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.h (ENCODE_SECTION_INFO): Move...
+ * config/mn10300/mn10300.c (mn10300_encode_section_info):
+ ... here. New function.
+ (TARGET_ENCODE_SECTION_INFO): Define to it.
+ 2001-11-04 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (builtin_setjmp_receiver): Fix typo in
+ pattern name.
+ (mn10300_loadPC): Define as insn splittable after reload.
+ 2001-05-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/sh/mn10300.h (JUMP_TABLES_IN_TEXT_SECTION): Let them
+ be defined in .rodata even in PIC, now that the assembler
+ supports that.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.h (GOT_SYMBOL_NAME): Don't let the
+ symbol take an underscore prefix.
+ 2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300-protos.h (legitimate_pic_operand_p,
+ legitimize_pic_address): Declare.
+ * config/mn10300/mn10300.h (CONDITIONAL_REGISTER_USAGE): Mark
+ the PIC register as fixed.
+ (EXTRA_CONSTRAINT): Match UNSPEC_PLT and UNSPEC_PIC for 'S'.
+ (GO_IF_LEGITIMATE_ADDRESS): Require legitimate_pic_operand for
+ PIC.
+ (LEGITIMATE_PIC_OPERAND_P): Define.
+ (PIC_OFFSET_TABLE_REGNUM): Define.
+ (GOT_SYMBOL_NAME): Define.
+ (SYMBOLIC_CONST_P): Define.
+ (ENCODE_SECTION_INFO): Use SYMBOL_REF_FLAG to mark local
+ symbols.
+ (MN10300_GLOBAL_P): Test it.
+ (OUTPUT_ADDR_CONST_EXTRA): Handle PIC-related unspecs.
+ (JUMP_TABLES_IN_TEXT_SECTION): Enable for PIC.
+ * config/mn10300/mn10300.c (print_operand): Handle unspec.
+ (expand_prologue): Set PIC register.
+ (call_address_operand): Don't match SYMBOL_REFs in PIC.
+ (legitimize_address): Call legitimize_pic_address.
+ (legitimize_pic_address): New fn.
+ (legitimate_pic_operand_p): New fn.
+ * config/mn10300/mn10300.md (PIC_REG, SP_REG): New constants.
+ (UNSPEC_INT_LABEL, UNSPEC_PIC, UNSPEC_GOT, UNSPEC_GOTOFF,
+ UNSPEC_PLT): New constants.
+ (pop_pic_reg): New insn.
+ (movsi): Adjust non-PIC addresses.
+ (builtin_setjmp_receiver): Restore the PIC register.
+ (casesi): New insn.
+ (call): Adjust non-PIC addresses.
+ (int_label, GOTaddr2picreg): New expands.
+ (am33_loadPC): New insn.
+ (mn10300_loadPC): New expand.
+ (call_next_insn): New insn.
+ (add_GOT_to_pic_reg): New expand.
+ (symGOT2reg, symGOT2reg_i): New expands.
+ (symGOTOFF2reg, symGOTOFF2reg_i): New expands.
+ (sym2PIC, sym2PLT): New expands.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.h (PREDICATE_CODES): Define.
+ 2001-05-01 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (sqrtsf2): flag_fast_math was renamed
+ to flag_unsafe_math_optimizations.
+ 2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (expand_prologue): Mark
+ FP-register-saving insns as frame-related.
+ 2001-02-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c
+ (mn10300_get_live_callee_saved_regs): Don't search past
+ LAST_EXTENDED_REGNUM.
+ (mn10300_gen_multiple_store, store_multiple_operation): Likewise.
+ * config/mn10300/mn10300.md: Remove excessive line breaks from
+ `@' output patterns that were accounted as additional
+ alternatives.
+ * config/mn10300/mn10300.md, config/mn10300/mn10300.c:
+ Re-introduce changes accidentally removed in Richard Sandiford's
+ 2000-12-05's patch.
+ * config/mn10300/t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
+ Re-instate am33-2 lost in merge from net GCC.
+ 2000-08-26 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.h (DBX_REGISTER_NUMBER): Added
+ floating-point registers.
+ 2000-08-07 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (movdf): Revert some am33-specific
+ pessimizations that had gone in on 2000-05-08.
+ 2000-06-28 Graham Stott <grahams@cygnus.co.uk>
+ * config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Fix typo.
+ 2000-06-22 Graham Stott <grahams@cygnus.co.uk>
+ * config/mn10300/mn10300.md (movqi): Use nonimmediate_operand for
+ operand 0.
+ * (movhi): Likewise.
+ * (movsi): Likewise.
+ * (movsf): Likewise.
+ * (movdi): Likewise.
+ * (movdf): Likewise.
+ 2000-05-24 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.c (fp_regs_to_save): New function.
+ (can_use_return_insn, initial_offset): Add fp_regs_to_save.
+ (expand_prologue, expand_epilogue): Save and restore FP regs.
+ 2000-05-20 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (movdi, movdf): 64-bit clean-up.
+ 2000-05-13 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2, addsf3,
+ subsf3, mulsf3, divsf3, fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4):
+ Do not clobber cc0.
+ 2000-05-12 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2):
+ Discourage the two-argument, longer opcodes.
+ (addsf3, subsf3, mulsf3, divsf3): Likewise for three-argument
+ ones.
+ * config/mn10300/mn10300.h (struct mn10300_cc_status_mdep): New.
+ (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Define.
+ * config/mn10300/mn10300.md (cmpsf): New pattern.
+ (branch): Test mdep.fpCC and output fbCC.
+ * config/mn10300/mn10300.c (print_operand): Output conditions.
+ (notice_cc_update): Recognize fcmp and set mdep.fpCC.
+ 2000-05-10 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (movsf, movdf, addsf3, subsf3,
+ mulsf3, divsf3): Use the `F' constraint for FP values.
+ * config/mn10300/mn10300.c (const_1f_operand): New function.
+ * config/mn10300/mn10300-protos.h (const_1f_operand): Declare.
+ * config/mn10300/mn10300.md (sqrtsf2): New expand.
+ (rsqrtsf2): New insn.
+ 2000-05-09 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (movdf): Oops, I missed it in my
+ previous check-in.
+ 2000-05-08 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (abssf2, negdf2): On
+ TARGET_AM33_2, expand to...
+ (abssf2_am33_2, negdf2_am33_2): New insns.
+ (addsf3, subsf3, mulsf3, divsf3): Likewise.
+ (fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4): Likewise.
+ * config/mn10300/mn10300.md (movqi, movhi, movsi, movsf,
+ movdi, movdf): Added FP regs.
+ * invoke.texi (-mam33-2, -mno-am33-2): Document.
+ 2000-04-29 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (FIRST_FP_REGNUM, LAST_FP_REGNUM):
+ New macros.
+ (REGNO_AM33_2_FP_P): Renamed to...
+ (REGNO_FP_P): Redefine in terms of FIRST_* and LAST_*.
+ (CONDITIONAL_REGISTER_USAGE, REGNO_REG_CLASS): Likewise.
+ 2000-04-27 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Remove FP
+ regs from GENERAL_REGS.
+ 2000-04-27 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (REGNO_AM33_2_FP_P): New macro.
+ * config/mn10300/mn10300.c (mn10300_address_cost): Added FP_REGS.
+ * config/mn10300/mn10300.h (REGISTER_MOVE_COST): Added FP_REGS.
+ 2000-04-23 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (CLASS_CANNOT_CHANGE_SIZE): Defined
+ as FP_REGS.
+ 2000-04-21 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (OK_FOR_Q): New macro.
+ (EXTRA_CONSTRAINT): Added OK_FOR_Q.
+ * config/mn10300/mn10300.c (secondary_reload_class): Adjust.
+ * config/mn10300/mn10300.c (print_operand): Support `D' for doubles.
+ * config/mn10300/mn10300.h (FIRST_PSEUDO_REGISTER): Adjust.
+ (FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER): Added
+ AM33/2.0 floating-point registers.
+ (CONDITIONAL_REGISTER_USAGE): Adjust.
+ (enum reg_class, REG_CLASS_NAMES): Added FP_REGS and FP_ACC_REGS.
+ (REG_CLASS_CONTENTS, REGNO_REG_CLASS): Adjust.
+ (REG_CLASS_FROM_LETTER): Added `f' and `A'.
+ (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Adjust.
+ * config/mn10300/t-mn10300 (MULTILIB_OPTIONS): Added am33-2.
+ (MULTILIB_DIRNAMES): Likewise.
+ * config/mn10300/mn10300.h (CPP_SPEC): Define `__AM33__=2' and
+ `__AM33_2__' when `-mam33-2' is given.
+ (TARGET_AM33_2): Define.
+ (TARGET_SWITCHES): Adjust.
+ * config/mn10300/mn10300.c (asm_file_start): Print `.am33_2'
+ when appropriate.
+
+2003-07-09 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/install.texi: Add missing @.
+
+2003-07-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (CRT_CALL_STATIC_FUNCTION): Define.
+
+2003-07-09 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/11144
+ * config/i386/i386.c (ix86_function_arg_boundary): Remove abort.
+
+2003-07-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR bootstrap/11043
+ * config/arc/t-arc: Replace bogus references to "x-crtinit.o",
+ "x-crtfini.o" with "crtinit.o", "crtfini.o".
+
+ * fixinc/inclhack.def (limits_ifndefs): Add select test.
+ * fixinc/fixincl.x: Rebuild.
+
+ * fixinc/inclhack.def (math_exception): Improve bypass and comment.
+ * fixinc/fixincl.x: Rebuild.
+
+2003-07-09 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/install.texi (Configuration): Document the valgrind option
+ to --enable-checking.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * objc-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+
+2003-07-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * c-lex.c (cb_ident): Cast cstr.text to const char *.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h: Update documentation.
+ (GCOV_GRAPH_SUFFIX, GCOV_GRAPH_MAGIC): Rename to GCOV_NOTE_SUFFIX,
+ GCOV_NOTE_MAGIC.
+ (GCOV_DATA_SUFFIX, GCOV_NOTE_SUFFIX): Update.
+ (GCOV_DATA_MAGIC, GCOV_NOTE_MAGIC): Make non-palindromic.
+ (struct gcov_var): Change buffer's type. Add endian flag.
+ (gcov_open): Remove mode in libgcov.
+ (gcov_magic): Prototype.
+ * gcov-io.c (from_file): New.
+ (gcov_open): Clear endian flag.
+ (gcov_magic): New.
+ (gcov_write_bytes, gcov_read_bytes): Return gcov_unsigned_t
+ pointers.
+ (gcov_write_unsigned, gcov_write_counter, gcov_write_string,
+ gcov_write_tag, gcov_write_length, gcov_write_tag_length): Update.
+ (gcov_read_unsigned, gcov_read_counter, gcov_read_string): Update.
+ * gcov-iov.c (main): Correct cast.
+ * coverage.c (read_counts_file): Use gcov_magic. Remove endianness
+ conversion.
+ (gcov_begin_output): Use GCOV_NOTE_MAGIC.
+ (coverage_init): Use GCOV_NOTE_SUFFIX.
+ * libgcov.c (gcov_version_mismatch): Remove endianness conversion.
+ Rename to gcov_version, and return flag.
+ (gcov_exit): Use gcov_version.
+ (__gcov_init): Use gcov_version.
+ * Makefile.in (coverageexts): Update.
+ * gcov.c (print_version): Remove endianness conversion.
+ (create_file_names): Use GCOV_NOTE_SUFFIX.
+ (read_graph_file): Use gcov_magic.
+ (read_count_file): Likewise.
+ * gcov-dump.c (dump_file): Remove endianness conversion, use
+ gcov_magic.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * configure.in (BUILD_PREFIX, BUILD_PREFIX_1): Set if enable
+ coverage is on.
+ * configure: Regenerated.
+ * Makefile.in (ALL_CFLAGS): Correct its comment.
+
+2003-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * fold-const.c (make_range): Do not access operand 1 for a
+ zero-operand operator.
+
+2003-07-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * toplev.c (warn_dummy, W_options): Die.
+ (display_help): Don't print W_options.
+ * common.opt: Add W_options help from toplev.c.
+
+2003-07-09 Andreas Jaeger <aj@suse.de>
+
+ * opts.c (wrap_help): Only pass int arguments as arguments to
+ printf's '*' modifier. Change argument of function.
+
+2003-07-08 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/invoke.texi: Fix misspelling of "@item".
+
+2003-07-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.md: Remove an old comment about
+ NOTICE_UPDATE_CC.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_node_name): New function.
+ (dump_cgraph): Use it.
+ * cgraph.h (cgraph_dump_file): Declare.
+ (cgraph_node_name): Declare.
+ * cgraphunit.c: Include timevar.h
+ (cgraph_finalize_compilation_unit): Use timevar; reorganize dumps.
+ (cgraph_optimize_function): Use TV_INTEGRATION.
+ (cgraph_mark_local_functions): reorganize dumps.
+ (cgraph_mark_functions_to_inline_once): Likewise.
+ (cgraph_optimize): Likewise; use timevar.
+ * timevar.def (TV_CGRAPH, TV_CGRAPHOPT): New.
+ * toplev.c (dump_file_index): Add DFI_cgraph.
+ (dump_file_info): Likewise.
+ (cgraph_dump_file): New global variable.
+ (do_compile): Open and close cgraph dump.
+ * invoke.texi (-d): Document new flag; renumber.
+
+2003-07-08 Roger Sayle <roger@eyesopen.com>
+
+ PR c/11370
+ * calls.c (emit_call_1): Don't bother popping the arguments off of
+ the stack after a noreturn function call; The adjustment is dead.
+ (expand_call): Likewise.
+
+2003-07-08 Geoffrey Keating <geoffk@apple.com>
+
+ * expr.c (MOVE_MAX_PIECES): Move from here...
+ * defaults.h (MOVE_MAX_PIECES): ... to here.
+
+2003-07-08 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in (stage1-start): Handle an empty SUBDIRS.
+
+2003-07-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattr.c (internal_dfa_insn_code): Don't prototype.
+ * genattrtab.c (attr_desc): Add `static_p' field.
+ (expand_units): Make blockage range and ready cost functions
+ static.
+ (write_attr_get): Don't add extern prototypes in C file. Mark
+ static functions as appropriate.
+ (find_attr, make_internal_attr): Initialize static_p.
+ * genattrtab.h (ATTR_STATIC): New macro.
+ * genautomata.c (output_internal_reset_func): Mark output function
+ as inline.
+ (make_internal_dfa_insn_code_attr): Mark output function as static.
+
+2003-07-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattrtab.h: Add new macros for attr `special' flags.
+ * genattrtab.c (attr_desc): Reorder/resize fields better.
+ Use attr `special' macros in all calls to make_internal_attr.
+ * genautomata.c: Likewise.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (c_estimate_num_insns_1): New static function.
+ (c_estimate_num_insns): New global function.
+ * c-common.h (DECL_NUM_STMTS): Rename to...
+ (DECL_ESTIMATED_INSNS): ... this.
+ (c_estimate_num_insns): Declare.
+ * c-decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
+ * c-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+ * c-semantics.c (add_stmt): Do not account statements.
+ * langhooks-def.h (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS):
+ New.
+ * langhooks.h (lang_hooks_for_tree_inlining): Add
+ estimate_num_insns
+ * params.def (max-inline-insns-auto, max-inline-insns-auto): set
+ to 100.
+ (max-inline-insns): set to 300.
+ (min-inline-insns): set to 10.
+ * tree-inline.c (struct inline_data): Rename inlined_stmts to
+ inlined-insns.
+ (INSNS_PER_STMT): Kill.
+ (inlinable_function_p): Compute and store body size.
+ (expand_call_inline): Likewise.
+ (optimize_inline_calls): Likewise.
+
+2003-07-08 James E Wilson <wilson@tuliptree.org>
+
+ PR target/10021
+ * emit-rtl.c (set_mem_attribute_minus_bitpos): When handle ARRAY_REF,
+ loop over new variable t2 instead of t.
+
+2003-07-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR bootstrap/11455
+ * config/i386/winnt.c: Replace use of error(), warning() with
+ error_with_decl(), warning_with_decl(), throughout.
+
+2003-07-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (wrap_help): Use unsigned int, not size_t.
+
+2003-07-08 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (HAVE_AS_DWARF2_DEBUG_LINE): Don't define
+ as .file/.loc directives are incompatible with linker relaxation.
+
+2003-07-08 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (fixinc.sh): Remove gnu-regex.[ch] from dependencies.
+ * fixinc/Makefile.in: Remove all references to gnu-regex.[och].
+ * fixinc/fixfixes.c, fixinc/fixincl.c, fixinc/fixlib.c
+ * fixinc/fixtests.c: Use xregexec not regexec, xregcomp not regcomp.
+ * fixinc/fixlib.h: Include xregex.h not gnu-regex.h.
+ * fixinc/inclhack.def (hpux10_cpp_pow_inline, hpux11_cpp_pow_inline):
+ Escape { and } characters which are not part of range expressions.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/gnu-regex.c, fixinc/gnu-regex.h: Delete file.
+
+2003-07-08 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c/1687
+ * tree-inline.c (find_alloca_call): Use
+ walk_tree_without_duplicates, instead of walk_tree.
+ (find_builtin_longjmp_call): Likewise.
+ * c-objc-common.c (c_cannot_inline_fn): Likewise.
+ * c-semantics.c (find_reachable_label): Likewise.
+
+2003-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/11420
+ * config/i386/i386.c (ix86_check_movabs): New function.
+ * config/i386/i386-protos.h (ix86_check_movabs): New prototype.
+ * config/i386/i386.md (movabs[shqd]i_1_rex64): Kill broken alternative.
+ (movabs[shqd]i_[12]_rex64): Add ix86_check_movabs check to conditions.
+
+2003-07-08 Chris Demetriou <cgd@broadcom.com>
+
+ * Makefile.in (install-po): Cope with empty CATALOGS.
+
+2003-07-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/elf64.h (TARGET_ASM_UNIQUE_SECTION): Delete.
+ (EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
+ (SECTION_FUNCTION_TEMPLATE): Delete.
+ * config/mips/elf.h: As for elf64.h.
+ (ASM_OUTPUT_ALIGNED_BSS): Use named_section rather than sbss_section.
+ * config/mips/linux.h: As for elf.h
+ * config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
+ * config/mips/iris6.h (EXTRA_SECTIONS): Delete.
+ (EXTRA_SECTION_FUNCTIONS): Remove sdata_section. Remove the handling
+ of in_sdata from current_section_name and current_section_flags.
+ * config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
+ * config/mips/mips.h (sdata_section, sbss_section): Remove prototypes.
+ (MASK_GP_OPT, TARGET_GP_OPT): Delete.
+ (MASK_NO_FUSED_MADD): Use MASK_GP_OPT's old value.
+ (TARGET_SWITCHES): Neuter gpOPT, gpopt, no-gpOPT and no-gpopt.
+ (SMALL_DATA_SECTION, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Remove.
+ * config/mips/mips.c (TARGET_IN_SMALL_DATA_P): Override.
+ (TARGET_SECTION_TYPE_FLAGS): Override if TARGET_IRIX6.
+ (mips_classify_symbol): Use SYMBOL_REF_SMALL_P.
+ (override_options): Remove setting of MASK_GPOPT.
+ (mips_output_external): Use mips_in_small_data_p to check whether a
+ symbol needs an .extern directive. Don't emit such directives for
+ TARGET_EXPLICIT_RELOCS.
+ (mips_declare_object): Update accordingly.
+ (mips_select_rtx_section): Call named_section rather than
+ SMALL_DATA_SECTION.
+ (mips_select_section): Use default_elf_section_section for everything
+ except .text string constants.
+ (mips_in_small_data_p): New function.
+ (mips_encode_section_info): Remove small data handling.
+ (mips_unique_section): Delete.
+ (iris6_section_type_flags): New function.
+ * doc/tm.texi: Remove documentation of -mgpopt and -mhalf-pic.
+
+2003-07-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR Target/11453
+ * pa.md: Disparage all mtsar constraints.
+ (extzv, extv, insv): Don't fail on length of {32|64}.
+
+2003-07-08 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h: Poison MAP_CHARACTER.
+ * config/i370/i370-protos.h (mvs_map_char): Delete.
+ * config/i370/i370.c (ascebc, ebcasc, mvs_map_char): Delete.
+ * config/i370/i370.h (MAP_CHARACTER): Delete definition.
+ (ASM_OUTPUT_ASCII): Don't use MAP_CHARACTER.
+
+2003-07-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * toplev.c (randomize): Correct call to time().
+
+2003-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * unroll.c (reg_dead_after_loop): Check for reg in REG_EQUAL and
+ REG_EQUIV notes as well.
+
+2003-07-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/md.texi: Fix the description of addmodecc.
+
+2003-07-07 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (top_builddir): Set to "..", not ".".
+ (INTLLIBS, INTLDEPS): Delete.
+ (LIBINTL, LIBINTL_DEP, LIBICONV_DEP): New variables to be substituted.
+ (LIBDEPS): Add $(LIBICONV_DEP).
+ (LIBS): Take out $(INTLLIBS), add $(LIBINTL) and $(LIBICONV).
+ (INCLUDES): Replace -I../intl with @INCINTL@.
+ ($(top_builddir)/intl/libintl.a): Delete rule.
+ (stage2-start, stage3-start, stage4-start, stageprofile-start,
+ stagefeedback-start): Use $$ for variable to be evaluated by
+ shell, not make.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT,
+ HAVE_LC_MESSAGES, HAVE_STPCPY): Delete.
+ * aclocal.m4: sinclude ../config/progtest.m4. Add
+ contents of lcmessage.m4 from gettext distro.
+ * configure.in: Check for wchar.h and setlocale. Set
+ LIBICONV_DEP to the empty string and substitute it.
+ Call AM_LC_MESSAGES. Delete AC_ARG_ENABLE for --enable-nls;
+ this is handled elsewhere. Use ZW_GNU_GETTEXT_SISTER_DIR,
+ not CY_GNU_GETTEXT. Clear $LIBICONV if its text is included
+ in $LIBINTL, to avoid linking it twice.
+ * configure, config.in: Regenerate.
+
+2003-07-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Remove winnt support.
+ * fixinc/fixinc.winnt: Delete with extreme prejudice.
+
+2003-07-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-opts.c (c_common_handle_option): opt_text now contains the '-'.
+ * c.opt: Update documentation.
+ * common.opt: Add some help text.
+ * opts.c: Include intl.h.
+ (wrap_help, print_help): New.
+ (find_opt, handle_option, common_handle_option): opt_text now
+ contains the '-'. Use print_help to output help.
+ * opts.h (struct cl_option): New member "help".
+ * opts.sh: Update to handle help text output and to prepend
+ options with '-'.
+ * toplev.c (display_help): Remove some help text.
+
+2003-07-07 David Edelsohn <edelsohn@gnu.org>
+ Fariborz Jahanian <fjahanian@apple.com>
+
+ * configure.in: Test for PowerPC mfcr field support in assembler.
+ * config.in, configure: Regenderated.
+
+ * config/rs6000/power4.md: Add mfcrf reservation.
+ * config/rs6000/rs6000-protos.h (mfcr_operation): Declare.
+ * config/rs6000/rs6000.c (mfcr_operation): Define.
+ (print_operand): Add 'Q' case for mfcrf.
+ * config/rs6000/rs6000.h (TARGET_MFCRF): New.
+ * config/rs6000/rs6000.md (attribute "type"): Add mfcrf.
+ (movcc_internal1): Emit optional field operand for mfcr and set
+ "type" attribute appropriately.
+ (mfcr SCC): Likewise.
+ (movesi_from_cr_one): New.
+
+2003-07-07 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.md: Correct check-in of incorrect version.
+
+2003-07-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bitmap.c (debug_bitmap_file): Merge uses of HOST_PTR_PRINTF with
+ adjacent stdio calls.
+ * c-decl.c (c_print_identifier): Likewise.
+ * mips-tfile.c (write_varray, write_object, allocate_cluster): Likewise.
+ * print-rtl.c (print_rtx): Likewise.
+ * print-tree.c (print_node_brief, print_node): Likewise.
+ * system.h (HOST_PTR_PRINTF): Ensure we have a literal string.
+
+ * configure.in (AC_COMPILE_CHECK_SIZEOF): Check for `void *'.
+ * config.in, configure: Regenerated.
+
+2003-07-07 Roger Sayle <roger@eyesopen.com>
+
+ PR target/10979
+ * config/i386/i386.md (atan2df3, atan2sf3, atan2xf3, atan2tf3):
+ Changed to define_expand patterns that copy operand[1] to prevent
+ it from being clobbered before emitting an atan2?f3_1 insn.
+ (atan2df3_1, atan2sf3_1, atan2xf_1, atan2tf3_1): New define_insn
+ patterns that actually specify the behaviour of x87's FPATAN.
+
+2003-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Remove bogus
+ clearing of SYMBOL_FLAG_LOCAL bit.
+ If vcall_offset fits into signed 16-bit immediate, use
+ one instruction for both addition and load.
+
+2003-07-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (common_handle_option): Correct handling of the
+ -falign- switches that do and don't take an argument.
+
+2003-07-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (pushqi1_h8300hs): Revert my patch
+ today.
+ (pushhi1_h8300hs): Likewise.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * genextract.c: Convert remaining prototypes to ISO C90.
+
+ * cpplex.c (_cpp_free_buff): Convert prototype to ISO C90.
+ * fold-const.c (fold_single_bit_test): Likewise.
+ * diagnostic.c (default_diagnostic_finalizer): Likewise.
+ * cfgrtl.c (rtl_redirect_edge_and_branch): Likewise.
+
+ * gengtype.c (write_array): Generate ISO C90 prototypes.
+
+ * genflags.c (gen_proto): Generate ISO C90 prototypes.
+
+2003-07-07 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11059
+ * expr.c (can_store_by_pieces): Return true if length is zero.
+ (store_by_pieces): If length is zero and endp is two, abort,
+ othwerise, if length is zero and endp is not two, return "to".
+ (clear_by_pieces): Do nothing if length is zero.
+ (clear_storage): Do nothing if length is zero.
+ (store_constructor): Simplify code when size is zero, or the
+ target has already been cleared. This avoids emitting a
+ blockage instruction when initializing empty structures.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * mips-tfile.c: Convert prototypes to ISO C90.
+ * mips-tdump.c: Convert prototypes to ISO C90.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (emit_line_note): Take a location_t.
+ (emit_line_note_force): Remove.
+ (set_file_and_line_for_statement): Take a location_t.
+ * tree.g (emit_line_note): Take a location_t.
+ * emit-rtl.c (emit_line_note): Take a location_t.
+ (emit_line_note_force): Remove.
+ * function.c (init_function_start): Adjust emit_line_note call.
+ (expand_function_end): Use force_next_line_note, not
+ emit_line_note_force.
+ * c-parse.in (maybe_type_qual): Adjust emit_line_note calls.
+ * c-semantics.c (genrtl_do_pushlevel, genrtl_goto_stmt,
+ genrtl_expr_stmt_value, genrtl_decl_stmt, genrtl_if_stmt,
+ genrtl_while_stmt, genrtl_do_stmt_1, genrtl_return_stmt,
+ genrtl_for_stmt, genrtl_break_stmt, genrtl_continue_stmt,
+ genrtl_continue_stmt, genrtl_switch_stmt,
+ genrtl_asm_stmt): Likewise.
+ * expr.c (expand_expr): Likewise.
+ * integrate.c (expand_inline_function): Likewise.
+ * stmt.c (set_file_and_line_for_stmt): Take a location_t.
+ (expand_decl_init): Adjust emit_line_note call.
+
+2003-07-07 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/darwin-tramp.asm: Fix trampolines. PR 10900.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/i386-protos.h: Convert prototypes to ISO C90.
+ * config/i386/i386.c: Likewise.
+
+2003-07-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Use gen_int_mode instead of
+ GEN_INT (trunc_int_for_mode (...)).
+
+2003-07-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (pushqi1_h8300hs): Optimize by pushing
+ 2 bytes and then subtract 2 from the stack pointer.
+ (pushhi1_h8300hs): Likewise.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * configure.in (enable_coverage): Remove -DSELF_COVERAGE, add
+ -frandom-seed.
+ * configure: Regenerated.
+ * Makefile.in: Remove extraneous comment.
+ * toplev.c (randomize): Protect against potential multiple calls.
+ * doc/invoke.texi (-frandom-seed): Document use for in coverage
+ files.
+
+2003-07-07 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11198
+ * alias.c (objects_must_conflict_p): Return 1 if the types have
+ the same alias set, not if the alias sets only conflict.
+
+2003-07-07 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cppcharset.c (ICONV_CONST): Define iff !HAVE_ICONV.
+ (convert_cset): Change inbuf to type ICONV_CONST char.
+ * Makefile.in (LIBS): Add LIBICONV.
+
+ * doc/invoke.texi (-falign-functions): Document that
+ when n is zero then a machine-dependent default is used.
+ (-falign-labels): Document that when n is zero then a
+ machine-dependent default is used and that -falign-labels =1
+ is equivalent to -fno-align-labels.
+ (-falign-loops): Likewise.
+ (-falign-jumps): Likewise.
+
+2003-07-06 Art Haas <ahaas@airmail.net>
+
+ * f/global.c (ffeglobal_type_string_): Fix obsolete GCC array
+ initializer syntax.
+
+2003-07-06 James E Wilson <wilson@tuliptree.org>
+
+ PR optimization/9812
+ * rtl.h (mem_for_const_double): Delete prototype.
+ * varasm.c (mem_for_const_double): Delete function.
+ * config/m68k/hp320.h, config/m68k/linux.h, config/m68k/m68kelf.h,
+ config/m68k/m68kv4.h, config/m68k/netbsd-elf.h
+ (LEGITIMATE_PIC_OPERAND_P): Delete duplicate definitions.
+ * config/m68k/m68k.h (LEGITIMATE_CONSTANT_P): Disallow XFmode.
+ (LEGITIMATE_PIC_OPERAND_P): Delete CONST_DOUBLE tests.
+ * config/m68k/m68k.md (movxf): Add reload_in_progress guard. Add
+ comment about confused support for XFmode constants.
+
+2003-07-07 Jan Hubicka <jh@suse.cz>
+
+ * cfglayout.c (fixup_reorder_chain): Call delete_dead_jumptables.
+
+2003-07-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Fix comment typos.
+ * config/h8300/h8300.md: Likewise.
+ * config/i386/athlon.md: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/pentium.md: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/ia64/itanium1.md: Likewise.
+ * config/ia64/itanium2.md: Likewise.
+ * config/m32r/m32r.md: Likewise.
+ * config/m68hc11/m68hc11.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mips/sr71k.md: Likewise.
+ * config/mips/t-iris5-as: Likewise.
+ * config/mmix/mmix.h: Likewise.
+ * config/ns32k/ns32k.h: Likewise.
+ * config/ns32k/NOTES: Fix a typo.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * stmt.c: Convert remaining prototypes to ISO C90.
+ * cfglayout.c: Likewise.
+ * dbxout.c: Likewise.
+ * gcc.c: Likewise.
+ * genemit.c: Likewise.
+
+ * basic-block.h: Convert prototypes to ISO C90.
+ * c-parse.in: Likewise.
+ * c-pragma.h: Likewise.
+ * c-typeck.c: Likewise.
+ * cfghooks.h: Likewise.
+ * cfgloopanal.c: Likewise.
+ * dbxout.h: Likewise.
+ * debug.h: Likewise.
+ * dwarf2asm.h: Likewise.
+ * gcov.c: Likewise.
+ * gengtype-lex.l: Likewise.
+ * sched-int.h: Likewise.
+ * timevar.c: Likewise.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (c_comon_handle_filename,
+ c_common_missing_arguement): New.
+ * c-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): New.
+ * c-opts.c (missing_arg): Rename c_common_missing_argument,
+ update to be an appropriate langhook.
+ (c_common_handle_option): Don't handle filenames.
+ (c_common_handle_filename): New.
+ * hooks.c (hook_void_constcharptr,
+ hook_bool_constcharptr_size_t_false): New.
+ * hooks.h (hook_void_constcharptr,
+ hook_bool_constcharptr_size_t_false): New.
+ * langhooks-def.h (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): New.
+ (LANG_HOOKS_INITIALIZER): Update.
+ * langhooks.h (struct lang_hooks): Add handle_filename and
+ missing_argument.
+ * opts.c (handle_option): Don't handle filenames here, but ...
+ (handle_options): ... here.
+ (common_handle_option): Don't handle missing arguments here.
+ * objc/objc-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): New.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makfile.in: Remove traces of mbchar.
+ * c-parse.in (MULTIBYTE_CHARS): Remove.
+ * config.in (MULTIBYTE_CHARS): Remove.
+ * configure: Remove --enable-mbchar.
+ * configure.in: Remove --enable-mbchar.
+ * mbchar.c, mbchar.h: Remove.
+ * system.h: Poison MULTIBYTE_CHARS.
+ * config/linux-aout.h (MULTIBYTE_CHARS): Remove.
+ * config/linux.h (MULTIBYTE_CHARS): Remove.
+ * config/svr4.h (MULTIBYTE_CHARS): Remove.
+ * config/sparc/linux.h (MULTIBYTE_CHARS): Remove.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * varray.c (varray_check_failed): Fix typo.
+
+ * unroll.c: Convert prototypes to ISO C90.
+ * varasm.c: Likewise.
+ * varray.c: Likewise.
+ * varray.h: Likewise.
+ * vmsdbgout.c: Likewise.
+ * xcoffout.c: Likewise.
+ * xcoffout.h: Likewise.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h: Add a local time stamp.
+ (struct gcov_info): Add stamp field.
+ (gcov_truncate): New.
+ * coverage.c (read_counts_file): Skip the stamp.
+ (coverage_begin_output): Write the stamp.
+ (build_gcov_info): Declare and init the stamp.
+ (coverage_finish): Only unlink data file, if stamp is zero.
+ * gcov-dump.c (dump_file): Dump the stamp.
+ * gcov.c (bbg_stamp): New.
+ (release_structures): Clear bbg_stamp.
+ (read_graph_file): Read stamp.
+ (read_count_file): Check stamp.
+ * libgcov.c (gcov_exit): Check stamp and truncate if needed.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (default_flag_random_seed): Remove.
+ * toplev.h (local_tick): Declare.
+ * tree.c (flag_random_seed, default_flag_random_seed): Move to
+ toplev.c.
+ (append_random_chars): Don't call default_flag_random_seed.
+ * toplev.c (flag_random_seed): Define here. Set local_tick.
+ (local_tick): Define.
+ (randomize): New, moved from tree.c.
+ (print_switch_values): Adjust.
+ (toplev_main): Call randomize.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (crc32_string): Declare.
+ * tree.c (append_random_chars): Remove.
+ (crc32_string): New.
+ (get_file_function_name_long): Use crc32_string here.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * gcc.c: Convert prototypes to ISO C90.
+ * gcc.h: Likewise.
+ * gcov-dump.c: Likewise.
+ * gcov-iov.c: Likewise.
+ * gcse.c: Likewise.
+ * genattrtab.h: Likewise.
+ * ggc.h: Likewise.
+ * global.c: Likewise.
+ * graph.c: Likewise.
+ * graph.h: Likewise.
+ * hosthooks.h: Likewise.
+ * hooks.h: Likewise.
+ * hooks.c: Likewise.
+ * hashtable.h: Likewise.
+ * hashtable.c: Likewise.
+ * haifa-sched.c: Likewise.
+ * integrate.h: Likewise.
+ * integrate.c: Likewise.
+ * input.h: Likewise.
+ * ifcvt.c: Likewise.
+ * jump.c: Likewise.
+ * langhooks-def.h: Likewise. Add extern to prototypes.
+ * langhooks.c: Likewise.
+ * langhooks.h: Likewise.
+ * lcm.c: Likewise.
+ * local-alloc.c: Likewise.
+ * loop-init.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop-unswitch.c: Likewise.
+ * loop.c: Likewise.
+ * loop.h: Likewise. Add extern to prototypes.
+ * machmode.h: Likewise.
+ * main.c: Likewise.
+ * mbchar.c: Likewise.
+ * mbchar.h: Likewise.
+ * mkdeps.c: Likewise.
+ * mkdeps.h: Likewise.
+ * optabs.c: Likewise.
+ * optabs.h: Likewise.
+ * output.h: Likewise.
+ * gccspec.c: Likwise.
+ * postreload.c: Likewise.
+ * prefix.c: Likewise.
+ * prefix.h: Likewise.
+ * print-rtl.c: Likewise.
+ * print-tree.c: Likewise.
+ * profile.c: Likewise.
+ * read-rtl.c: Likewise.
+ * real.c: Likewise.
+ * real.h: Likewise.
+ * recog.c: Likewise.
+ * recog.h: Likewise.
+ * reg-stack.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * regrename.c: Likewise.
+ * regs.h: Likewise.
+ * reload.c: Likewise.
+ * reload.h: Likewise.
+ * reload1.c: Likewise.
+ * reorg.c: Likewise.
+ * resource.c: Likewise.
+ * resource.h: Likewise.
+ * rtl-error.c: Likewise.
+ * rtl.c: Likewise.
+ * rtl.h: Likewise.
+ * rtlanal.c: Likewise.
+ * sbitmap.c: Likewise.
+ * sbitmap.h: Likewise.
+ * scan-decls.c: Likewise.
+ * scan.c: Likewise.
+ * sched-deps.c: Likewise.
+ * sched-ebb.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-rgn.c: Likewise.
+ * sched-vis.c: Likewise.
+ * sibcall.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * sreal.c: Likewise.
+ * sreal.h: Likewise.
+ * ssa-ccp.c: Likewise.
+ * ssa-dce.c: Likewise.
+ * ssa.c: Likewise.
+ * ssa.h: Likewise.
+ * stack.h: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * stringpool.c: Likewise.
+ * target.h: Likewise.
+ * timevar.c: Likewise.
+ * timevar.h: Likewise.
+ * tlink.c: Likewise.
+ * tracer.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-inline.h: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (nonzero_bits1): Fix a warning.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_mov_length): Correct the
+ length of loading CONST0_RTX (SFmode).
+
+2003-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * toplev.c (output_clean_symbol_name): Remove.
+ * toplev.h (output_clean_symbol_name): Remove.
+ * config/alpha/alpha.c (unicosmk_output_module_name): Use
+ lbasename & clean_symbol_name.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ggc.h: Follow spelling conventions.
+ * config/i386/i386.c: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bt-load.c: Fix comment typos.
+ * c-incpath.c: Likewise.
+ * cfg.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfgloop.h: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * diagnostic.h: Likewise.
+ * dwarfout.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * et-forest.c: Likewise.
+ * et-forest.h: Likewise.
+ * expr.c: Likewise.
+ * gcse.c: Likewise.
+ * genattr.c: Likewise.
+ * jump.c: Likewise.
+ * langhooks.h: Likewise.
+ * local-alloc.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop-unswitch.c: Likewise.
+ * ra-build.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * rtl.def: Likewise.
+ * rtlanal.c: Likewise.
+ * sched-ebb.c: Likewise.
+ * sched-rgn.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * ssa.c: Likewise.
+ * tracer.c: Likewise.
+ * tree.c: Likewise.
+
+2003-07-05 Zack Weinberg <zack@codesourcery.com>
+
+ * cppcharset.c: Use the correct return type for the fallback iconv
+ macro.
+
+2003-07-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ Blame to Jan Hubicka <jh@suse.cz>
+ * cfglayout.c (record_effective_endpoints): Split insns before
+ first basic block correctly.
+
+2003-07-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr, case COMPONENT_REF): When seeing if should use
+ bitfield operations, use STRICT_ALIGNMENT, not SLOW_UNALIGNED_ACCESS
+ if EXPAND_CONST_ADDRESS or EXPAND_INITIALIZER.
+
+2003-07-05 Andreas Jaeger <aj@suse.de>
+
+ * genattrtab.c (write_attr_get): Revert part of last patch to
+ always write out a prototype.
+
+ * genemit.c (gen_split): Readd lost unused attributes in last
+ patch.
+
+2003-07-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (force_single_succ_latches): Force latch to be
+ different from header.
+
+2003-07-05 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.c: Remove code protected by CRDS.
+ * config/m68k/m68k.md: Likewise.
+
+2003-07-05 Neil Booth <neil@daikokuya.co.uk>
+
+ PR driver/11417
+ * c-opts.c (permit_fortran_options): New.
+ (c_common_init_options): Accept fortran front end options if
+ it looks like we might be preprocessing Fortran.
+ (c_common_handle_option): Don't reject switch if permit_fotran_options.
+
+2003-07-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattr.c (internal_dfa_insn_code): Output prototype.
+ * genattrtab.c: Don't output unnecessary decls, output in ISO C.
+ * genautomata.c: Likewise.
+ * genconditions.c: Likewise.
+ * genemit.c: Likewise.
+ * genextract.c: Likewise.
+ * gengenrtl.c: Likewise.
+ * gengtype.c: Likewise.
+ * genopinit.c: Likewise.
+ * genoutput.c: Likewise.
+ * genpeep.c: Likewise.
+ * genrecog.c: Likewise.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * cpplib.h (CPP_AT_NAME, CPP_OBJC_STRING): New token types.
+ (struct cpp_options): Add narrow_charset, wide_charset,
+ bytes_big_endian fields. Remove EBCDIC field.
+ (cpp_init_iconv, cpp_interpret_string): New external interfaces.
+
+ * cpphash.h: Include <iconv.h> if we have it, otherwise
+ provide a dummy definition of iconv_t.
+ (struct cpp_reader): Add narrow_cset_desc and wide_cset_desc fields.
+ (_cpp_valid_ucn): Update prototype.
+ (_cpp_destroy_iconv): New prototype.
+
+ * doc/cpp.texi: Document character set handling.
+ * doc/cppopts.texi: Document -fexec-charset= and -fexec-wide-charset=.
+ * doc/extend.texi: Delete entire section on multiline strings.
+ Rewrite section on __FUNCTION__ etc now that these are
+ variables in C.
+
+ * cppucnid.tab, cppucnid.pl: New files.
+ * cppucnid.h: New generated file.
+ * cppcharset.c: Include cppucnid.h. Lots of commentary added.
+ (iconv_open, iconv, iconv_close): Provide dummy definitions
+ if !HAVE_ICONV.
+ (SOURCE_CHARSET, struct strbuf, init_iconv_desc, cpp_init_iconv,
+ _cpp_destroy_iconv, convert_cset, width_to_mask, convert_ucn,
+ emit_numeric_escape, convert_hex, convert_oct, convert_escape,
+ cpp_interpret_string, narrow_str_to_charconst,
+ wide_str_to_charconst): New.
+ (ucn_valid_in_identifier): Use a binary search through the
+ ucnranges table defined in cppucnid.h, not a long chain of if
+ statements.
+ (_cpp_valid_ucn): Add a limit pointer. Downgrade "universal
+ character names are only valid in C++ and C99" to a warning.
+ Issue the "meaning of \[uU] is different in traditional C"
+ warning here. Take care not to let iconv see an invalid UCS
+ value if we get a malformed UCN. Issue an error if we don't
+ have iconv.
+ (cpp_interpret_charconst): Moved here from cpplex.c. Use
+ cpp_interpret_string to do the heavy lifting.
+
+ * cppinit.c (cpp_create_reader): Initialize bytes_big_endian,
+ narrow_charset, wide_charset fields of options structure.
+ (cpp_destroy): Call _cpp_destroy_iconv.
+ * cpplex.c (forms_identifier_p): Adjust call to _cpp_valid_ucn.
+ (maybe_read_ucn, hex_digit_value, cpp_parse_escape): Delete.
+ (cpp_interpret_charconst): Moved to cppcharset.c.
+ * cpplib.c (dequote_string): Delete.
+ (interpret_string_notranslate): New.
+ (do_line, do_linemarker): Use interpret_string_notranslate.
+
+ * Makefile.in (cppcharset.o): Depend on cppucnid.h.
+
+ * c-common.c (fname_string, combine_strings): Delete.
+ * c-common.h (fname_string, combine_strings): Delete prototypes.
+ * c-lex.c (ignore_escape_flag): Delete.
+ (cb_ident): Use cpp_interpret_string, not lex_string.
+ (get_nonpadding_token): New function.
+ (c_lex): Handle Objective-C @-prefixed identifiers and strings here.
+ Adjust calls to lex_string. Don't write *value twice.
+ (lex_string): Now handles string constant concatenation.
+ Most of the work handed off to cpp_interpret_string.
+ Call fix_string_type here.
+ * c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): Replace with
+ FUNC_NAME, throughout.
+ (OBJC_STRING): New token type.
+ (primary:STRING): No need to call fix_string_type here.
+ (primary:objc_string): Make that OBJC_STRING.
+ (objc_string nonterminal): Delete.
+ (yylexname): Delete code to handle fake string constants.
+ (yylexstring): Delete entirely.
+ (_yylex): Handle CPP_AT_NAME and CPP_OBJC_STRING. No need
+ to handle CPP_ATSIGN.
+
+ * c.opt (-fexec-charset=, -fwide-exec-charset=): New options.
+ * c-opts.c (missing_arg, c_common_handle_option): Handle
+ OPT_fexec_charset_ and OPT_fwide_exec_charset_.
+ (c_common_init): Set cpp_opts->bytes_big_endian, not
+ cpp_opts->EBCDIC. Call cpp_init_iconv.
+ (print_help): Document -fexec-charset= and -fexec-wide-charset=.
+ (TARGET_EBCDIC): Delete default definition.
+
+ * objc/objc-act.c (build_objc_string_object): No need to
+ handle string constant concatenation.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/pa/fptr.c: Fix comment typos.
+ * config/pa/pa-64.h: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/pa/pa.h: Likewise.
+ * config/rs6000/603.md: Likewise.
+ * config/rs6000/7xx.md: Likewise.
+ * config/rs6000/darwin.h: Likewise.
+ * config/rs6000/freebsd.h: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+ * config/rs6000/spe.h: Likewise.
+
+2003-07-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/2064.md: Change GNU CC to GCC.
+ * config/s390/2084.md: Likewise.
+ * config/s390/fixdfdi.h: Likewise.
+ * config/s390/linux.h: Likewise.
+ * config/s390/s390-modes.def: Likewise.
+ * config/s390/s390-protos.h: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/s390/s390.h: Likewise.
+ * config/s390/s390.md: Likewise.
+ * config/s390/s390x.h: Likewise.
+
+2003-07-04 Jeff Law <law@redhat.com>
+
+ PR c/11428
+ * expr.c (do_store_flag): Pass in the correct result type
+ when calling fold_single_bit_test.
+ * fold-const.c (fold_single_bit_test): Use result_type for the
+ result when folding a sign bit test.
+
+2003-07-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (common_handle_options): Negate sense of -falign- switches.
+
+2003-07-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.in: Replace PWD with PWD_COMMAND.
+
+2003-07-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopanal.c (count_strange_loop_iterations): New static function.
+ (constant_iterations, count_loop_iterations, simple_loop_exit_p):
+ Handle strange loops.
+
+2003-07-04 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * install.texi: Even the g77 manpage is derived from
+ the full g77 manual.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * ABOUT-NLS: Delete.
+ * intl: Delete entire directory.
+ * aclocal.m4: Include ../config/gettext.m4. Delete
+ AC_ISC_POSIX, AM_LANGINFO_CODESET, jm_GLIBC21, AM_LC_MESSAGES,
+ AM_PATH_PROG_WITH_TEST, AM_WITH_NLS, and AM_GNU_GETTEXT.
+ * configure.in: Use CY_GNU_GETTEXT, not AM_GNU_GETTEXT.
+ Remove intl/Makefile from all_outputs.
+ * configure, config.in: Regenerate.
+ * Makefile.in: Expunge all references to intl subdirectory.
+ Add -I../intl to INCLUDES.
+ * intl.h: Include libintl.h if and only if ENABLE_NLS is defined.
+
+2003-07-04 Roger Sayle <roger@eyesopen.com>
+
+ * config/rs6000/aix51.h (TARGET_C99_FUNCTIONS): Define.
+ * config/rs6000/aix52.h (TARGET_C99_FUNCTIONS): Likewise.
+
+2003-07-04 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/5287, PR c++/7910, PR c++/11021
+ * config/i386/winnt.c (ix86_handle_dll_attribute): Don't add
+ dllimport attribute if function is defined at declaration, but
+ report error instead. Likewise for dllimport'd variable
+ definitions. Set implicit TREE_PUBLIC for dllimport'd variables
+ declared within functions, Report error if dllimport or dllexport
+ symbol is not global.
+ (i386_pe_dllimport_p): Ignore dllimport attribute of functions
+ if defined after declaration or if inlined. Don't allow definition
+ of static data members of C++ classes. Don't dllimport virtual
+ methods.
+ (i386_pe_mark_dllexport): Warn about inconsistent dll attributes.
+ (i386_pe_mark_dllimport): Remove unnecessary checks.
+ (i386_pe_encode_section_info): Warn if the dllimport attribute
+ and symbol prefix have been instantiated and then overridden.
+
+ * doc/extend.texi: Document dllimport and dllexport attributes.
+
+ * config/i386/winnt.c (i386_pe_output_labelref): Fix indents.
+
+2003-07-03 Uwe Stieber <uwe@kaos-group.de>
+
+ * config/kaos.h (CPP_PREDEFINES): Delete.
+ (TARGET_OS_CPP_BUILTINS): New.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-aux-info.c: Include toplev.h after c-tree.h.
+ * c-common.c: Likewise.
+ (GCC_DIAG_STYLE): Undef.
+ * c-semantics.c (GCC_DIAG_STYLE): Define.
+ * c-tree.h (GCC_DIAG_STYLE): Likewise.
+ * diagnostic.h (inform): Move prototype to toplev.h.
+ * jump.c: Include diagnostic.h before toplev.h.
+ * toplev.h (GCC_DIAG_STYLE, ATTRIBUTE_GCC_DIAG): Define.
+ (warning, error, fatal_error, pedwarn, sorry, inform,
+ error_for_asm, warning_for_asm): Mark with ATTRIBUTE_GCC_CXXDIAG.
+
+2003-07-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfglayout.c (cfg_layout_duplicate_bb): Do not update frequencies
+ at all if edge is not specified.
+ (can_copy_bbs_p, copy_bbs): New.
+ * cfglayout.h (can_copy_bbs_p, copy_bbs): Declare.
+ * cfgloop.c (get_loop_body): Comment more precisely.
+ * cfgloopmanip.c (copy_bbs, record_exit_edges): Removed.
+ (scale_bbs_frequencies): Fix comment typo.
+ (can_duplicate_loop_p): Use can_copy_bbs_p.
+ (duplicate_loop_to_header_edge): Simplify by using copy_bbs.
+
+2003-07-03 Devang Patel <dpatel@apple.com>
+
+ * c-opts.c (c_common_parse_file): Remove extra
+ debug_hooks->start_source_file call.
+
+2003-07-03 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_trunc, real_floor, real_ceil): New functions
+ to implement trunc, floor and ceil respectively.
+ * real.h (real_trunc, real_floor, real_ceil): Prototype here.
+ * builtins.c (integer_valued_real_p): New function to test if
+ a floating point expression has an integer valued result.
+ (fold_trunc_transparent_mathfn): Optimize foo(foo(x)) as
+ foo(x) where foo is an integer rounding function. Similarly,
+ optimize foo(bar(x)) as bar(x), and foo((double)(int)x) as
+ (double)(int)x when both foo and bar are integer rounding
+ functions and we don't need to honor errno.
+ (fold_builtin_trunc, fold_builtin_floor, fold_builtin_ceil):
+ New functions to fold trunc, floor and ceil.
+ (fold_builtin): Use fold_builtin_trunc to fold BUILT_IN_TRUNC*,
+ fold_builtin_floor to fold BUILT_IN_FLOOR* and fold_builtin_ceil
+ to fold BUILT_IN_CEIL*.
+ * fold-const.c (tree_expr_nonnegative_p): Handle FLOAT_EXPR and
+ the remaining integer rounding functions.
+
+2003-07-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_partial_nregs): Use
+ SPARC_INT_ARG_MAX to determine where to split unnamed
+ complex FP arguments.
+
+2003-07-03 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (create_basic_block, merge_blocks_nomove): Kill.
+ * cfgcleanup.c (merge_blocks): Rename to merge_blocks_move.
+ (merge_blocks_move_predecessor_nojumps,
+ merge_blocks_move_successor_nojumps): Use merge_blocks.
+ (try_optimize_cfg): Use merge_blocks_move.
+ * cfgrtl.c (create_basic_block): Rename to rtl_create_basic_block.
+ (merge_blocks_nomove): Rename to rtl_merge_blocks.
+ (cfg_layout_create_basic_block): New.
+ (rtl_can_merge_blocks): New.
+ (cfg_layout_split_block): Do not alloc aux by hand.
+ * cfghooks.h (cfg_hooks): Add create_basic_block, can_merge_blocks_p,
+ merge_blocks.
+ (create_basic_block, can_merge_blocks_p, merge_blocks): New macros.
+ * cfglayout.c (cfg_layout_duplicate_bb): Do not allocate aux by hand.
+ * cfgloopmanip.c (loop_split_edge_with): Likewise.
+ * ifcvt.c (merge_if_block): Use merge_blocks_nomove.
+
+ * basic-block.h (basic_block_def): Add field 'rbi'.
+ * bb-reorder.c (find_traces, rotate_loop, mark_bb_visited,
+ find_traces_1_round, copy_bb, connect_traces): Update use of rbi.
+ * cfg.c (entry_exit_blocks): Add new field.
+ * cfglayout.c: Include alloc-pool.h;
+ (cfg_layout_pool): New.
+ (record_effective_endpoints, fixup_reorder_chain,
+ fixup_fallthru_exit_predecessor, cfg_layout_duplicate_bb): Update use
+ of rbi.
+ (cfg_layout_initialize_rbi): New function.
+ (cfg_layout_initialize): Use it.
+ (cfg_layout_finalize): Clear rbi fields.
+ * cfglayout.h (RBI): Kill.
+ (cfg_layout_initialize_rbi): Declare.
+ * cfgloopmanip.c (copy_bbs): Use rbi.
+ (record_exit_edges): Likewise.
+ (duplicate_loop_to_header_edge): Likewise.
+ * cfgrtl.c (cfg_layout_create_basic_block): Use
+ cfg_layout_initialize_rbi.
+ (cfg_layout_split_block): Use rbi.
+ (cfg_layout_delete_block): Likewise.
+ * loop-init.c (loop_optimizer_finalize): Likewise.
+ * loop-unswitch.c (unswitch_loop): Likewise.
+ * tracer.c (seen, tail_duplicate, layout_superblocks): Likewise.
+
+ * cfgrtl.c: Update comments.
+ (try_redirect_by_replacing_jump): New argument.
+ (redirect_branch_edge): Break out from ...
+ (rtl_redirect_edge_and_branch): ... this one.
+ (update_cfg_after_block_merging): Break out from ...
+ (rtl_merge_blocks): ... this one.
+ (cfg_layout_split_edge): New.
+ (cfg_layout_merge_blocks): New.
+ (cfg_layout_can_merge_blocks_p): New.
+ (cfg_layout_redirect_edge_and_branch): Reorganize.
+ (cfg_layout_rtl_cfg_hooks): Fill in.
+ (cfg_layout_delete_block): Kill barriers.
+ * cfganal.c (can_fallthru): Deal with exit blocks
+ * cfglayout.c (cfg_layout_function_header): New function
+ (record_effective_endpoints): Record function header.
+ (fixup_reorder_chain): Fixup dead jumptables; place header
+
+ * basic-block.h (CLEANUP_CFGLAYOUT): New flag.
+ * bb-reorder.c (cfg_layout_initialize): Update call.
+ * cfgcleanup.c (try_optimize_cfg): Supress optimizations of fallthru
+ edges in cfglayout mode.
+ * cfglayout.c (cleanup_unconditional_jumps): Kill.
+ (cfg_layout_initialize): Kill agrument loops; use cfgcleanup.
+ * cfglayout.h (cfg_layout_initialize): Update prototype.
+ * cfgloop.h (CP_INSIDE_CFGLAYOUT): Kill.
+ * cfgloopmanip.c (loop_split_edge_with): Use split_edge.
+ * flow.c (propagate_block): Do not crash when basic block ends
+ by first insn in the chain.
+ * loop-init.c (loop_optimizer_init): First enter cfglayout mode; later
+ do loop discovery.
+ * tracer.c (tracer): Update call of cfg_layout_initialize.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in: Use dependency variables in lieu of explicit
+ files throughout.
+
+2003-07-03 Steven Bosscher <steven@gcc.gnu.org>
+
+ * rtl.h (ECF_*, flags_from_decl_or_type): Move from here...
+ * tree.h: ...to here.
+
+2003-07-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/s390/2064.md: Fix comment typos.
+ * config/s390/2084.md: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/s390/s390.md: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sh/sh.md: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/sparc/sparc.md: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/stormy16/stormy-abi: Fix a typo.
+
+2003-07-03 Kelley Cook <kelleycook@wideopenwest.org>
+
+ * Makefile.in (ifcvt.o): Depend on OPTABS_H.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/mips.h (save_argv): Delete.
+
+2003-07-03 Roger Sayle <roger@eyesopen.com>
+
+ PR target/10700
+ * fold-const.c (extract_muldiv_1): There's nothing that can be done
+ if the expression is a SAVE_EXPR.
+
+2003-07-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c: Fix comment typos.
+ * config/m68hc11/m68hc11.c: Likewise.
+ * config/m68hc11/m68hc11.h: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore.md: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/mips/netbsd.h: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+
+2003-07-03 Andreas Schwab <schwab@suse.de>
+
+ * dbxout.c (pending_bincls): Move decl down inside
+ DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO section.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (NOTE_DATA): Refer to whole union.
+ * emit-rtl.c (emit_note): Use memset to clear NOTE_DATA.
+
+2003-07-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11381
+ * simplify-rtx.c (simplify_relational_operation): Check that
+ two equal operands have no side-effects before simplifying
+ the comparison.
+
+2003-07-02 Jeff Law <law@redhat.com>
+
+ * expr.c (do_store_flag): Remove special case folding for
+ single bit tests. Instead call back into the commonized folder
+ routine.
+ * fold-const.c (fold_single_bit_test): New function, mostly
+ extracted from do_store_flag, with an additional case extracted
+ from fold.
+ (fold): Call fold_single_bit_test appropriately.
+ * tree.h (fold_single_bit_test): Prototype.
+
+2003-07-02 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h: Include filenames.h.
+ (IS_DIR_SEPARATOR, IS_ABSOLUTE_PATHNAME): Don't define.
+ (DIR_SEPARATOR, DIR_SEPARATOR_2): If not already defined,
+ define based on HAVE_DOS_BASED_FILE_SYSTEM.
+ * config/i386/xm-cygwin.h, config/i386/xm-djgpp.h
+ * config/i386/xm-mingw32.h: Don't define
+ HAVE_DOS_BASED_FILE_SYSTEM,
+ DIR_SEPARATOR, or DIR_SEPARATOR_2.
+ * doc/hostconfig.texi: Update to match.
+
+ * cppfiles.c, gcc.c, gensupport.c, protoize.c,
+ config/i386/cygwin.h:
+ Use IS_ABSOLUTE_PATH throughout.
+ * gcc.c (DIR_UP): Delete, unused.
+ * protoize.c (IS_SAME_PATH): Define in terms of
+ FILENAME_CMP.
+ (is_abspath): Delete.
+
+2003-07-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/emmintrin.h: Fix comment typos.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/sco5.h: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/ia64/itanium2.md: Likewise.
+
+2003-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dbxout.c (pending_bincls): Replace DBX_USE_BINCLS with
+ DBX_USE_BINCL.
+ (emit_bincl_stab): Same.
+ (emit_pending_bincls): Same.
+
+2003-07-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_mov_length): Fix the length of
+ loading CONST0_RTX (SFmode).
+ * config/h8300/h8300.h (CONST_DOUBLE_OK_FOR_LETTER_P): Change
+ 'G' to CONST0_RTX (SFmode).
+ * config/h8300/h8300.md (movsf_h8300): Change the first
+ constraint to 'G'.
+ (movsf_h8300h): Likewise.
+
+2003-07-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (c_common_init_options): New prototype.
+ * c-opts.c (deferred_size): Remove.
+ (defer_opt): Array is now pre-allocated.
+ (c_common_init_options): Pre-allocate deferred_opts. Make
+ lang_flags unsigned.
+ (push_command_line_options): Free deferred_opts.
+ * hooks.c (hook_uint_uint_constcharptrptr_0): New.
+ * hooks.h (hook_uint_uint_constcharptrptr_0): New.
+ * langhooks-def.h (LANG_HOOKS_INIT_OPTIONS): Update.
+ * langhooks.h (struct lang_hooks): New prototype for init_options.
+ * main.c (main): Cast argv.
+ * opts.c (handle_option, handle_options): Update prototypes.
+ (decode_options): save_argc, save_argv are not global. Constify.
+ * opts.h (decode_options): New prototype.
+ * toplev.c (general_init): New protoype.
+ (save_argv): Make static.
+ (save_argc): Remove.
+ (print_switch_values, general_init): Constify.
+ (toplev_main): Save argv.
+ * toplev.h (toplev_main): Update prototype.
+ (save_argc, save_argv): Remove.
+
+2003-07-02 David Edelsohn <edelsohn@gnu.org>
+
+ * dbxout.c (pending_bincls): Guard with DBX_USE_BINCLS.
+ (emit_bincl_stab): Same.
+ (emit_pending_bincls): Same.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11072
+ * ginclude/stddef.h (offsetof): Remove cast to 'char &'. Explain why.
+
+2003-07-02 Andreas Schwab <schwab@suse.de>
+
+ * dbxout.c (pending_bincls): Only define if DBX_DEBUGGING_INFO.
+
+2003-07-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11210
+ * expr.c (handled_component_p) [NOP_EXPR]: Add ??? note
+ about the behaviour with regard to bitfields.
+ * fold-const (decode_field_reference): Record outermost type in
+ case the expression is a NOP. Strip all NOPs. Set the signedness
+ to that of the outermost type (if any) when the bitsize is equal
+ to the size of the type.
+
+2003-07-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (addsi3): Remove workaround for adds of -32768.
+ (addsi3_internal, adddi3, adddi3_internal_2): Likewise.
+ (adddi3_internal_3, addsi3_internal_2): Likewise.
+
+2003-07-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (machine_function): Add new fields:
+ ignore_hazard_length_p and all_noreorder_p.
+ (mips_flag_delayed_branch): New variable.
+ (override_options): Treat '/' as an operand punctuation character.
+ Set up mips_flag_delayed_branch.
+ (print_operand): Handle '/'.
+ (mips_output_function_prologue): Put the whole function in
+ .set noreorder and .set nomacro if all_noreorder_p is true.
+ (mips_output_function_epilogue): End the noreorder/nomacro sequence.
+ (mips16_optimize_gp): Remove "first insn" parameter.
+ (mips16_lay_out_constants): New function, split out from mips_reorg.
+ (mips_avoid_hazard, mips_avoid_hazards): New functions.
+ (mips_reorg): For mips16 code, call mips16_lay_out_constant
+ and (optionally) mips16_optimize. If TARGET_EXPLICIT_RELOCS,
+ do delayed-branch scheduling followed by hazard detection.
+ (mips_adjust_insn_length): Only account for hazards if
+ !ignore_hazard_length_p.
+ (mips_output_load_label): Add a nop to the o32 sequence if
+ the target suffers from load delays.
+ (mips_output_conditional_branch): Add %/ to the end of branches.
+ (mips_output_division): Fill the branch delay slot with %#.
+ * config/mips/mips.md: Remove redundant '%*' from mips16 branch
+ instructions. End all other %* branches with %/.
+ (ffssi2, ffsdi2): Fix lengths.
+ (truncdisi2, truncdihi2, truncdiqi2): Add store attributes.
+ (fix_truncdfsi2_macro): Turn off .set nomacro if appropriate.
+ (fix_truncsfsi2_macro): Likewise.
+ (mov_lwl): Set hazard to "none".
+ (ashldi3_internal): Fill the branch delay slot with %#.
+ (ashrdi3_internal, lshrdi3_internal): Likewise.
+ (exception_receiver): Explicitly set $28.
+ (hazard_nop): New pattern.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_unit): Set current_function_decl
+ before calling tree_inlinable_function_p.
+
+2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (irix_stdio_va_list): Apply to IRIX 6.5
+ <internal/stdio_core.h> too.
+ (stdio_va_list): Apply to IRIX 6.5 <internal/stdio_core.h> and
+ <internal/wchar_core.h> too.
+ Substitute va_list uses in inline definition.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5.h (SET_FILE_NUMBER): Moved here from iris3.h.
+ Undef before redefinition.
+ (LABEL_AFTER_LOC): Likewise.
+ (DEFAULT_SIGNED_CHAR): Likewise.
+ (ASM_OUTPUT_ASCII): Moved here from iris4.h.
+ Fix IRIX spelling.
+
+ * config/mips/iris3.h: Remove, unused.
+ * config/mips/iris4.h: Likewise.
+
+ * config/mips/mips.h (STACK_ARGS_ADJUST): Remove, unused.
+
+ * config/mips/iris5.h (TARGET_DEFAULT): Move ...
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): ... here to
+ target_cpu_default.
+
+ * config/mips/iris5.h: Move explicit includes ...
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): ... here.
+
+ * config/mips/iris6.h (MIPS_ISA_DEFAULT, MIPS_ABI_DEFAULT): Move ...
+ * config.gcc (mips-sgi-irix6*, mips-sgi-irix5cross64): ... here to
+ tm_defines.
+
+ * config/mips/iris6.h (TARGET_DEFAULT): Move ...
+ * config.gcc (mips-sgi-irix6*, mips-sgi-irix5cross64): ... here to
+ target_cpu_default.
+
+ * config/mips/iris6.h: Fix IRIX spelling.
+ (MULTILIB_DEFAULTS): Undef before redefinition.
+
+ * config/mips/iris6.h: Move explicit includes ...
+ * config.gcc (mips-sgi-irix6*, mips-sgi-irix5cross64): ... here.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_mark_needed_node, cgraph_varpool_mark_needed_node,
+ cgraph_varpool_finalize_decl, cgraph_varpool_assemble_pending_decls):
+ Use next_needed field instead of aux to maintain the queue.
+ * cgraph.h (cgraph_node): Add next_needed.
+ (cgraph_varpool_node): Add next_needed; remove aux.
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Use next_needed.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_function): Set finalized.
+ (cgraph_finalize_function): Do not examine inlinablility.
+ (cgraph_finalize_compilation_unit): Do it here.
+ * cgraph.h (cgraph_local_info): Add finalized field.
+
+2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * ggc-common.c (gt_pch_save): Cast MAP_FAILED to void *.
+ (gt_pch_restore): Likewise.
+
+2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c: Fix comment typos.
+ * config/alpha/elf.h: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/t-arm-coff: Likewise.
+ * config/arm/t-strongarm-pe: Likewise.
+ * config/arm/xscale-elf.h: Likewise.
+ * config/avr/avr.h: Likewise.
+
+2003-07-01 Jeff Law <law@redhat.com>
+
+ * stmt.c (any_pending_cleanups): Remove another redundant test.
+
+2003-07-01 David Edelsohn <edelsohn@gnu.org>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/rs6000/rs6000.md (ctr{s,d}i_internal?): Add earlyclobber
+ for MEM case.
+
+2003-07-01 Devang Patel <dpatel@apple.com>
+
+ * dbxout.c (DBXOUT_DECR_NESTING): Emit pending bincls, if required.
+ (binclstatus): New.
+ (struct dbx_file): New members - bincl_status, pending_bincl_name and
+ prev.
+ (pending_bincls): New.
+ (dbxout_init): Initialize new dbx_file members.
+ (dbxout_start_source_file): Same.
+ (emit_bincl_stab): New function.
+ (emit_pending_bincls): Same.
+ (emit_pending_bincls_if_required): Same.
+ (dbxout_end_source_file): Emit EINCL stab only if BINCL is already
+ processed.
+ (dbxout_begin_block): Emit pending BINCL stabs.
+ (dbxout_end_block): Same.
+ (dbxout_function_decl): Same.
+ (dbxout_continue): Same.
+ (dbxout_type): Same.
+ (dbxout_class_name_qualifiers): Same.
+ (dbxout_symbol): Same.
+ (dbxout_symbol_location): Same.
+ (dbxout_parms): Same.
+
+2003-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-semantics.c (genrtl_case_label): Fix format specifier bug.
+ * cfgrtl.c (rtl_verify_flow_info_1): Likewise.
+
+2003-07-01 Andreas Jaeger <aj@suse.de>
+
+ * fold-const.c: Convert prototypes to ISO C90.
+ * function.c: Likewise.
+ * function.h: Likewise.
+
+2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/contrib.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+ * doc/passes.texi: Likewise.
+ * doc/sourcebuild.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * basic-block.h: Fix comment typos.
+ * bb-reorder.c: Likewise.
+ * c-format.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfghooks.h: Likewise.
+ * cfgloop.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * cgraph.h: Likewise.
+ * cgraphunit.c: Likewise.
+ * combine.c: Likewise.
+ * convert.c: Likewise.
+ * dbxout.c: Likewise.
+ * df.c: Likewise.
+ * df.h: Likewise.
+ * diagnostic.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * et-forest.h: Likewise.
+ * flow.c: Likewise.
+ * fold-const.c: Likewise.
+ * function.h: Likewise.
+ * gcov-io.h: Likewise.
+ * gcov.c: Likewise.
+ * gcse.c: Likewise.
+ * genautomata.c: Likewise.
+ * ggc-common.c: Likewise.
+ * ggc-page.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop-unswitch.c: Likewise.
+ * loop.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * optabs.c: Likewise.
+ * ra-build.c: Likewise.
+ * ra-colorize.c: Likewise.
+ * ra-rewrite.c: Likewise.
+ * ra.h: Likewise.
+ * regmove.c: Likewise.
+ * reload.c: Likewise.
+ * rtlanal.c: Likewise.
+ * sched-ebb.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-vis.c: Likewise.
+ * sreal.c: Likewise.
+ * ssa-ccp.c: Likewise.
+ * ssa.c: Likewise.
+ * toplev.c: Likewise.
+ * tree-inline.c: Likewise.
+ * value-prof.c: Likewise.
+ * value-prof.h: Likewise.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (emit_line_note_after): Remove.
+ (emit_note_copy_after, emit_note_copy): New.
+ * emit-rtl.c (reorder_insns_with_line_notes): Replace
+ emit_line_note_after with emit_note_copy_after.
+ (emit_insn_after_with_line_notes): Likewise.
+ (emit_line_note_after): Kill.
+ (emit_note_copy_after): New.
+ (emit_note_copy): New.
+ * function.c (emit_return_into_block): Use emit_note_copy_after.
+ (thread_prologue_and_epilogue_insns): Likewise.
+ * integrate.c (expand_inline_function): Use emit_note_copy.
+ (copy_insn_list): Likewise.
+ * unroll.c (copy_loop_body): Likewise.
+ * cfglayout.c (duplicate_insn_chain): Likewise.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-tree.h (define_label): Replace filename and lineno arguments
+ with a location_t.
+ * c-decl.c (poplevel): Adjust define_label call.
+ (pop_label_level): Likewise.
+ (define_label): Replace filename and lineno arguments with a
+ location_t.
+ (store_parm_decls): Use DECL_SOURCE_LOCATION.
+ * c-parse.in (label): Adjust define_label call.
+
+2003-07-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/sol2.h, config/alpha/alpha.h, config/alpha/linux.h,
+ config/i386/i386-interix.h, config/ia64/hpux.h, config/mips/iris6.h,
+ config/mips/linux.h, config/mips/mips.h, config/pa/pa-hpux.h,
+ config/pa/pa-hpux10.h, config/pa/pa-hpux11.h, config/pa/pa-pro-end.h,
+ config/pa/pa.h, config/pa/rtems.h: Use c_dialect_ macros.
+
+2003-07-01 Andreas Jaeger <aj@suse.de>
+
+ * final.c: Convert prototypes to ISO C90.
+ * flow.c: Likewise.
+ * flags.h: Likewise.
+ * gcov-io.c: Likewise.
+ * gcov-io.h: Likewise.
+
+See ChangeLog.9 for earlier changes.
diff --git a/gcc/ChangeLog.11 b/gcc/ChangeLog.11
new file mode 100644
index 00000000000..92a4d69b804
--- /dev/null
+++ b/gcc/ChangeLog.11
@@ -0,0 +1,21016 @@
+2004-06-30 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a
+ constant as a sequence of additions depending upon the rtx_costs.
+ (synth_mult): Update the "observed" cost of a shift, based upon
+ the above optimization.
+
+2004-06-28 Geoffrey Keating <geoffk@apple.com>
+ Andreas Tobler <a.tobler@schweiz.ch>
+
+ PR 15813
+ * dwarf2out.c (reg_save): Output DW_CFA_same_value when a
+ register is saved in itself.
+ (initial_return_save): If the return address is a register,
+ it's already there, don't bother to mention it in the CFI.
+ (struct queued_reg_save): Add field saved_reg.
+ (struct reg_saved_in_data): New.
+ (regs_saved_in_regs): New.
+ (num_regs_saved_in_regs): New.
+ (queue_reg_save): Add extra parameter to specify register saved
+ in register. Remove duplicate entries from queue. Add comment
+ for function.
+ (flush_queued_reg_saves): Handle registers saved in registers.
+ Update regs_saved_in_regs. Add comment for function.
+ (clobbers_queued_reg_save): Add comment for function. Allow
+ for regs_saved_in_regs.
+ (reg_saved_in): New.
+ (dwarf2out_frame_debug_expr): Handle saving registers in other
+ registers.
+ (dwarf2out_frame_debug): Reset regs_saved_in_regs.
+ * unwind-dw2.c (execute_cfa_program): Correct handling of
+ DW_CFA_same_value. Add FIXME comment about incorrect implementation
+ of DW_CFA_restore_extended.
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Let
+ dwarf2out_frame_debug_expr see instructions that save registers
+ in other registers or save those other registers in memory.
+
+ * unwind-dw2.c (DWARF_FRAME_REGISTERS): Move to unwind-dw2.h.
+ (_Unwind_FrameState): Likewise.
+ * unwind-dw2.h: New.
+ * Makefile.in (LIB2ADDEHDEP): Add unwind-dw2.h.
+ * config/rs6000/darwin-fallback.c: New file.
+ * config/rs6000/darwin.h (MD_FALLBACK_FRAME_STATE_FOR): Define.
+ * config/rs6000/t-darwin (LIB2FUNCS_EXTRA): Add darwin-fallback.o.
+
+2004-07-01 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_mixed_function_arg): Rewrite.
+ (function_arg): Use rs6000_arg_size rather than CLASS_MAX_NREGS in
+ calculating gpr size for altivec. Simplify and correct
+ rs6000_mixed_function_arg calls. Call rs6000_mixed_function_arg
+ for ABI_V4 gpr case too. Fix off-by-one error in long double
+ reg test. Generate the correct PARALLEL to handle long double
+ for ABI_AIX 32-bit. Use this for -m32 -mpowerpc64 fpr case too.
+ (function_arg_partial_nregs): Align before calculating regs left.
+ Don't return info on partial fprs when we need info on gprs.
+ Correct long double fpr off-by-one error.
+
+2004-06-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-protos.h (prefetch_operand): Add prototype.
+ * pa.c (prefetch_operand): New function.
+ * pa.h (prefetch_operand): Add to PREDICATE_CODES.
+ * pa.md (prefetch, prefetch_32, prefetch_64): New prefetch patterns.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Remove x_whole_function_mode_p.
+ * c-decl.c (store_parm_decls): Don't set it.
+ * tree-optimize.c (tree_rest_of_compilation): Likewise.
+ * passes.c (rest_of_compilation): Don't check it.
+ * stmt.c (expand_fixup): Likewise.
+ * function.c (fixup_var_refs_insn): Remove unused variable.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * tree.h (immediate_size_expand): Delete.
+ * stor-layout.c (immediate_size_expand): Delete.
+ (variable_size): Don't look at it.
+ * c-decl.c (push_parm_decl): Don't frob immediate_size_expand.
+ (start_function): Likewise.
+ * cfgexpand.c (construct_exit_block): Likewise.
+ * function.c (init_function_start, expand_function_end): Likewise.
+ * tree-optimize.c (tree_rest_of_compilation): Likewise.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_compound_lval): Take fallback argument
+ instead of want_lvalue.
+ (gimplify_call_expr): Take want_value argument instead of test
+ function. Gimplify arguments to val only if reg_type; otherwise
+ allow lvalue forms.
+ (gimplify_expr): Update gimplify_compound_lval and gimplify_call_expr
+ calls.
+ * tree-gimple.c: Update GIMPLE grammer. Use true/false not 1/0.
+ Tidy commentary globally.
+ (get_call_expr_in): Remove RETURN_EXPR handling. Tidy.
+ * tree-gimple.h (is_gimple_call_addr): Mark extern.
+
+ * gimplify.c (gimplify_modify_expr_to_memcpy): Fix typo.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * tree-gimple.c (right_assocify_expr): Kill
+ (rationalize_compound_expr): Kill.
+ * tree-gimple.h: Likewise.
+ * tree-inline.c (expand_call_inline): Don't call it.
+
+ * function.h (struct function): Remove x_last_parm_insn,
+ inl_last_parm_insn.
+ (last_parm_insn): Remove.
+ * function.c (free_after_compilation): Don't clear them.
+ (fixup_var_refs_insn, assign_parms): Don't set them.
+
+ * function.c, rtl.h (get_first_nonparm_insn): Remove.
+
+2004-06-30 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-common.h (check_function_format): Remove first parameter.
+ * c-format.c (format_check_context): Remove status.
+ (check_format_info, check_format_info_main,
+ maybe_read_dollar_number, avoid_dollar_number,
+ finish_dollar_format_checking, check_format_types,
+ check_function_format): Remove first parameter. Don't use
+ status_warning.
+ (check_format_arg): Don't use status_warning.
+ (status_warning): Remove.
+ * c-common.c (check_function_arguments): Update call to
+ check_function_format.
+
+2004-06-30 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc-protos.h (output_cbranch): Constify return
+ value.
+ (output_v9branch): Likewise.
+ (sparc_v8plus_shift): Likewise. Rename into output_v8plus_shift.
+ * config/sparc/sparc.c (output_cbranch): Constify return value.
+ Prettify output for delay slots.
+ (output_v9branch): Likewise.
+ (sparc_v8plus_shift): Constify return value. Rename into
+ output_v8plus_shift.
+ * config/sparc/sparc.md (ashldi3_v8plus): Adjust call to
+ sparc_v8plus_shift.
+ (ashrdi3_v8plus): Likewise.
+ (lshrdi3_v8plus): Likewise.
+ (call_address_struct_value_sp32): Prettify output for delay slots.
+ (call_symbolic_struct_value_sp32): Likewise.
+ (call_address_untyped_struct_value_sp32): Likewise.
+ (call_symbolic_untyped_struct_value_sp32): Likewise.
+
+2004-06-30 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * common.opt (ftree-loop-optimize): New flag.
+ * tree-flow.h (kill_redundant_phi_nodes): Declare.
+ * tree-optimize.c (init_tree_optimization_passes): Add pass_loop.
+ * tree-pass.h (pass_loop_init, pass_loop_done): Declare.
+ * tree-ssa-loop.c (current_loops): New variable.
+ (tree_loop_optimizer_init, gate_loop, tree_ssa_loop_init,
+ tree_ssa_loop_done): New functions.
+ (pass_loop, pass_loop_init, pass_loop_done): New passes.
+ * tree-ssa.c (kill_redundant_phi_nodes): Export.
+ * doc/invoke.texi (-ftree-loop-optimize): Document.
+
+2004-06-30 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-loop-ch.c: New file.
+ * Makefile.in (tree-ssa-loop-ch.o): Add.
+ (tree-into-ssa.o): Add GGC_H dependency.
+ * tree-cfg.c (tree_duplicate_bb): Copy virtual arguments.
+ * tree-flow.h (rewrite_into_ssa): Declaration changed.
+ (rewrite_ssa_into_ssa, compute_global_livein, duplicate_ssa_name):
+ Declare.
+ * tree-into-ssa.c: Include ggc.h.
+ (struct def_blocks_d): Add phi_blocks field.
+ (struct mark_def_sites_global_data): Add names_to_rename field.
+ (struct ssa_name_info): New.
+ (compute_global_livein): Export.
+ (set_def_block, insert_phi_nodes, mark_def_sites, set_livein_block,
+ insert_phi_nodes_1, rewrite_finalize_block, insert_phi_nodes_for,
+ register_new_def, get_reaching_def, def_blocks_free,
+ get_def_blocks_for, rewrite_into_ssa): Modified to work with
+ rewrite_ssa_into_ssa.
+ (get_ssa_name_ann, get_phi_state, set_phi_state, get_current_def,
+ set_current_def, ssa_mark_def_sites_initialize_block,
+ ssa_mark_phi_uses, ssa_mark_def_sites, duplicate_ssa_name,
+ ssa_register_new_def, ssa_rewrite_initialize_block,
+ ssa_rewrite_phi_arguments, ssa_rewrite_finalize_block,
+ ssa_rewrite_stmt, rewrite_ssa_into_ssa, rewrite_all_into_ssa): New
+ functions.
+ (pass_build_ssa): Call rewrite_all_into_ssa.
+ * tree-optimize.c (execute_todo, execute_one_pass,
+ tree_rest_of_compilation): Allocate vars_to_rename only once.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Provide parameter
+ to rewrite_into_ssa.
+ * tree-ssa-loop.c (should_duplicate_loop_header_p,
+ mark_defs_for_rewrite, duplicate_blocks, do_while_loop_p,
+ copy_loop_headers, gate_ch, pass_ch): Moved to tree-ssa-loop-ch.c.
+ Use rewrite_ssa_into_ssa.
+ * tree-ssa-operands.c (copy_virtual_operands): New function.
+ * tree-ssa-operands.h (copy_virtual_operands): Declare.
+ * tree.h (struct tree_ssa_name): Add aux field.
+ (SSA_NAME_AUX): New macro to access it.
+
+2004-05-28 Aaron W. LaFramboise <aaronraolete36@aaronwl.com>
+
+ * prefix.c (lookup_key): Cast buffer to LPBYTE.
+
+2004-06-30 Per Bothner <per@bothner.com>
+
+ Conditionally compile support for --enable-mapped_location.
+ * input.h: #include line-map.h for source_location typedef.
+ (BUILTINS_LOCATION, UNKNOWN_LOCATION, expand_location,
+ LOCATION_FILE, LOCATION_LINE): New macros and functions.
+ (expanded_location, source_locus): New typedefs.
+ (push_srcloc): Change parameter list if USE_MAPPED_LOCATION.
+ * rtl.def (NOTE, ASM_OPERANDS): Modify specifcation, if
+ USE_MAPPED_LOCATION.
+ * rtl.h (NOTE_DELETED_LABEL_NAME): New macro.
+ (NOTE_SOURCE_LOCATION, NOTE_EXPNDED_LOCATION, SET_INSN_DELETED):
+ New conditional macros.
+ (ASM_OPERANDS_SOURCE_FILE, ASM_OPERANDS_SOURCE_LINE): Replace
+ by ASM_OPERANDS_SOURCE_LOCATION if USE_MAPPED_LOCATION.
+ * tree.h (EXPR_LOCATION, SET_EXPR_LOCATION, EXPR_HAS_LOCATION,
+ EXPR_LOCUS, SET_EXPR_LOCUS, EXPR_FILENAME, EXPR_LINENO,
+ DECL_IS_BUILTIN): New macros, most depending on USE_MAPPED__LOCATION.
+ (tree_exp): Change type of locus to use new source_locus typedef.
+ * tree.c (build1_stat): Use SET_EXPR_LOCATION.
+ (annotate_with_locus, annotate_with_file_line): Conditionalize.
+ (expand_location): New function.
+ * toplev.c (unknown_location): New static, when USE_MAPPED_LOCATION.
+ (push_srcloc, pop_loc): Adjust parameter handling.
+ (process_options): Don't set input_filename by itself.
+ (lang_dependent_init): Save, set input_location to <built-in>.
+ (warn_deprecated_use): Use expand_location.
+
+ * basic-block.h (struct edge_def): Use new source_locus typedef.
+ * c-common.c (fname_decl): Update save/clear/store of input_location.
+ (c_do_switch_warnings): Update for USE_MAPPED_LOCATION case.
+ * c-decl.c: Likewise.
+ * c-dump.c (dump_stmt): Likewise.
+ * c-gimplify.c (c-gimplify.c): Generalize using SET_EXPR_LOCATION.
+ * c-lex.c (cb_line_change): If USE_MAPPED_LOCATION use token's src_loc
+ to set input_location direction, rather than using linemap_lookup.
+ (fe_file_change, cb_def_pragma): Again use source_location directly.
+ * c-opts.c (saved_lineno): Remove static variable.
+ (c_common_post_options, c_common_init): Don't bothner to save,
+ clear and restore input_Location - now handled by lang_dependent_init.
+ * function.c (init_function_start): Use new DECL_IS_BUILTIN macro.
+ * xcoffout.c (xcoff_assign_fundamental_type_number): Likewise.
+ * tree-mudflap.c (mf_file_function_line_tree): Take a location_t
+ rather than a pointer to one. Use expand_location.
+ (mf_varname_tree): Use expand_location.
+ * tree-dump.c: Use expand_location on DECL_SOURCE_LOCATION.
+ * coverage.c: Likewise.
+ * print-tree.c: Likewise.
+ * c-aux-info.c (gen_aux_info_record): Likewise.
+ * c-parse.in: Use SET_EXPR_LOCATION macro.
+ * gimple-low.c: Likewise.
+ * tree-mudflap.c: Likewise.
+ * gimplify.c: Likewise. Also use EXPR_LOCATION and EXPR_HAS_LOCATION.
+ * c-ppoutput.c: Use new source_location typedef instead of fileline.
+ * c-semantics.c: Use new macros.
+ * c-typeck.c: Likewise.
+ * cfgexpand.c: Handle USE_MAPPED_LOCATION case for function_end_locus.
+ * cfglayout.c (insn_locators_initialize): Const cleanup. New macros.
+ * cfgrtl.c (delete_insn): Use new NOTE_DELETED_LABEL_NAME macro.
+ * print-rtl.c (print_rtx): Likewise.
+ * emit-rtl.c: Don't clear NOTE_SOURCE_FILE if USE_MAPPED_LOCATION.
+ * combine.c: Use new SET_INSN_DELETED macro.
+ * flow.c: Likewise.
+ * haifa-sched.c: Likewise.
+ * ifcvt.c: Likewise.
+ * recog.c: Likewise.
+ * reload1.c: Likewise.
+ * diagnostic.c: Use expand_location macro.
+ * pretty-print.c (pp_base_format_text): Likewise.
+ * profile.c: Likewise.
+ * dwarf2out.c: Likewise. Also use expand_location, DECL_IS_BUILTIN.
+ * dwarf2out.c (dwarf2out_decl: Use BUILTINS_LOCATION.
+ * emit-rtl.c (emit_line_note): Simplify if USE_MAPPED_LOCATION.
+ (force_next_line_note, insn_emit): Handle USE_MAPPED_LOCATION case.
+ * final.c (final): Likewise.
+ * haifa-sched.c: Likewise.
+ * integrate.c: Likewise.
+ * jump.c: Likewise.
+ * rtl-error.c: Likewise.
+ * stmt.c (check_seenlabel): Likewise.
+ * tree-pretty-print.c: Likewise.
+ * gengtype-lex.l: Temporary kludge to avoid duplicate typedef.
+ * gengtype.c: Update for now typdefs in input.h. More kludges.
+ * modulo-sched.c (sms_schedule): Use NOTE_EXPANDED_LOCATION macro.
+ * ra-debug.c (ra_print_rtl): Likewise.
+ * sched-rgn.c: Likewise.
+ * sched-vis.c: Likewise.
+ * rtl.h (gen_rtx_ASM_OPERANDS): Redefine if USE_MAPPED_LOCATION.
+ * stmt.c (expand_asm_operands): Adjust calls to gen_rtx_ASM_OPERANDS.
+ * tree-cfg.c: Use new macros and typedefs.
+ * tree-flow-inline.h: Likewise.
+
+2004-06-30 Richard Sandiford <rsandifo@redhat.com>
+ Eric Christopher <echristo@redhat.com>
+
+ * config/mips/3000.md: Improve description.
+
+2004-06-30 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/cirrus.md (cirrus_arm_movdi, cirrus_movsf_hard_insn,
+ cirrus_movdf_hard_insn): Set pool ranges for coprocessor loads.
+
+2004-06-30 Sebastian Pop <pop@cri.ensmp.fr>
+
+ * Makefile.in (OBJS-common): Add tree-chrec.o.
+ (tree-chrec.o): New rule.
+ (GTFILES): Add tree-chrec.h.
+ * gengtype.c (open_base_files): Add tree-chrec.h.
+ * tree-chrec.c: New file.
+ * tree-chrec.h: New file.
+ * tree.def (SCEV_KNOWN, SCEV_NOT_KNOWN, POLYNOMIAL_CHREC): New nodes.
+
+2004-06-30 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c: Include "output.h" to define dump_file.
+ (uid_insn_cost, last_insn_cost): New global variables.
+ (combine_insn_cost): New function to estimate cost of an insn.
+ (combine_validate_cost): New function to determine whether a
+ try_combine replacement sequence is cheaper than the original.
+ (combine_instructions): Allocate and populate uid_insn_cost
+ array at the start of the combine pass, and deallocate it after.
+ (try_combine): Check combine_validate_cost to determine whether
+ a "recombination" should be rejected as being more expensive.
+ * Makefile.in (combine.o): Add dependency upon output.h.
+
+2004-06-30 Roger Sayle <roger@eyesopen.com>
+
+ * config/rs6000/rs6000.c (rs6000_rtx_costs) <MINUS_EXPR>: Handle
+ subtractions identically to additions, always COSTS_N_INSNS (1).
+
+2004-06-30 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * expmed.c (expand_smod_pow2): Fix sign of mask.
+
+2004-06-29 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-pre.c (phi_trans_add): Use is_gimple_min_invariant
+ to check for constants.
+ (set_remove): Likewise.
+ (value_replace_in_set): Likewise.
+ (find_leader): Likewise.
+ * tree-vn.c (set_value_handle): Likewise.
+ (vn_lookup): Likewise.
+ (vn_lookup_or_add): Likewise.
+
+2004-06-30 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ RTL prologue/epilogue for SPARC
+ * config/sparc/sparc-protos.h (sparc_emitting_epilogue): Delete.
+ (sparc_skip_caller_unimp): Likewise.
+ (load_pic_register): Likewise.
+ (leaf_return_peephole_ok): Likewise.
+ (compute_frame_size): Rename into sparc_compute_frame_size.
+ (sparc_expand_prologue): New prototype.
+ (sparc_expand_epilogue): Likewise.
+ (output_return): Likewise.
+ (eligible_for_epilogue_delay): Rename into eligible_for_return_delay.
+ * config/sparc/sparc.h (INITIAL_ELIMINATION_OFFSET): Adjust call to
+ compute_frame_size. Move comment up.
+ (DELAY_SLOTS_FOR_EPILOGUE): Delete.
+ (ELIGIBLE_FOR_EPILOGUE_DELAY): Likewise.
+ (EPILOGUE_USES): Return true for %g1 if the function uses EH return.
+ * config/sparc/sparc.md (UNSPECV_SAVEW): New constant.
+ (type attribute): Add 'return' and 'savew'.
+ (eligible_for_return_delay): New attribute.
+ (return): New delay_slot.
+ (sibcall_epilogue): Call sparc_expand_epilogue.
+ (prologue): Likewise. Move up.
+ (save_register_window): New expander.
+ (save_register_windowsi): New pattern.
+ (save_register_windowdi): Likewise.
+ (epilogue): New expander.
+ (return_internal): New pattern.
+ (Return peepholes): Delete.
+ * config/sparc/sparc.c (SIBCALL_SLOT_EMPTY_P): New macro.
+ (sparc_emitting_epilogue): Delete.
+ (sparc_skip_caller_unimp): Likewise.
+ (sparc_sr_alias_set): New global variable.
+ (frame_base_name): Delete.
+ (frame_base_reg): New global variable.
+ (sparc_override_options): Get new alias set for save/restore.
+ (leaf_return_peephole_ok): Delete.
+ (eligible_for_epilogue_delay): Rename into eligible_for_return_delay.
+ Factor out code into eligible_for_restore_insn_delay.
+ (eligible_for_restore_insn_delay): New function extraced from above.
+ Use IN_UNCOND_BRANCH_DELAY_TRUE instead of IN_BRANCH_DELAY_TRUE.
+ (eligible_for_sibcall_delay): Use SIBCALL_SLOT_EMPTY_P.
+ Factor out code into eligible_for_restore_insn_delay.
+ (load_pic_register): Make static. Remove check.
+ (save_regs): Delete.
+ (restore_regs): Likewise.
+ (compute_frame_size): Rename into sparc_compute_frame_size.
+ Rename leaf_function into leaf_function_p.
+ (build_big_number): Delete.
+ (save_or_restore_regs): New function.
+ (emit_save_regs): Likewise.
+ (emit_restore_regs): Likewise.
+ (emit_stack_pointer_increment ): Likewise.
+ (emit_stack_pointer_decrement): Likewise.
+ (sparc_expand_prologue): Likewise.
+ (sparc_function_prologue): Rename into sparc_asm_function_prologue.
+ Remove all code to emit instructions.
+ (sparc_expand_epilogue): New function.
+ (sparc_function_epilogue): Rename into sparc_asm_function_epilogue.
+ Remove all code to emit instructions.
+ (output_restore): New function.
+ (output_return): Likewise.
+ (output_sibcall): Factor out code into output_restore.
+ (print_operand): Adjust for frame_base_reg.
+ * target.h (struct gcc_target): New field 'late_rtl_prologue_epilogue'.
+ * target-def.h (TARGET_LATE_RTL_PROLOGUE_EPILOGUE): New define.
+ (TARGET_INITIALIZER): Add it.
+ * passes.c (rest_of_compilation): Set the conditional predicate
+ 'current_function_uses_only_leaf_regs' before sched2. If target
+ has 'late_rtl_prologue_epilogue', emit RTL prologue/epilogue right
+ before sched2.
+ * reorg.c (return_insn_p): New predicate.
+ (find_end_label): Use it.
+ (relax_delay_slots): Do not thread an unconditional jump that points
+ to the end return label.
+ * doc/tm.texi (Registers) <Leaf Functions>: Clarify the validity
+ domain of 'current_function_uses_only_leaf_regs'.
+ (Stack and Calling) <Function Entry>: Document new target hook
+ TARGET_LATE_RTL_PROLOGUE_EPILOGUE.
+
+2004-06-30 Jakub Jelinek <jakub@redhat.com>
+
+ * simplify-rtx.c (simplify_binary_operation): Simplify
+ ((A & N) + B) & M -> (A + B) & M if M is pow2 minus 1 constant and
+ N has at least all bits in M set as well.
+
+ PR tree-optimization/15310
+ * expr.c (expand_assignment): Optimize += or -= on a bit field in
+ most significant bits.
+
+2004-06-30 Steven Bosscher <stevenb@suse.de>
+
+ * config/c4x/c4x.md: Fix comment.
+
+2004-06-30 Akos Kiss <akiss@inf.u-szeged.hu>
+
+ * arm.md (cond_return_inverted): Add "length" attribute.
+
+2004-06-29 Per Bothner <per@bothner.com>
+
+ * config/i386/winnt.c (i386_pe_encode_section_info): Smash rtlname's
+ XSTR in place, so we don't lose SYMBOL_REF_DECL info.
+
+2004-06-29 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/hpux.h: Target does too support thread-local storage.
+
+2004-06-29 Zack Weinberg <zack@codesourcery.com>
+
+ * combine.c (distribute_notes): Don't look at global_regs for
+ pseudos.
+
+2004-06-29 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr_rhs): Move immediately before
+ gimplify_modify_expr.
+ (gimplify_init_constructor): Likewise. Gimplify the null
+ CONSTRUCTOR assignment.
+ (gimplify_modify_expr_to_memcpy): New.
+ (gimplify_modify_expr_to_memset): New.
+ (gimplify_modify_expr): Use them.
+
+2004-06-29 Roman Zippel <zippel@linux-m68k.org>
+
+ * web.c (union_defs): use all defs of an instruction to create a
+ union with a read/write use
+
+2004-06-29 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/16216
+ * builtins.c (gimplify_va_arg_expr): Check for valist being
+ an error_mark_node.
+
+2004-06-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/16195
+ * config/rs6000/rs6000.c (rs6000_conditional_register_usage): Make
+ r30 fixed if TARGET_TOC && TARGET_MINIMAL_TOC.
+ (first_reg_to_save): Pretend call_used_regs[30] is 0 if
+ TARGET_TOC && TARGET_MINIMAL_TOC.
+ (rs6000_emit_prologue, rs6000_emit_epilogue): Likewise.
+
+2004-06-29 J"orn Rennecke <joern.rennecke@superh.com>
+
+ Fix gcc.dg/builtin-apply2.c failures:
+ * sh.h (TARGET_VARARGS_PRETEND_ARGS): Define.
+ * sh.c (extra_push): Delete.
+ (sh_expand_prologue): Don't do extra stack adjustment for
+ current_function_pretend_args_size if it comes from varargs setup.
+ Use TARGET_VARARGS_PRETEND_ARGS. Don't set extra_push.
+ (sh_expand_epilogue): Don't use extra_push.
+ (sh_setup_incoming_varargs): Set pretend_arg_size when necessary.
+
+2004-06-29 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (expand_smod_pow2): Provide alternate implementations
+ that avoid conditional jumps, and choose between them based upon
+ the target's rtx_costs.
+
+2004-06-29 Andrew Pinski <apinski@apple.com>
+
+ * tree-sra.c: Include expr.h for definition of MOVE_RATIO.
+ * Makefile.in (tree-sra.c): Update dependencies.
+
+2004-06-29 Richard Henderson <rth@redhat.com>
+
+ * tree-sra.c: Rewrite from scratch. Handle nested aggregates.
+
+2004-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.h (VEC_T_safe_push, VEC_T_safe_insert): Tweak for when
+ size_t is bigger than int.
+
+2004-06-29 Paul Brook <paul@codesourcery.com>
+
+ * target-def.h (TARGET_CXX_GET_COOKIE_SIZE,
+ TARGET_CXX_COOKIE_HAS_SIZE): Define.
+ (TARGET_CXX): Use them.
+ * target.h (struct gcc_target): Add cxx.get_cookie_size and
+ cxx.cookie_has_size.
+ * targhooks.c (default_cxx_get_cookie_size): New fucntion.
+ * targhooks.h (default_cxx_get_cookie_size): Add prototype.
+ * config/arm/arm.c (TARGET_CXX_GET_COOKIE_SIZE,
+ TARGET_CXX_COOKIE_HAS_SIZE): Define.
+ (arm_get_cookie_size, arm_cookie_has_size): New functions.
+ * Make-lang.in (cp/init.o): Add dependency on $(TARGET_H).
+ * doc/tm.texi: Document TARGET_CXX_GET_COOKIE_SIZE and
+ TARGET_CXX_COOKIE_HAS_SIZE.
+
+2004-06-29 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cfglayout.c (fixup_reorder_chain): Don't do anything for
+ e_fall->dest == EXIT_BLOCK_PTR.
+
+2004-06-28 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (verify_stmt): Add last_in_block parameter. Verify
+ that eh stmts can throw.
+ (verify_stmts): Update verify_stmt call.
+ (tree_purge_dead_eh_edges, tree_purge_all_dead_eh_edges): New.
+ * tree-eh.c (remove_stmt_from_eh_region): New.
+ (lower_eh_constructs): Fix throw_stmt_table delete routine.
+ (tree_could_trap_p): Match may_trap_p.
+ (maybe_clean_eh_stmt): New.
+ * tree-flow.h: Update decls.
+ * tree-ssa-ccp.c (pass_ccp): Add TODO_verify_stmts.
+ (substitute_and_fold): Clean eh edges.
+ * tree-ssa-dce.c (mark_control_dependent_edges_necessary): Handle
+ empty basic blocks.
+ * tree-ssa-dom.c (need_eh_cleanup): New.
+ (tree_ssa_dominator_optimize): Allocate it. Cleanup eh edges.
+ (optimize_stmt): Cleanup eh stmts; set need_eh_cleanup.
+
+2004-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * function.c (assign_parms): Don't abort with zero size stack
+ parm failing the PARM_BOUNDARY check.
+
+2004-06-28 Diego Novillo <dnovillo@redhat.com>
+
+ * common.opt (ftree-fre): New flag.
+ * flags.h (flag_tree_fre): Declare.
+ * opts.c (decode_options): Set.
+ * timevar.def (TV_TREE_FRE): Define.
+ * tree-flow-inline.h (may_propagate_copy): Re-arrange for
+ readability. Handle destinations that are not SSA_NAMEs.
+ * tree-flow.h (struct ptr_info_def): Move from tree.h
+ (cprop_into_stmt, cprop_into_successor_phis): Remove.
+ (vn_compute, vn_lookup_or_add, vn_add, vn_lookup): Add
+ vuse_optype parameter.
+ * tree-pass.h (pass_fre): Declare.
+ * tree-ssa-copy.c (cprop_operand): Move to tree-ssa-dom.c
+ (cprop_into_stmt): Likewise.
+ (cprop_into_successor_phis): Likewise.
+ * tree-ssa-dom.c (eliminate_redundant_computations): Fix
+ argument ordering in call to may_propagate_copy.
+ * tree-ssa-pre.c (is_undefined_value): Assume hard registers
+ to be always defined.
+ (add_to_sets): New local function.
+ (create_value_expr_from): New local function.
+ (compute_avail): Call them.
+ (eliminate): Don't ignore statements with virtual operands.
+ (init_pre): New local function.
+ (fini_pre): New local function.
+ (execute_pre): Call them.
+ Add argument DO_FRE. Don't do insertion if DO_FRE is true.
+ (do_pre): New function.
+ (do_fre): New function.
+ (gate_fre): New function.
+ (pass_fre): Declare.
+ * tree-ssa.c (init_tree_ssa): Don't call vn_init.
+ (delete_tree_ssa): Don't call vn_delete.
+ * tree-vn.c (val_expr_pair_d): Add documentation.
+ (vn_compute): Add VUSES argument to incorporate in computing
+ hash values. Update all callers.
+ (expressions_equal_p): Call operand_equal_p with
+ OEP_PURE_SAME.
+ (vn_add): Add VUSES argument. Update all callers.
+ (vn_lookup): Likewise.
+ (vn_lookup_or_add): Likewise.
+ * doc/invoke.texi: Document -ftree-fre and -fdump-tree-fre.
+
+2004-06-28 Steven Bosscher <stevenb@suse.de>
+
+ * config/m32r/m32r.c (m32r_sched_odd_word_p, m32r_adjust_cost,
+ m32r_sched_init, m32r_sched_reorder, m32r_variable_issue): Remove.
+ (TARGET_SCHED_ADJUST_COST, TARGET_SCHED_VARIABLE_ISSUE,
+ TARGET_SCHED_INIT, TARGET_SCHED_REORDER): Don't define.
+ * config/m32r/m32r.md: Rewrite the pipeline description as a DFA.
+
+2004-06-28 Richard Henderson <rth@redhat.com>
+
+ * tree.def (REALPART_EXPR, IMAGPART_EXPR): Change class to 'r'.
+ * fold-const.c (operand_equal_p <case 'r'>): Add REALPART_EXPR,
+ IMAGPART_EXPR.
+ * tree-dump.c (dequeue_and_dump): Handle REALPART_EXPR and
+ IMAGPART_EXPR explicitly.
+ * tree-inline.c (estimate_num_insns_1): Don't handle REALPART_EXPR
+ and IMAGPART_EXPR specially.
+ * tree.c (build1_stat): Copy TREE_THIS_VOLATILE into class 'r'.
+
+2004-06-28 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config.gcc (sh*-*elf*): Remove dead assignment of sh_multilibs.
+
+2004-06-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * builtins.def (execl, execlp, execle, execv, execvp, execve,
+ fork): Change to DEF_EXT_LIB_BUILTIN.
+
+2004-06-28 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (expand_smod_pow2): New function to expand signed
+ remainder by a constant power of 2, such as "x % 16".
+ (expand_divmod): Call new expand_smod_pow2 when appropriate.
+ Minor corrections to comments, e.g. wrapping long lines.
+
+2004-06-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * Makefile.in (vec.o): Fix dependencies.
+
+2004-06-28 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * Makefile.in: Fix parallel make dependency problem on vec.o.
+
+2004-06-28 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ PR target/14041
+ * config/h8300/h8300.h (ASM_OUTPUT_ALIGNED_BSS): Define.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (tree_check_failed): Make varadic.
+ (tree_not_check_failed): New prototype.
+ (tree_check2_failed, tree_check3_failed,
+ tree_check4_failed, tree_check5_failed): Remove.
+ (TREE_CHECK, TREE_CHECK2, TREE_CHECK3, TREE_CHECK4,
+ TREE_CHECK5): Adjust.
+ (TREE_NOT_CHECK, TREE_NOT_CHECK2, TREE_NOT_CHECK3, TREE_NOT_CHECK4,
+ TREE_NOT_CHECK5): New.
+ (TREE_VEC_ELT_CHECK, PHI_NODE_ELT_CHECK, TREE_OPERAND_CHECK_CODE,
+ TREE_RTL_OPERAND_CHECK): Adjust.
+ * tree.c (tree_check_failed): Make varadic.
+ (tree_not_check_failed): New.
+ (tree_check2_failed, tree_check3_failed,
+ tree_check4_failed, tree_check5_failed): Remove.
+
+2004-06-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (can_combine_p): Do not prevent building insns that use
+ and clobber the same fixed hard register.
+ (reg_dead_at_p): Likewise.
+
+2004-06-28 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree-sra.c (is_sra_candidate_ref): Remove second arg; all callers
+ changed.
+ (is_sra_candidate_complex_ref): New function.
+ (scalarize_modify_expr): Call it and check for LHS also.
+
+ * tree-pretty-print.c (dump_function_declaration): New.
+ (dump_generic_node, case FUNCTION_TYPE): Call it.
+ (dump_generic_node, case RECORD_TYPE): Don't output dup semicolon.
+ (dump_generic_node, case DECL_EXPR): New case.
+ (dump_generic_node, case PLACEHOLDER_EXPR): Handle.
+ (print_declaration): Handle type and function declarations.
+
+ * tree-nested.c (create_tmp_var_for): Allow ARRAY_TYPE.
+ (convert_nonlocal_reference, convert_local_reference): Properly
+ convert nest of handled component references.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.h, vec.c: New, type safe vector API.
+ * Makefile.in (OBJS-common): Add vec.o.
+ (vec.o): New target.
+ (gengtype-lex.o): Depend on vec.h.
+
+2004-06-28 Paolo Bonzini <bonzini@gnu.org>
+
+ * fold-const.c (fold_cond_expr_with_comparison): Add ARG1
+ parameter. Use it instead of ARG00 to produce the result.
+
+2004-06-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300-protos.h (legitimate_address_p): Declare.
+ * config/mn10300/mn10300.c (legitimate_address_p): New. Test that
+ index is legitimate, compared with code moved from...
+ * config/mn10300/mn10300.h (GO_IF_LEGITIMATE_ADDRESS): here.
+ (REG_STRICT): Define, according to REG_OK_STRICT.
+ (REGNO_IN_RANGE_P, REGNO_DATA_P, REGNO_ADDRESS_P, REGNO_SP_P,
+ REGNO_EXTENDED_P, REGNO_AM33_P, REGNO_FP_P): Introduce strict
+ argument.
+ (REGNO_STRICT_OK_FOR_BASE_P, REGNO_STRICT_OK_FOR_BIT_BASE_P,
+ REGNO_STRICT_OK_FOR_INDEX_P): New.
+ (REGNO_OK_FOR_BASE_P, REG_OK_FOR_BASE_P, REGNO_OK_FOR_BIT_BASE_P,
+ REG_OK_FOR_BIT_BASE_P, REGNO_OK_FOR_INDEX_P, REG_OK_FOR_INDEX_P,
+ RTX_OK_FOR_BASE_P): Use them.
+
+2004-06-28 Ben Elliston <bje@au.ibm.com>
+
+ * doc/cfg.texi (Basic Blocks): Define dominators.
+
+2004-06-27 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/16205
+ * c-common.c (warn_for_collisions_1): Warn for only decls which
+ have a name.
+
+ PR c++/15145
+ * c.opt (Wsequence-point): Enable for C++ and ObjC++.
+
+ PR c/14963
+ * c-decl.c (start_decl): Check for null types.
+
+2004-06-27 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_legitimate_offset_address_p):
+ Accept TOC addresses.
+
+2004-06-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_load_got): Update prototype.
+ * config/s390/s390.c (struct machine_function): Add member base_reg.
+ (s390_decompose_address): Accept UNSPEC_LTREF. Simplify logic.
+ (s390_split_branches): Annotate late pool references.
+ (annotate_constant_pool_refs): New function.
+ (find_constant_pool_ref): Work on annotated pool references.
+ (replace_constant_pool_ref): Likewise. Use explicit base.
+ (replace_ltrel_base): Use explicit base.
+ (s390_mainpool_start): Reflect main_pool pattern change.
+ (s390_mainpool_finish): Use base register from main_pool.
+ Update calls to replace_ltrel_base and replace_constant_pool_ref.
+ (s390_chunkify_start): Use base_reg from struct machine_function.
+ (s390_chunkify_finish): Remove base_reg argument. Update calls
+ to replace_ltrel_base and replace_constant_pool_ref.
+ (s390_reorg): Don't decide upon base register. Update calls.
+ (s390_load_got): Remove MAYBE_DEAD handling. Do not emit insns
+ but return sequence instead.
+ (s390_emit_prologue): Decide upon base register to use. Annotate
+ all literal pool references. Adapt to main_pool pattern change.
+ Update s390_load_got call; move MAYBE_DEAD handling here.
+ (s390_emit_epilogue): Annotate late literal pool references.
+ Remove barrier before register restore instruction.
+ * config/s390/s390.md (UNSPEC_LTREF): New constant.
+ ("builtin_setjmp_receiver"): Update s390_load_got call.
+ ("main_pool"): Explicitly reference base register.
+
+2004-06-27 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <BIT_IOR_EXPR>: Optimize ~X|X and X|~X as -1.
+ <BIT_XOR_EXPR>: Optimize ~X|X and X|~X as -1.
+ <BIT_AND_EXPR>: Optimize ~X&X and X&~X as 0.
+ <TRUTH_AND_EXPR, TRUTH_ANDIF_EXPR>: Optimize !X&&X and X&&!X as false.
+ <TRUTH_OR_EXPR, TRUTH_ORIF_EXPR>: Optimize !X||X and !X||X as true.
+ <TRUTH_XOR_EXPR>: Optimize !X^X and X^X! as true. Now that
+ TRUTH_XOR_EXPR is a commutative tree code, don't test whether arg0
+ is a constant.
+
+2004-06-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * c-common.c (c_safe_from_p, c_walk_subtrees): Deleted.
+ * c-common.def (DECL_STMT): Remove.
+ * c-common.h (DECL_STMT_DECL): Deleted.
+ (COMPOUNT_LITERAL_EXPR_DECL): Use DECL_EXPR_DECL.
+ (c_safe_from_p, c_walk_subtrees): Deleted.
+ * c-decl.c, c-parse.in, c-pretty-print.c: DECL_STMT now DECL_EXPR.
+ * c-dump.c (c_dump_tree, case DECL_STMT): Deleted.
+ * c-gimplify.c (gimplify_decl_stmt): Deleted.
+ (gimplify_compound_literal_expr): Use DECL_EXPR_DECL
+ and gimplify_and_add.
+ (c_gimplify_expr, case DECL_EXPR): New case.
+ (c_gimplify_expr, case DECL_STMT): Deleted.
+ * c-lang.c (LANG_HOOKS_SAFE_FROM_P): Likewise.
+ (LANG_HOOKS_TREE_INLINING_WALK_SUBTREES): Likewise.
+ * expr.c (safe_from_p, case 's'): New case.
+ * gimplify.c (gimplify_decl_expr): New function.
+ (gimplify_expr, case DECL_EXPR): New case.
+ * tree-inline.c (walk_tree): Walk into all fields of a type and
+ decl only if they are in a DECL_EXPR.
+ (mark_local_for_remap_r): Minor code cleanup.
+ * tree-outof-ssa.c (discover_nonconstant_array_refs_r): Add else.
+ * tree.c (has_cleanups, case DECL_EXPR): New case.
+ * tree.def (DECL_EXPR): New code.
+ * tree.h (DECL_EXPR_DECL): New macro.
+
+ * objc/objc-lang.c (LANG_HOOKS_SAFE_FROM_P): Deleted.
+
+2004-06-26 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR 13334
+ * doc/install.texi: Document non-standard CFLAGS and bootstrap
+ failures and warnings.
+
+2004-06-26 Andrew Haley <aph@redhat.com>
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Check
+ TREE_THIS_NOTRAP when setting MEM_NOTRAP_P.
+ * tree-eh.c (tree_could_trap_p): Check TREE_THIS_NOTRAP.
+ * tree.h (TREE_THIS_NOTRAP): New.
+
+2004-06-26 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * genattrtab.c (write_test_expr): Put a unsigned cast before
+ the first operand for GEU, GTU, LEU and LTU.
+
+2004-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-typeck.c, cfgexpand.c, ddg.c, ddg.h, df.c, fold-const.c,
+ gcov.c, gimplify.c, modulo-sched.c, passes.c, tree-cfg.c,
+ tree-mudflap.c, tree-nrv.c, tree-outof-ssa.c, tree-ssa-dom.c,
+ tree-ssa-dse.c, tree-ssa-operands.c, tree-ssa-pre.c,
+ tree-tailcall.c: Fix comment typos. Follow spelling
+ conventions.
+
+2004-06-25 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.md: Add back scheduling exclusion info.
+
+2004-06-25 Roger Sayle <roger@eyesopen.com>
+
+ * ifcvt.c (seq_contains_jump): Delete function.
+ (end_ifcvt_sequence): Replace call to seq_contains_jump with an
+ inline test for a jump instruction in the existing "insn" loop.
+ (block_fallthru): Document function.
+
+2004-06-25 Philip Blundell <philb@gnu.org>
+
+ PR wrong-code/15089
+ * loop.c (scan_loop): Do not move user-specified register
+ assignments.
+
+2004-06-25 DJ Delorie <dj@redhat.com>
+
+ * c-common.h (warn_cast_qual, warn_missing_format_attribute,
+ warn_pointer_arith, warn_missing_prototypes, warn_parentheses,
+ warn_missing_braces, warn_sign_compare, warn_long_long,
+ warn_redundant_decls, warn_float_equal, warn_char_subscripts,
+ warn_conversion, warn_format_y2k, warn_format_extra_args,
+ warn_format_zero_length, warn_format_nonliteral,
+ warn_format_security, mesg_implicit_function_declaration,
+ warn_bad_function_cast, warn_traditional,
+ warn_declaration_after_statement, warn_strict_prototypes,
+ warn_missing_declarations, warn_nested_externs,
+ warn_sequence_point, warn_init_self, warn_div_by_zero,
+ warn_implicit_int, warn_nonnull, warn_old_style_definition,
+ warn_selector, warn_undeclared_selector, warn_protocol,
+ warn_abi, warn_invalid_offsetof, warn_ctor_dtor_privacy,
+ warn_overloaded_virtual, warn_nonvdtor, warn_reorder,
+ warn_synth, warn_pmf2ptr, warn_ecpp, warn_sign_promo,
+ warn_old_style_cast, warn_nontemplate_friend,
+ warn_deprecated): Remove explicit declarations.
+ * c-common.c: Likewise, remove explicit definitions.
+ * c-opts.c: Likewise, remove explicit assignments.
+ * c.opts: Likewise, add implicit declare/define/assign.
+
+2004-06-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * gimplify.c (lookup_tmp_var): Set TREE_READONLY in is_formal case.
+ (build_addr_expr_with_type): Deleted.
+ (build_addr_expr): Deleted; callers changed to build_fold_addr_expr.
+ (gimplify_compound_lval): Make two passes over reference nest.
+
+ * tree-nested.c (build_addr): Merge real/imagpart with
+ handled_component_p.
+ (convert_nonlocal_reference, convert_local_reference): Process extra
+ args to COMPONENT_REF and ARRAY_REF.
+ * tree-outof-ssa.c (discover_nonconstant_array_refs_r): Check for
+ lower bound and field offset being constant.
+
+2004-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR wrong-code/16129
+ * alias.c (get_alias_set): Adjust setting of
+ DECL_POINTER_ALIAS_SET for pointers to aggregates.
+
+2004-06-24 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree-inline.c (remap_type): Arrange to have just one pointer type
+ for each type, mode, and 'can alias' value.
+ (setup_one_parameter): Remap type when making VAR_DECL for PARM_DECL.
+ (estimate_num_insns_1): Minor code reformatting.
+ (inline_forbidden_p_1): Likewise; add; missing return statement.
+
+2004-06-25 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/15825
+ * ifcvt.c (unshare_ifcvt_sequence): Rename to end_ifcvt_sequence.
+ Use get_isns and end_sequence instead of accepting a seq argument.
+ Scan the instruction sequence for unrecognizable or jump insns.
+ (noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
+ noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove,
+ noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
+ noce_try_sign_mask): Use end_ifcvt_sequence to factor common code.
+
+2004-06-24 Jeff Law <law@redhat.com>
+
+ * gimplify.c (gimplify_compound_lval): Reset TREE_SIDE_EFFECTS
+ after gimplifying the innermost component.
+
+2004-06-25 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/16176
+ * config/mips/mips.c (mips_expand_unaligned_load): Use a temporary
+ register for the destination of the lwl or ldl.
+
+2004-06-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree-dfa.c (get_virtual_var): Merge real/imaginary parts with
+ handled_component_p handling.
+ * tree-gimple.c (get_base_address): Likewise and fix typo that
+ caused both recursion and looping.
+
+ * tree-cfg.c (verify_expr): Add macro CHECK_OK.
+ Properly test for nest of handled_components in LHS context.
+
+2004-06-25 Devang Patel <dpatel@apple.com>
+
+ * doc/tree-ssa.texi: Document info about MODIFY_EXPR's type
+
+2004-06-25 Paul Brook <paul@codesourcery.com>
+
+ * target-def.h (TARGET_CXX_GUARD_TYPE, TARGET_CXX_GUARD_MASK_BIT,
+ TARGET_CXX): Define.
+ (TARGET_INITIALIZER): Use TARGET_CXX.
+ * target.h (struct gcc_target): Add struct cxx.
+ * targhooks.h (default_cxx_guard_type): Add prototype.
+ * targhooks.c (default_cxx_guard_type): New function.
+ * config/arm/arm.c (TARGET_CXX_GUARD_TYPE, TARGET_CXX_GUARD_MASK_BIT):
+ Define.
+ (arm_cxx_guard_type, arm_cxx_guard_mask_bit): New functions.
+ * doc/tm.texi: Document TARGET_CXX_GUARD_TYPE and
+ TARGET_CXX_GUARD_MASK_BIT.
+
+2004-06-25 Devang Patel <dpatel@apple.com>
+
+ * config/rs6000/darwin.h (CC1_SPEC): Handle -gused and -gfull.
+ * config/i386/darwin.h (CC1_SPEC): Same.
+
+2004-06-25 Mark G. Adams <mark.g.adams@sympatico.ca>
+
+ * dbxout.h: Add include guards
+
+2004-06-25 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_EABI__.
+
+2004-06-25 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_arch4t): New variable.
+ (arm_override_options): Initialize it. If compiling for armv5 or
+ higher clear TARGET_INTERWORK.
+ (output_call): Abort if called for armv5. Use BX if it's available.
+ (output_call_mem): Use BLX if available and ensure that all armv5
+ code is interworking safe.
+ (output_return_instruction): Always use BX in preference to MOV if
+ it's available.
+ (arm_output_epilogue): Likewise.
+ (arm_final_prescan_insn): Never conditionally call a subroutine
+ on armv5.
+ * arm.h (arm_arch4t): Declare.
+ * arm.md (call_reg_armv5, call_value_reg_armv5): New.
+ (call_reg_arm, call_value_reg_arm): Renamed from call_reg and
+ call_value_reg respectively.
+ (call_reg_thumb_v5, call_value_reg_thumb_v5): New.
+ (call_reg_thumb, call_value_reg_thumb): Renamed from call_indirect
+ and call_value_indirect respectively.
+
+2004-06-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (reg_or_const_float_1_operand): Reimplement
+ in terms of const_float_1_operand.
+
+2004-06-25 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/16144
+ * config/mips/mips.md (divsf, divdf): Don't FAIL if the first operand
+ is 1.0; force it into a register instead.
+
+2004-06-25 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h: Restore valid comment removed by mistake with
+ the recent m68k comments cleanup.
+
+2004-06-24 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * c-gimplify.c (gimplify_for_stmt): Use gimplify_and_add.
+ * gimplify.c (internal_get_tmp_var, gimplify_return_expr): Likewise.
+ (gimplify_loop_expr, gimplify_init_constructor): Likewise.
+ (gimplify_self_mod_expr, gimplify_cond_expr): Likewise.
+
+ PR/16131
+ * gimplify.c (voidify_wrapper_expr): Allow TARGET_EXPR.
+
+ * gimplify.c: Remove unneeded forward declarations.
+
+ * gimplify.c (append_to_compound_expr): Deleted.
+ * tree-gimple.h (append_to_compound_expr): Deleted.
+
+ * fold-const.c (fold_addr_expr_with_type): Look through all
+ valid LHS modifiers to find a base to mark addressable.
+
+ * tree.h (debug_find_tree): Add declaration.
+ * tree-inline.c (debug_find_tree): Remove extern declaration.
+
+2004-06-24 Eric Christopher <echristo@redhat.com>
+
+ * config/rs6000/rs6000.md: Apply change mistakenly
+ deleted with 2004-06-22 patch.
+
+2004-06-24 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (c_in_iteration_stmt, c_in_case_stmt): Remove.
+ (c_break_label, c_cont_label): New.
+ (start_function): Update initializations.
+ (c_push_function_context): Update saves.
+ (c_pop_function_context): Update restores.
+ * c-parse.in: Update expected conflicts.
+ (stmt_count, compstmt_count): Remove. Remove all updates.
+ (if_prefix, simple_if, do_stmt_start): Remove.
+ (lineno_labeled_stmt): Remove.
+ (lineno_labels): New.
+ (c99_block_lineno_labeled_stmt): Use it.
+ (lineno_stmt, lineno_label): Don't clear EXPR_LOCUS before calling
+ annotate_with_locus.
+ (select_or_iter_stmt): Replace by ...
+ (condition, if_statement_1, if_statement_2, if_statement,
+ start_break, start_continue, while_statement, do_statement,
+ for_cond_expr, for_incr_expr, for_statement, switch_statement): New.
+ (stmt): Split out ...
+ (stmt_nocomp): ... this. Use c_finish_bc_stmt, c_finish_goto_label,
+ c_finish_goto_ptr.
+ * c-semantics.c (add_stmt): Don't add line numbers to labels.
+ * c-tree.h: Update prototypes.
+ (struct language_function): Remove x_in_iteration_stmt, x_in_case_stmt;
+ add x_break_label, x_cont_label, x_switch_stack.
+ (c_switch_stack): Declare.
+ * c-typeck.c (c_finish_goto_label, c_finish_goto_ptr): New.
+ (c_finish_return): Return the statement.
+ (c_switch_stack): Rename from switch_stack; export.
+ (if_elt, if_stack, if_stack_space, if_stack_pointer): Remove.
+ (c_begin_if_stmt, c_finish_if_cond, c_finish_then, c_begin_else,
+ c_finish_else): Remove.
+ (c_finish_if_stmt): Rewrite to perform the entire operation.
+ (c_begin_while_stmt, c_finish_while_stmt_cond, c_finish_while_stmt,
+ c_begin_for_stmt, c_finish_for_stmt_init, c_finish_for_stmt_cond,
+ c_finish_for_stmt_incr, c_finish_for_stmt): Remove.
+ (c_finish_loop): New.
+ (c_finish_bc_stmt): New.
+ (c_finish_expr_stmt): Return the statement. Split out...
+ (c_process_expr_stmt): ... this. Don't add locus to error marks.
+ * gimplify.c (gimplify_cond_expr): Accept NULL type statements.
+ * tree-gimple.c (is_gimple_stmt): Likewise.
+ * tree-pretty-print.c (dump_generic_node <COND_EXPR>): Likewise.
+ (print_struct_decl): Delete empty compound statement.
+ * objc/objc-act.c (objc_build_throw_stmt): Return the statement.
+ * objc/objc-act.h: Update decl.
+
+2004-06-24 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree-pretty-print.c (dump_generic_node, case TYPE_DECL):
+ Don't look at TYPE_METHODS unless RECORD_TYPE or UNION_TYPE.
+
+2004-06-24 Andrew Pinski <apinski@apple.com>
+
+ * objc-act.c (build_objc_method_call): Save the lookup_object
+ so we do not call it twice.
+
+2004-06-24 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (real_avail_expr_hash): New.
+ (tree_ssa_dominator_optimize): Use it in the htab.
+
+2004-06-24 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_register_decls): Add third (type) argument
+ to synthesized __mf_unregister call.
+
+2004-06-24 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/15239
+ * expmed.c (expand_mult): Remove artificial restriction on the
+ maximum cost of a synthetic multiplication sequence.
+
+2004-06-24 Eric Christopher <echristo@redhat.com>
+
+ * combine.c (distribute_notes): Don't delete sets to
+ global register variables.
+
+2004-06-24 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (ffsdi2, clzdi2): New expanders.
+ (ffs_rex64): New splitter.
+ (ffsdi_1, ctzdi2, bsr_rex64): New instructions.
+
+2004-06-24 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin7.h (MATH_LIBRARY): Remove.
+ (LIB_SPEC): Define.
+ * config/darwin.h (MATH_LIBRARY): Define always to empty.
+ (LIB_SPEC): Only define if not already defined.
+
+2004-06-24 Revital Eres <eres@il.ibm.com>
+
+ * loop-iv.c (iv_analyze, simple_set_p): Support for identifying
+ shifts of induction variable.
+ (iv_shift): New function.
+
+2004-06-24 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_body): Watch for body vanishing.
+
+2004-06-24 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (record_dominating_conditions): New function.
+ (dom_opt_finalize_block, get_eq_expr_value): Use it.
+
+2004-06-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * calls.c (shift_returned_value): Fix handling of non-integer
+ TYPE_MODEs.
+
+2004-06-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * c-decl.c (finish_function): Do not check for DEFAULT_MAIN_RETURN.
+ * system.h (DEFAULT_MAIN_RETURN): Poison.
+ * doc/tm.texi (DEFAULT_MAIN_RETURN): Remove documentation.
+
+2004-06-24 Ben Elliston <bje@au.ibm.com>
+
+ * doc/cfg.texi (Edges): Fix typo.
+
+2004-06-24 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_output_epilogue): Remove excess checks.
+
+2004-06-23 Andrew Pinski <apinski@apple.com>
+
+ PR middle-end/15988
+ * fold-const.c (fold_convert): Types which are compatible
+ can be converted with only a NOP_EXPR.
+
+2004-06-24 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (expand_call): Call INIT_CUMULATIVE_ARGS earlier, and
+ pass raw n_named_args to it.
+ * targhooks.c: Formatting.
+ (hook_bool_CUMULATIVE_ARGS_false): Correct comment.
+
+2004-06-23 Richard Henderson <rth@redhat.com>
+
+ * c-gimplify.c (gimplify_decl_stmt): Push gimplify_one_sizepos inside
+ non-constant size check. Gimplify the type too. Tidy building
+ BUILT_IN_STACK_ALLOC call.
+
+2004-06-23 Roger Sayle <roger@eyesopen.com>
+
+ * c-common.c (expand_unordered_cmp): Delete.
+ (expand_tree_builtin): Delete.
+ * c-common.h (expand_tree_builtin): Delete function prototype.
+ * c-typeck.c (build_function_call): Don't call expand_tree_builtin.
+
+2004-06-23 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_compound_lval): Don't set ARRAY_REF or
+ COMPONENT_REF variable fields unless they're non-constant.
+
+2004-06-23 Robert Millan <robertmh@gnu.org>
+
+ * config.gcc: Merge kfreebsd*-gnu with linux* and add knetbsd*-gnu.
+ * config/i386/linux.h: Allow overriding of LINK_EMULATION,
+ DYNAMIC_LINKER and register names in sc_ structure.
+ * config/kfreebsd-gnu.h: New. kfreebsd-gnu followup for linux.h.
+ * config/i386/kfreebsd-gnu.h: New. Ditto for i386-kfreebsd-gnu.
+ * config/knetbsd-gnu.h: New. Ditto for knetbsd-gnu.
+ * config/i386/knetbsd-gnu.h: New. Ditto for i386-knetbsd-gnu.
+
+ * config/kfreebsdgnu.h: Remove.
+ * config/t-kfreebsd-gnu: Likewise.
+ * config/i386/kfreebsdgnu.h: Likewise.
+
+2004-06-23 Eric Christopher <echristo@redhat.com>
+
+ * fold-const.c (make_range): Cleanup type checking through function.
+ Remove orig_type. Replace with checks to exp_type and arg0_type.
+ Clarify comment when converting from unsigned to signed.
+
+2004-06-23 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.c (mips_use_dfa_pipeline_interface): Add R3000.
+ * config/mips/mips.md: Remove R3000 scheduling description.
+ * config/mips/3000.md: New file.
+
+2004-06-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_emit_compare): Add prototype.
+ (s390_emit_jump): Likewise.
+ * config/s390/s390.c (s390_emit_compare): New function.
+ (s390_emit_jump): Likewise.
+ * config/s390/s390.md ("beq", "bne", "bgt", "bgtu", "blt", "bltu",
+ "bge", "bgeu", "ble", "bleu", "bunordered", "bordered", "buneq",
+ "bungt", "bunlt", "bunge", "bunle", "bltgt"): Use s390_emit_compare
+ and s390_emit_jump.
+ ("cjump"): Remove, replace by ...
+ ("*cjump_64", "*cjump_31"): ... these insns. Improve length default.
+ ("icjump", "*icjump_64", "*icjump_31"): Likewise.
+ ("trap"): Fix type attribute.
+ ("conditional_trap"): Use s390_emit_compare.
+ ("doloop_si"): Remove, replace by ...
+ ("doloop_si64", "doloop_si31"): ... these new insn_and_split.
+ Merge existing splitter into insn_and_split. Improve length default.
+ ("doloop_di"): Merge with existing splitter into insn_and_split.
+ ("doloop"): Adapt.
+ ("jump"): Convert to expander. Use s390_emit_jump.
+ ("*jump_64", "*jump_31"): New insns. Improve length default.
+
+2004-06-23 Wu Yongwei <adah@sh163.net>
+
+ * gthr-win32.h (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust.
+ (__gthr_i486_lock_cmp_xchg): New inline assembly function.
+ (__GTHR_W32_InterlockedCompareExchange): New macro to choose a
+ suitable function for interlocked compare-and-exchange.
+ (__gthread_mutex_trylock): Use
+ __GTHR_W32_InterlockedCompareExchange.
+ (__gthread_mutex_init_function, __gthread_mutex_lock,
+ __gthread_mutex_trylock, __gthread_mutex_unlock): Adjust the
+ initial counter value to work correctly under Windows 95.
+ * config/i386/gthr-win32.c: Adjust include order.
+ Define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES before including
+ gthr-win32.h.
+ (__gthr_win32_mutex_init_function, __gthr_win32_mutex_lock,
+ __gthr_win32_mutex_trylock, __gthr_win32_mutex_unlock): Adjust
+ to match inline versions in gthr-win32.h.
+
+2004-06-23 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_use_dfa_pipeline_interface): Delete.
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE): Redefine a hook_int_void_1.
+ (insvdi_rshift_rlwimi_p): New function.
+ * config/rs6000/rs6000.md (insvdi_internal2/3): New patterns.
+ (extendsfdf2): Convert to define_insn_and_split.
+ * config/rs6000/rs6000-protos.h (insvdi_rshift_rlwimi_p): Prototype.
+
+2004-06-23 Andrew Pinski <apinski@apple.com>
+
+ * c-typeck.c (composite_type, <case ARRAY_TYPE>): Abort if we have
+ type qualifiers at all.
+ If both of the type domains are null and the new element type is
+ the same as one of the, return the one which the element type.
+ matches.
+ Do not call qualify_type on the new type.
+
+2004-06-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (DEFAULT_MAIN_RETURN): Remove.
+
+2004-06-23 Roger Sayle <roger@eyesopen.com>
+
+ * convert.c (strip_float_extension): Skip both NOP_EXPR and
+ CONVERT_EXPR floating point extensions.
+
+2004-06-23 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-vn.o): New.
+ (tree-ssa-pre.o): Don't depend on RTL_H.
+ * tree-dfa.c (find_referenced_vars): Don't call init_tree_ssa.
+ * tree-flow.h (struct var_ann_d): Remove field expr_set.
+ (add_to_value, expressions_equal_p, get_value_handle, vn_compute,
+ vn_lookup_or_add, vn_add, vn_lookup, vn_init, vn_delete): Declare.
+ * tree-optimize.c (execute_init_datastructures): New local function.
+ (pass_init_datastructures): New local variable.
+ (init_tree_optimization_passes): Sequence pass_init_datastructures.
+ * tree-pretty-print.c (MASK_POINTER): Remove.
+ (dump_generic_node): Handle VALUE_HANDLE.
+ * tree-ssa-pre.c: Move all value numbering routines to tree-vn.c.
+ Update callers to use new function names.
+ Use VALUE_HANDLE_ID and VALUE_HANDLE_EXPR_SET instead of
+ variable annotations.
+ * tree-ssa.c (init_tree_ssa): Call vn_init.
+ (delete_tree_ssa): Call vn_delete.
+ * tree-vn.c: New file.
+ * tree.c (tree_size): Handle VALUE_HANDLE.
+ (tree_node_structure): Likewise.
+ (iterative_hash_expr): Likewise.
+ * tree.def (VALUE_HANDLE): New code.
+ * tree.h (struct tree_value_handle): New.
+ (VALUE_HANDLE_ID): Define.
+ (VALUE_HANDLE_EXPR_SET): Define.
+ (enum tree_node_structure_enum): Add TS_VALUE_HANDLE.
+ (union tree_node): Add struct tree_value_handle.
+
+2004-06-23 Andrew Pinski <apinski@apple.com>
+
+ * c-typeck.c (composite_type):
+ <case POINTER_TYPE>: Build a qualified type of
+ the new type.
+ <case ARRAY_TYPE>: Likewise.
+ <case FUNCTION_TYPE>: Likewise.
+
+2004-06-23 Pat Haugen <pthaugen@us.ibm.com>
+
+ PR optimization/15633
+ * value-prof.c (divmod_fixed_value_transform): Compute probability
+ of taking optimal path and pass along to gen_ routine.
+ (mod_pow2_value_transform): Same.
+ (mod_subtract_transform): Same.
+ (gen_divmod_fixed_value): Add new probability parameter.
+ Add probability to newly created jump.
+ (gen_mod_pow2): Same.
+ (gen_mod_subtract): Same.
+
+2004-06-23 Richard Earnshaw <rearnsha@arm.com>
+
+ * PR target/15948
+ * arm.md (bicsi3_cbranch): Add alternative to handle tying operands
+ one and two.
+
+2004-06-23 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/15927
+ * arm.h (THUMB_SECONDARY_OUTPUT_RELOAD_CLASS): Don't need a secondary
+ reload if CLASS is BASE_REGS.
+
+2004-06-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * gengtype-yacc.y (option): Avoid use of non-constant struct
+ initializer.
+
+2004-06-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/extend.texi (Function Attributes): Alphabetize.
+
+2004-06-23 Richard Henderson <rth@redhat.com>
+
+ * c-gimplify.c (gimplify_decl_stmt): Update gimplify_type_sizes call.
+ Use gimplify_and_add.
+ * c-typeck.c (c_finish_if_stmt): Use NULL instead of empty stmt.
+ * gimplify.c (build_and_jump, gimplify_exit_expr,
+ gimplify_init_constructor, gimplify_save_expr, gimple_push_cleanup,
+ gimplify_stmt, gimplify_expr): Likewise.
+ (shortcut_cond_expr): Handle NULL arms of COND_EXPR.
+ (gimplify_statement_list): Remove NULL entries.
+ (gimplify_to_stmt_list): Handle NULL results.
+ (gimplify_type_sizes): Add list_p argument.
+ (gimplify_one_sizepos): Don't use internal pre/post queue.
+ * tree-gimple.h (gimplify_type_sizes): Update.
+
+2004-06-22 Eric Christopher <echristo@redhat.com>
+
+ * config/rs6000/rs6000.md (*insvsi_internal5/6): New patterns.
+
+2004-06-22 Pat Haugen <pthaugen@us.ibm.com>
+
+ * cfghooks.c (make_forwarder_block): Decrement count on fallthru edge
+ when redirecting back edges.
+
+ * cfghooks.c (split_block): Call make_single_succ_edge so that edge
+ count/probability are set correctly.
+
+2004-06-22 Richard Henderson <rth@redhat.com>
+
+ * c-typeck.c (emit_side_effect_warnings): Ignore error marks.
+ (c_finish_stmt_expr): Likewise.
+
+ * config/i386/i386.c (TARGET_STRUCT_VALUE_RTX): New.
+ (ix86_return_in_memory): Move SSE vector return warning ...
+ (ix86_struct_value_rtx): ... here. New.
+
+2004-06-22 Richard Henderson <rth@redhat.com>
+
+ * tree.def (VTABLE_REF): Remove.
+ (OBJ_TYPE_REF): New.
+ (TRY_CATCH_EXPR, TRY_FINALLY_EXPR): Set type 's'.
+ * expr.c (expand_expr_real_1): Replace VTABLE_REF with OBJ_TYPE_REF.
+ * fold-const.c (non_lvalue): Likewise.
+ * gimplify.c (gimplify_expr): Likewise.
+ (gimplify_call_expr): Use is_gimple_call_addr.
+ * langhooks-def.h (LANG_HOOKS_FOLD_OBJ_TYPE_REF): New.
+ * langhooks.h (fold_obj_type_ref): New.
+ * tree-gimple.c (is_gimple_call_addr): New.
+ * tree-gimple.h (is_gimple_call_addr): Declare.
+ * tree-inline.c (inlinable_function_p): Fix merge error.
+ (estimate_num_insns_1): Replace VTABLE_REF with OBJ_TYPE_REF.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ (print_call_name): Handle OBJ_TYPE_REF.
+ * tree-ssa-ccp.c (fold_stmt): Fold OBJ_TYPE_REF.
+ * tree-ssa-operands.c (get_expr_operands): Handle OBJ_TYPE_REF.
+ * tree.h (OBJ_TYPE_REF_EXPR): New.
+ (OBJ_TYPE_REF_OBJECT, OBJ_TYPE_REF_TOKEN): New.
+ * doc/c-tree.texi (VTABLE_REF): Remove.
+ * objc/objc-act.c (build_objc_method_call): Build an OBJ_TYPE_REF.
+
+2004-06-22 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/16026
+ * function.c (assign_parms): Don't abort for overaligned PARALLEL.
+
+2004-06-22 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in (distclean): Don't try to remove empty directories.
+
+2004-06-22 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/15869
+ * config/mips/mips.c (mips_avoid_hazards): Call split_all_insns_noflow.
+
+2004-06-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md (movdi, movdf): Use high/low for movu
+ operands.
+
+2004-06-22 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c (legitimate_offset_address_p): Make
+ global, rename rs6000_legitimate_offset_address_p.
+ (rs6000_legitimate_address_p): Adjust calls to it.
+ (lmw_operation): Ditto.
+ (stmw_operation): Ditto.
+ * config/rs6000/rs6000-protos.h: Declare it.
+ * config/rs6000/rs6000.md (*movdf_hardfloat32): Use it
+ instead of offsettable_memref_p.
+
+2004-06-22 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_legitimate_address): Disallow
+ [reg+reg] mode for TFmode memory accesses.
+ (rs6000_eliminate_indexed_memrefs): New.
+ (rs6000_emit_move): Call preceding for TImode and TFmode.
+
+2004-06-22 Paolo Bonzini <bonzini@gnu.org>
+
+ * tree-cfg.c (pass_warn_function_return): It needs
+ CFG, not SSA.
+
+2004-06-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/invoke.texi (Machine Dependent Options): Alphabetize.
+ (Submodel Options): Likewise.
+
+2004-06-21 Andrew Pinski <apinski@apple.com>
+
+ Radar #: 3701874
+ * c-decl.c (push_file_scope): Return early if we already
+ have a file scope.
+
+2004-06-21 Geoffrey Keating <geoffk@apple.com>
+
+ * c-opts.c (c_common_handle_option): Handle -fpch-preprocess.
+ * c-common.h (flag_pch_preprocess): Declare.
+ (c_common_pch_pragma): Likewise.
+ * c-common.c (flag_pch_preprocess): New.
+ * c-pch.c (c_common_read_pch): Support -fpreprocess-only.
+ (c_common_pch_pragma): New.
+ * c-ppoutput.c (cb_read_pch): New.
+ (init_pp_output): Support -fpch-preprocess.
+ * c-pragma.c (init_pragma): Support #pragma GNUC pch_preprocess.
+ * c.opt (fpch-preprocess): New.
+ * gcc.c (cpp_options): When save-temps, pass -fpch-preprocess.
+ * doc/cppopts.texi: Document -fpch-preprocess.
+ * doc/invoke.texi (Precompiled Headers): Mention that
+ -fpreprocessed is safe for PCH. Mention that if an option is
+ listed as safe that doesn't mean it does what you expect.
+
+2004-06-22 Ben Elliston <bje@au.ibm.com>
+
+ * tree-ssa.c (ssa_redirect_edge): Correct leading comment.
+
+2004-06-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Makefile.in (gimplify.o): Add cgraph.h.
+ * alias.c (adjust_offset_for_component_ref): Use
+ component_ref_field_offset.
+ * c-decl.c (build_array_declarator): Add news args for ARRAY_REF.
+ * c-gimplify.c (gimplify_expr_stmt): Use alloc_stmt_list.
+ (gimplify_decl_stmt): Call gimplify_type_sizes for type.
+ For decl, call gimplify_one_sizepos and use statement list.
+ (gimplify_compound_literal_expr): New arg PRE_P.
+ Add statement to PRE_P list and return DECL.
+ (c_gimplify_expr, case COMPOUND_LITERAL_EXPR): Add arg to
+ gimplify_compound_literal_expr.
+ * c-tree.h (getdecls): Deleted.
+ * c-typeck.c (build_component_ref): Add operand for COMPONENT_REF.
+ (build_array_ref): Add two operands for ARRAY_REF.
+ (build_unary_op): Set TREE_INVARIANT and TREE_CONSTANT for
+ COMPOUND_LITERAL_EXPR.
+ * coverage.c (tree_coverage_counter_ref): Add new operands
+ for ARRAY_REF.
+ * emit-rtl.c (component_ref_for_mem_expr): Add new operand
+ for COMPONENT_REF.
+ (set_mem_attributes_minus_bitpos): Use array_ref_low_bound
+ and array_ref_element_size.
+ (widen_memory_access):Use component_ref_field_offset.
+ * explow.c (update_nonlocal_goto_save_area): Add two operands
+ for ARRAY_REF.
+ * expr.c (array_ref_element_size, array_ref_low_bound): New functions.
+ (component_ref_field_offset): Likewise.
+ (get_inner_reference): Use them.
+ (expand_expr_real_1, case ARRAY_REF): Use array_ref_low_bound.
+ * fold-const.c (fold, case EQ_EXPR): Properly handle DECL_SIZE.
+ (fold_read_from_constant_string): Use array_ref_low_bound.
+ Verify that result is a character type.
+ (build_fold_indirect_ref): Add two operands for ARRAY_REF.
+ * function.c (expand_function_start): Likewise.
+ * gimple-low.c (expand_var_p): Delete duplicated line.
+ * gimplify.c: Add static decls for local functions.
+ (cgraph.h): Now included.
+ (create_tmp_var): Remove check for ARRAY_TYPE.
+ (copy_if_shared_r): Look at bounds and sizes of types.
+ (build_and_jump): Return alloc_stmt_list instead of build_empty_stmt.
+ (gimplify_exit_expr, shortcut_cond_expr): Likewise.
+ (gimplify_save_expr, gimple_push_cleanup): Likewise.
+ (gimplify_init_constructor): Likewise.
+ WANT_VALUE now bool.
+ If empty list with no result wanted, return GS_UNHANDLED.
+ Add additional operands for ARRAY_REF and COMPONENT_REF.
+ (canonicalize_component_ref): Convert to &array[L].
+ (gimplify_array_ref_to_plus): Use array_ref_element_size and
+ array_ref_lower_bound.
+ (build_addr_expr_with_type, build_addr_expr): New functions.
+ (gimplify_compound_lval): WANT_LVALUE now bool.
+ Major rework to allow handle_component_p and initialize and
+ gimplify new operands for ARRAY_REF, ARRAY_RANGE_REF, and
+ COMPONENT_REF.
+ (gimplify_array_ref): Deleted.
+ (gimplify_self_mod_expr): WANT_VALUE now bool.
+ (gimplify_modify_expr): Gimplify to_p and from_p later.
+ Factor out code into gimplify_modify_expr_rhs and call twice.
+ Move variable-size code earlier and handle PLACEHOLDER_EXPR.
+ (gimplify_modify_expr_rhs, gimplify_variable_sized_compare): New fns.
+ (gimplify_addr_expr, case VIEW_CONVERT_EXPR): New case.
+ (gimplify_expr, case ARRAY_REF): Delete special case.
+ Instead handle like COMPONENT_REF; also do ARRAY_RANGE_REF,
+ IMAGPART, and REALPART the same way.
+ (gimplify_expr, case VIEW_CONVERT_EXPR): New case.
+ (gimplify_expr): Call gimplify_variable_sized_compare if applicable.
+ Call alloc_stmt_list instead of build_empty_stmt.
+ Deal with _REF that's volatile.
+ (gimplify_type_sizes, gimplify_one_sizepos): New functions.
+ (unshare_body, unvisit_body): New functions.
+ (gimplify_body): Call them.
+ * stmt.c (expand_stack_alloc): Don't expand TYPE_MAX_VALUE.
+ * stor-layout.c (get_pending_sizes): Don't change SAVE_EXPR_CONTEXT.
+ * tree-alias-common.c (get_alias_var): Also skip ARRAY_RANGE_REF.
+ * tree-cfg.c (tree_node_can_be_shared): Treat ARRAY_RANGE_REF
+ like ARRAY_REF.
+ (verify_expr, case ADDR_EXPR): Use handled_component_p.
+ * tree-dfa.c (get_virtual_var): Likewise.
+ * tree-dump.c (dequeue_and_dump, case COMPONENT_REF, ARRAY_REF):
+ New cases to dump new operands; likewise for ARRAY_RANGE_REF.
+ * tree-eh.c (tree_could_trap, case ARRAY_RANGE_REF): Like ARRAY_REF.
+ * tree-gimple.c (is_gimple_addr_expr_arg): Add ARRAY_RANGE_REF
+ and INDIRECT_REF.
+ (get_base_address): Use handled_component_p.
+ * tree-gimple.h (gimplify_type_sizes, gimplify_one_sizepos): New.
+ * tree-inline.c (walk_tree): Walk more things for types and decls.
+ * tree-mudflap.c (mf_build_check_statement_for): Add new operands
+ for ARRAY_REF and COMPONENT_REF.
+ (mx_xform_derefs_1): Clean up usage of decl sizes.
+ * tree-nested.c (build_addr): Use handled_component_p.
+ (walk_stmts, case CATCH_EXPR): Add missing "break".
+ (get_static_chain, get_frame_field): Add new operand for COMPONENT_REF.
+ (finalize_nesting_tree_1): Likewise.
+ (convert_nonlocal_reference, case ARRAY_RANGE_REF): Like ARRAY_REF
+ and process additional operands.
+ (convert_local_reference): Likewise.
+ * tree-outof-ssa.c (discover_nonconstant_array_refs_r): Treat
+ ARRAY_RANGE_REF similarly to ARRAY_REF.
+ * tree-pretty-print.c (dump_generic_node, case QUAL_UNION_TYPE): Handle
+ like RECORD_TYPE.
+ (dump_generic_node, case COMPONENT_REF): Print offset operand.
+ (dump_generic_node, case ARRAY_RANGE_REF): Treat like ARRAY_REF
+ and print lower bound and element size for both.
+ (op_prio, case ARRAY_RANGE_REF): Like ARRAY_REF.
+ * tree-sra.c (csc_build_component_ref): Add new operand.
+ (scalarize_call_expr): Use get_base_address.
+ * tree-ssa-ccp.c (widen_bitfield): Clean up size handling.
+ (maybe_fold_offset_to_array_ref): Rework to handle input having an
+ ARRAY_REF, refine handling of lower bound, and add new operands
+ for ARRAY_REF.
+ (maybe_fold_to_component_ref): Add new operand for COMPONENT_REF.
+ (maybe_fold_stmt_indirect): Only fold *&B to B if types match.
+ (maybe_fold_stmt_addition): Only handle constant lower bound.
+ * tree-ssa-operands.c (get_expr_operands): Minor rearrangements.
+ Treat ARRAY_REF and ARRAY_RANGE_REF the same; look at extra operands.
+ Look at new offset operand of COMPONENT_REF.
+ * tree-ssa.c (set_is_used): Use handled_component_p.
+ * tree.c (substitute_in_expr, case COMPONENT_REF): Add new operand.
+ (stabilize_reference, case COMPONENT_REF): Likewise.
+ (stabilize_reference, case ARRAY_RANGE_REF, ARRAY_REF): Similarly.
+ (recompute_tree_invariant_for_addr_expr): Completely rework to
+ be more precise. Also set TREE_SIDE_EFFECTS.
+ (build1_stat, case ARRAY_EXPR): Don't handle TREE_SIDE_EFFECTS here.
+ (build2_stat, build3_stat, build4_stat): For references,
+ propagate TREE_THIS_VOLATILE.
+ (get_unwidened): Add new operand for COMPONENT_REF.
+ (get_narrower): Likewise; use host_integerp for DECL_SIZE.
+ * tree.def (COMPONENT_REF): Add new operand.
+ (ARRAY_REF, ARRAY_RANGE_REF): Add two new operands.
+ * tree.h (array_ref_element_size, array_ref_low_bound): New decls.
+ (component_ref_field_offset): Likewise.
+ * config/alpha/alpha.c (alpha_va_start): Add new op for COMPONENT_REF.
+ (alpha_gimplify_va_arg): Likewise.
+ * config/i386/i386.c (ix86_va_start, ix86_gimplify_va_arg): Likewise.
+ * config/i860/i860.c (i860_va_start, i860_va_arg): Likewise.
+ * config/iq2000/iq2000.c (iq2000_va_arg): Likewise.
+ * config/mips/mips.c (mips_va_start, mips_va_arg): Likewise.
+ * config/rs6000/rs6000.c (rs6000_va_start, rs6000_gimplify_va_arg):
+ Likewise.
+ * config/s390/s390.c (s390_va_start, s390_gimplify_va_arg): Likewise.
+ * config/sh/sh.c (sh_va_start, sh_va_arg): Likewise.
+ * config/stormy16/stormy16.c (xstormy1_expand_builin_va_start):
+ Likewise.
+ (xstormy16_expand_builtin_va_arg): Likewise.
+ * config/xtensa/xtensa.c (xtensa_va_start, xtensa_va_arg): Likewise.
+ * objc/objc-act.c (generate_static_references): Likewise.
+ (generate_strings, build_method_prototype_list_template): Likewise.
+ (generate_protocol_list): Likewise.
+
+2004-06-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR rtl-optimization/14782
+ * pa.c (emit_move_sequence): Use SFmode for 4-byte modes when doing
+ the address checks for secondary reloads for loads from and stores
+ to floating-point registers.
+ * pa.h (EXTRA_CONSTRAINT, case T): Use SFmode for 4-byte modes
+ in the address check. Move work around for ELF32 targets to
+ GO_IF_LEGITIMATE_ADDRESS.
+ (GO_IF_LEGITIMATE_ADDRESS): Require constant offsets to be
+ correctly aligned for DImode loads and stores. Don't allow long
+ SFmode displacements on ELF32.
+
+2004-06-21 Richard Henderson <rth@redhat.com>
+
+ PR rtl-opt/16114
+ * cse.c (merge_equiv_classes): Also rehash in response to
+ delete_reg_equiv changes.
+ (rehash_using_reg): Don't exclude REGs from rehashing.
+
+2004-06-21 Richard Henderson <rth@redhat.com>
+
+ * c-common.def (RETURN_STMT): Remove.
+ * c-common.h (RETURN_STMT_EXPR): Remove.
+ (c_expand_return, build_return_stmt): Remove.
+ (c_common_stmt_codes): Remove RETURN_STMT.
+ * c-dump.c (dump_next_stmt): Remove.
+ (c_dump_tree): Remove RETURN_STMT.
+ * c-decl.c (finish_function): Use c_finish_return.
+ * c-parse.in (stmt): Likewise.
+ * c-gimplify.c (gimplify_return_stmt): Remove.
+ (c_gimplify_expr): Remove RETURN_STMT.
+ * c-pretty-print.c (pp_c_statement): Likewise.
+ * c-semantics.c (build_return_stmt): Remove.
+ * c-tree.h (c_finish_return): Declare.
+ * c-typeck.c (c_finish_return): Rename from c_expand_return.
+ Return void. Build RETURN_EXPR directly.
+ * tree-dump.h (dump_next_stmt): Remove.
+
+2004-06-21 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (start_function): Don't call make_decl_rtl. Don't
+ look at TREE_ADDRESSABLE of symbol name.
+
+2004-06-21 Kelley Cook <kcook@gcc.gnu.org>
+
+ PR target/15551
+ * config/i386/i386.md: Change UNSPEC_STACK_PROBE to UNSPECV_STACK_PROBE.
+ (allocate_stack_worker): Make unspec_volatile.
+ (allocate_stack_worker_rex64): Likewise.
+ (allocate_stack_worker_postreload): Likewise.
+ (allocate_stack_worker_rex64_postreload): Likewise.
+
+2004-06-21 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR optimization/15982
+ * tree-ssa-pre.c: Update a few comments and todos to
+ reflect constants change.
+ (get_value_handle): Constants now value number to themselves.
+ (lookup): Constants lookup to themselves.
+ (add_to_value): Adjust to always be on.
+ (set_contains_value): Adjust for constants change.
+ (find_leader): Ditto.
+ (phi_translate): 'r' nodes are never ANTIC right now.
+ (valid_in_set): Ditto.
+ (get_expr_set): New function.
+ (find_or_generate_expression): New function, broken out from
+ insert_aux.
+ (create_expression_by_pieces): Ditto, plus additional
+ machinery to handle complex values.
+ (compute_avail): Remove dead RETURN_EXPR handling.
+
+2004-06-21 Steven Bosscher <stevenb@suse.de>
+
+ * config/i386/i386.c: Include insn-codes.h
+ * config/i386/i386.h (FLAGS_REG, FPSR_REG, DIRFLAG_REG): Don't
+ define here.
+ * config/i386/i386.md (BP_REG, SP_REG, FLAGS_REG, FPSR_REG,
+ DIRFLAG_REG): New define_constants. Use them everywhere.
+
+2004-06-21 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/t-linux (MULTILIB_OPTIONS): Remove.
+
+2004-06-21 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (SUPPORT_SH1, SUPPORT_SH2E, SUPPORT_SH4): Conditionally define.
+ (SUPPORT_SH4_SINGLE): Likewise.
+ (TARGET_SWITCHES): Break out switches for cpu subtargets:
+ (TARGET_SWITCH_SH1, TARGET_SWITCH_SH2, TARGET_SWITCH_SH2E): Define.
+ (TARGET_SWITCH_SH3, TARGET_SWITCH_SH3E): Likewise.
+ (TARGET_SWITCH_SH4_SINGLE_ONLY, TARGET_SWITCH_SH4_SINGLE): Likewise.
+ (TARGET_SWITCH_SH4_NOFPU, TARGET_SWITCH_SH4): Likewise.
+ (TARGET_SWITCH_SH5_64MEDIA, TARGET_SWITCH_SH5_64MEDIA_NOFPU): Likewise.
+ (TARGET_SWITCHES_SH5_32MEDIA): Likewise.
+ (TARGET_SWITCHES_SH5_32MEDIA_NOFPU): Likewise.
+ (SELECT_SH5_64, SELECT_SH5_64_NOFPU): Rename to:
+ (SELECT_SH5_64MEDIA, SELECT_SH5_64MEDIA_NOFPU)
+ (SELECT_SH5_32, SELECT_SH5_32_NOFPU): Rename to:
+ (SELECT_SH5_32MEDIA, SELECT_SH5_32MEDIA_NOFPU).
+ (SH_MULTILIB_CPU_DEFAULT, MULTILIB_DEFAULTS): Define.
+ (ASM_ISA_SPEC_DEFAULT, ASM_ISA_DEFAULT_SPEC): Likewise.
+ * sh64.h (ASM_SPEC, LINK_DEFAULT_CPU_EMUL): Don't redefine.
+ (TARGET_DEFAULT): Likewise.
+ * config/sh/t-elf: Amend comment.
+ * config/sh/t-1e, config/sh/t-mlib-sh1: New files.
+ * config/sh/t-mlib-sh2, config/sh/t-mlib-sh2e: Likewise.
+ * config/sh/t-mlib-sh3, config/sh/t-mlib-sh3e: Likewise.
+ * config/sh/t-mlib-sh4, config/sh/t-mlib-sh4-nofpu: Likewise.
+ * config/sh/t-mlib-sh4-single: Likewise.
+ * config/sh/t-mlib-sh4-single-only: Likewise.
+ * config/sh/t-mlib-sh5-32media: Likewise.
+ * config/sh/t-mlib-sh5-32media-nofpu: Likewise.
+ * config/sh/t-mlib-sh5-64media: Likewise.
+ * config/sh/t-mlib-sh5-64media-nofpu: Likewise.
+ * config/sh/t-mlib-sh5-compact: Likewise.
+ * config/sh/t-mlib-sh5-compact-nofpu: Likewise.
+ * config/sh/t-sh: (MULTILIB_ENDIAN): Add mb.
+ (MULTILIB_CPUS): Define.
+ (MULTILIB_OPTIONS): Use MULTILIB_CPUS.
+ (MULTILIB_MATCHES): Use some shell code to calculate it.
+ (MULTILIB_EXCEPTIONS): Change to ml/m1.
+ * config/sh/elf.h (SUBTARGET_ASM_ISA_SPEC): Use ASM_ISA_DEFAULT_SPEC.
+ * config/sh/netbsd-elf.h: Update code which sets TARGET_VERSION_CPU.
+ (LINK_DEFAULT_CPU_EMUL): Don't redefine.
+ (NO_PROFILE_COUNTERS): Define to 1.
+ * config/sh/t-netbsd (MULTILIB_OPTIONS): Don't append to.
+ (MULTILIB_DIRNAMES, MULTILIB_MATCHES, MULTILIB_EXCEPTIONS): Don't zap.
+ * config/sh/t-netbsd-sh5-64 (MULTILIB_OPTIONS): Don't redefine.
+ (MULTILIB_MATCHES): Don't zap.
+ (MULTILIB_DIRNAMES): Use MULTILIB_RAW_DIRNAMES.
+ * config/sh/t-sh64 (MULTILIB_OPTIONS): Don't redefine.
+ (MULTILIB_MATCHES, MULTILIB_EXCEPTIONS): Don't zap.
+ (MULTILIB_RAW_DIRNAMES): Define.
+ (MULTILIB_DIRNAMES): Use it.
+ * config.gcc: Also set cpu_type / need_64bit_hwint for sh[be]*-*-*.
+ (sh*linux configurations): Merge into:
+ (sh*elf / sh*kaos configurations). Support --with-endian, --with-cpu,
+ --with-multilib-list options. Support sh-superh-elf configuration.
+ (sh*-netbsd*): Use SELECT_SH* macros.
+ (supported_defaults): sh[123456ble]-*-* | sh-*-* support "cpu".
+ Merge sh*-*-netbsd* configurations into sh-elf configurations.
+ * config/sh/t-netbsd-sh5, config/sh/t-be, config/sh/t-le: Delete.
+ * config/sh/t-monolib: Likewise.
+
+2004-06-21 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.h (ARM_LEGITIMIZE_RELOAD_ADDRESS): Soft-float need
+ not imply FPA.
+
+2004-06-21 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (operand_equal_p): Pass flags in recursive calls for
+ binary and relational operations. Add support for TRUTH_ANDIF_EXPR,
+ TRUTH_ORIF_EXPR, TRUTH_AND_EXPR, TRUTH_OR_EXPR and TRUTH_XOR_EXPR.
+ * tree.c (commutative_tree_code): Also list UNORDERED_EXPR,
+ ORDERED_EXPR, UNEQ_EXPR, LTGT_EXPR, TRUTH_AND_EXPR, TRUTH_OR_EXPR
+ and TRUTH_XOR_EXPR.
+
+2004-06-21 Paolo Bonzini <bonzini@gnu.org>
+
+ * rtlanal.c (may_trap_p): Mark LTGT as trapping.
+
+2004-06-21 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * tree-alias-common.h (struct tree_alias_ops): Change ip and
+ ip_partial to unsigned int.
+
+2004-06-21 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (verify_sequence_points): Export.
+ (c_expand_expr_stmt): Move to c-typeck.c.
+ * c-common.h (c_expand_expr_stmt): Remove.
+ (verify_sequence_points): Declare.
+ * c-mudflap.c (mflang_flush_calls): Use c_finish_expr_stmt.
+ * c-parse.in (for_init_stmt, stmt): Likewise.
+ * c-tree.h (c_finish_expr_stmt): Declare.
+ (c_tree_expr_nonnegative_p): Remove.
+ * c-typeck.c (c_tree_expr_nonnegative_p): Remove.
+ (build_conditional_expr, build_binary_op): Use tree_expr_nonnegative_p.
+ (emit_side_effect_warnings): New.
+ (c_finish_expr_stmt): Rename from c_expand_expr_stmt. Use it.
+ (c_finish_stmt_expr): Work without EXPR_STMT. Handle eh regions.
+ Use emit_side_effect_warnings.
+ (push_cleanup): Copy STATEMENT_LIST_STMT_EXPR.
+ * fold-const.c (tree_expr_nonnegative_p): Handle TARGET_EXPR.
+ * gimplify.c (gimplify_modify_expr): Don't discard TARGET_EXPR
+ with void initializer.
+ (gimplify_target_expr): Handle void BIND_EXPR initializer.
+ * tree-inline.c (estimate_num_insns_1): Fix type lookup for
+ INIT_EXPR and MODIFY_EXPR.
+ * objc/objc-act.c (build_module_descriptor): Use add_stmt
+ instead of c_expand_expr_stmt.
+
+2004-06-21 Paolo Bonzini <bonzini@gnu.org>
+
+ * fold-const.c (fold_cond_expr_with_comparison):
+ New function, extracted from fold.
+ (fold): Extract code to fold A op B ? A : C, use
+ it to fold A op B ? C : A. Really optimize
+ A & N ? N : 0 where N is a power of two. Avoid
+ relying on canonicalization and recursion for
+ foldings of COND_EXPR to happen.
+
+2004-06-20 David Ayers <d.ayers@inode.at>
+
+ * objc/objc-act.h (get_object_reference): Rename to
+ get_protocol_reference.
+ (super_type): Rename to objc_super_type.
+ (selector_type): Rename to objc_selector_type.
+ (id_type): Rename to objc_id_type.
+ (instance_type): Rename to objc_instance_type.
+ (protocol_type): Rename to objc_protocol_type.
+ (IS_ID): Update reference to id_type.
+ * objc/objc-act.c (get_object_reference): Rename to
+ get_protocol_reference; add documentation; update references to
+ id_type.
+ (lookup_method_in_protocol_list): Rename class_meth to
+ is_class; add documentation.
+ (finish_message_expr): Rename is_class to class_tree.
+ (synth_module_prologue, objc_is_object_ptr, objc_build_exc_ptr,
+ next_sjlj_build_try_catch_finally, objc_begin_catch_clause,
+ build_next_objc_exception_stuff, get_arg_type_list,
+ build_objc_method_call): Update references to id_type.
+ (synth_module_prologue, build_objc_symtab_template,
+ build_selector_reference_decl, build_selector,
+ build_selector_translation_table, build_typed_selector_reference,
+ get_arg_type_list, synth_self_and_ucmd_args, get_arg_type_list,
+ synth_self_and_ucmd_args): Update references to selector_type.
+ (build_private_template, build_ivar_reference): Update references
+ to instance_type.
+ (synth_module_prologue, build_protocol_reference,
+ build_protocol_expr, start_protocol): Update references to
+ protocol_type.
+ (synth_module_prologue, get_arg_type_list, build_objc_method_call):
+ Update references to super_type.
+ * c-parse.in: (typespec_nonreserved_nonattr): Update
+ references to get_object_reference.
+ * objc/objc-tree.def: Add C mode identifier sequence.
+
+2004-06-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * loop-invariant.c: New file.
+ * Makefile.in (loop-invariant.o): New.
+ * cfgloop.h (global_cost_for_size, init_set_costs,
+ move_loop_invariants): Declare.
+ * cfgloopanal.c (seq_cost, init_set_costs, global_cost_for_size): New
+ functions.
+ (avail_regs, res_regs, small_cost, pres_cost, spill_cost): New
+ variables.
+ * common.opt (floop-optimize2, fmove-loop-invariants): New options.
+ * loop-init.c (loop_optimizer_init): Call init_set_costs.
+ * passes.c (rest_of_handle_loop2): Call move_loop_invariants.
+ (rest_of_compilation): Check flag_loop_optimize2.
+ * toplev.c (process_options): Handle flag_loop_optimize2.
+ * doc/invoke.texi (-floop-optimize2, -fmove-loop-invariants): Document.
+ * doc/passes.texi (loop-invariant.c): Document.
+
+2004-06-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-pre.c (compute_antic): Keep BB_VISITED flag zeroed.
+
+2004-06-20 Richard Henderson <rth@redhat.com>
+
+ * stmt.c (warn_if_unused_value): Add locus argument.
+ * tree.h (warn_if_unused_value): Update decl.
+ * c-typeck.c (internal_build_compound_expr): Update call.
+ * c-gimplify.c (gimplify_expr_stmt): Likewise.
+
+2004-06-20 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/16089
+ * builtins.c (entry_of_function): Move to ...
+ * cfgrtl.c (entry_of_function): Here and make non-static.
+ * integrate.c (emit_initial_value_sets): Use entry_of_function.
+ * rtl.h (entry_of_function): Prototype.
+
+2004-06-20 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (pentium4_cost): Increase "lea" cost from 1 to 3.
+ (ix86_rtx_costs) <ASHIFT, PLUS>: Consider ix86_cost->lea even when
+ TARGET_DECOMPOSE_LEA.
+
+2004-06-20 Richard Henderson <rth@redhat.com>
+
+ * c-common.h (add_decl_stmt): Move to cp-tree.h.
+ * c-decl.c (finish_decl): Don't use add_decl_stmt.
+ * c-parse.in: Likewise.
+ * c-gimplify.c (gimplify_expr_stmt): Don't build CLEANUP_POINT_EXPR.
+ (gimplify_c_loop, gimplify_return_stmt, gimplify_decl_stmt): Likewise.
+ * c-semantics.c (add_decl_stmt): Move to cp/semantics.c.
+
+2004-06-20 Richard Henderson <rth@redhat.com>
+
+ * c-common.def (IF_STMT, CLEANUP_STMT): Move to cp-tree.def.
+ * c-common.h (IF_COND, THEN_CLAUSE, ELSE_CLAUSE, CLEANUP_BODY,
+ CLEANUP_EXPR, CLEANUP_DECL): Move to cp-tree.h.
+ (c_common_stmt_codes): Remove IF_STMT, CLEANUP_STMT.
+ * c-dump.c (c_dump_tree): Move IF_STMT, CLEANUP_STMT to cp_dump_tree.
+ * c-pretty-print.c (pp_c_statement): Similarly.
+ * c-gimplify.c (gimplify_cleanup_stmt, gimplify_cleanup_stmts,
+ gimplify_if_stmt): Move to cp-gimplify.c.
+ (c_genericize, c_gimplify_expr): Don't call them.
+ * c-semantics.c (push_cleanup): Move to cp/semantics.c.
+ * c-typeck.c (push_cleanup): New.
+ (c_begin_if_stmt, c_finish_if_cond, c_finish_then, c_finish_else,
+ c_finish_if_stmt): Use COND_EXPR.
+ * tree.h (CLEANUP_EH_ONLY): Update documentation.
+
+2004-06-20 Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.h (has_c_linkage): New interface.
+ * c-cppbuiltin.c: Include target.h.
+ (c_cpp_builtins): Define __PRAGMA_REDEFINE_EXTNAME and
+ __PRAGMA_EXTERN_PREFIX when appropriate.
+ * c-pragma.c: Include target.h.
+ Document clarified semantics of symbol-renaming #pragmas.
+ (handle_pragma_redefine_extname, handle_pragma_extern_prefix)
+ (maybe_apply_renaming_pragma): Rewrite according to clarified
+ semantics. Always recognize, but do not necessarily execute.
+ (init_pragma): Unconditionally register symbol-renaming pragmas.
+ * system.h: Poison HANDLE_PRAGMA_REDEFINE_EXTNAME
+ and HANDLE_PRAGMA_EXTERN_PREFIX.
+ * target.h (struct gcc_target): Add handle_pragma_redefine_extname
+ and handle_pragma_extern_prefix flags.
+ * target-def.h: Add defaults for TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME
+ and TARGET_HANDLE_PRAGMA_EXTERN_PREFIX.
+ * Makefile.in (c-pragma.o, c-cppbuiltin.o): Update dependencies.
+ * config/sol2.h: Define TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME,
+ not HANDLE_PRAGMA_REDEFINE_EXTNAME.
+ (TARGET_OS_CPP_BUILTINS): No need to define __PRAGMA_REDEFINE_EXTNAME.
+ (TRANSFER_FROM_TRAMPOLINE): Prototype mprotect.
+ * config/alpha/osf.h: Define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX,
+ not HANDLE_PRAGMA_EXTERN_PREFIX.
+ (TARGET_OS_CPP_BUILTINS): No need to define __PRAGMA_EXTERN_PREFIX.
+ * doc/extend.texi (Solaris Pragmas, Tru64 Pragmas): Combine
+ into one section "Symbol-Renaming Pragmas"; clarify; document
+ adjusted semantics.
+
+ * builtins.c (expand_builtin): Do not issue error for a builtin
+ with no special case code and no DECL_ASSEMBLER_NAME; just do the
+ library call.
+ * c-decl.c (builtin_function): Don't call make_decl_rtl.
+ * c-objc-common.c (has_c_linkage): Stub implementation.
+ * cgraphunit.c (cgraph_expand_function)
+ (cgraph_remove_unreachable_nodes): Don't clear DECL_ARGUMENTS.
+
+2004-06-19 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_unordered_cmp): Take an EXP argument
+ instead of both an ARGLIST and a result TYPE. Handle these C99
+ comparison functions as "polymorphic" builtins. Also handle
+ lowering of BUILT_IN_ISUNORDERED to an UNORDERED_EXPR tree node.
+ (fold_builtin_1): Update calls to fold_builtin_unordered_cmp.
+ Move handling of BUILT_IN_ISUNORDERED from here to there.
+
+2004-06-19 Richard Henderson <rth@redhat.com>
+
+ * c-common.c, c-common.h (lang_gimplify_stmt): Remove.
+ * c-gimplify.c: Remove unnecessary prototypes.
+ (c_gimplify_stmt): Merge into ...
+ (c_gimplify_expr): ... here. Don't play with prep_stmt.
+ * c-semantics.c (prep_stmt): Remove.
+ * gimplify.c (annotate_one_with_locus): Break out from ...
+ (annotate_all_with_locus): ... here.
+ (gimplify_expr): Add locus to expressions even if pre/post queues
+ are not present.
+
+2004-06-19 Richard Henderson <rth@redhat.com>
+
+ PR target/15941
+ * function.c (assign_parms): If not padding upward or intentionally
+ forcing upward padding, take offset_rtx into account when determining
+ the alignment for stack_parm.
+
+2004-06-19 Richard Henderson <rth@redhat.com>
+
+ PR target/15550
+ * ifcvt.c (noce_try_move): Recognize all generated instructions.
+
+2004-06-19 Jan Hubicka <jh@suse.cz>
+
+ * function.c (free_after_compilation): Do not free computed_goto_common*.
+ * function.h (struct function): Kill computed_goto_common*.
+ * stmt.c (expand_computed_goto): Do not commonize the computed gotos.
+ * tree-cfg.c (disband_implicit_edges): Do not forward across the
+ commonized computed goto.
+
+2004-06-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * doc/invoke.texi: Remove obsolete comment regarding PA 2.0 support
+ in binutils.
+
+2004-06-19 Andrew Pinski <apinski@apple.com>
+
+ PR c++/15721
+ * toplev.c (wrapup_global_declarations): Do not check
+ TREE_SYMBOL_REFERENCED of the DECL_ASSEMBLER_NAME but check
+ cgraph_varpool_node's needed field.
+
+2004-06-19 Jan Hubicka <jh@suse.cz>
+ Steven Bosscher <stevenb@suse.de>
+
+ CFG transparent RTL expansion:
+ * Makefile.in (cfgexpand.o): New object file.
+ (builtins.o): Add dependency on basic-block.h
+ * builtins.c: Include basic-block.h
+ (entry_of_function): New function.
+ (expand_builtin_apply_args, expand_builtin_saveargs): Use it.
+ * cfgexpand.c: New file.
+ * expr.c (execute_expand, pass_expand): Kill.
+ * pass.c (rest_of_compilation): Do not build CFG unless called from
+ coverage code.
+ * tree-cfg.c (delete_tree_cfg): Rename to..
+ (delete_tree_cfg_annotations): ... this one; Do not remove the CFG itself.
+ * tree-flow.h (delete_tree_cfg_annotations): Declare.
+ (dleete_tree_cfg): Kill.
+ * tree-optimize.c (execute_rebuild_bind, pass_rebuild_bind): Kill.
+ (execute_del_cfg): Rename to...
+ (execute_free_datastructures): This one...
+ (pass_del_cfg): Rename to...
+ (pass_free_datastructures): ... this one; Do not kill PROP_cfg.
+ (init_tree_optimization_passes): Make cfg build and profiling to happen
+ unconditionally.
+
+2004-06-19 Steven Bosscher <stevenb@suse.de>
+
+ * tree-mudflap.c (mf_decl_cache_locals): Skip labels before
+ inserting the cache variables.
+
+ * tree-mudflap.c: Include headers to make basic_block available.
+ Move functions around such that related functions are near each
+ other. Add prototypes for all static functions. Add comments
+ briefly explaining what IR the mudflap1 and mudflap2 work on and
+ what they do.
+ (mudflap_function_decls): Rename to execute_mudflap_function_decls.
+ (mudflap_function_ops): Rename to execute_mudflap_function_ops.
+ (pass_mudflap_1, pass_mudflap_2): Update.
+ (mf_decl_cache_locals): Make it work on the CFG instead of the saved
+ function tree.
+ (mf_build_check_statement_for): Make it work on the CFG.
+ (mf_xform_derefs_1): Likewise. Cleanup code style.
+ (mf_xform_derefs): Likewise.
+
+2004-06-19 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (label_to_block): Invent the label destination for
+ undefined labels.
+ (cleanup_dead_labels): Update table in the case label_to_block added
+ new label.
+
+2004-06-18 Richard Henderson <rth@redhat.com>
+
+ PR c++/16036
+ * gimple-low.c (lower_function_body): Generate return statement for
+ fall off the end of the function here ...
+ * tree-cfg.c (make_edges): ... instead of here.
+ * gimplify.c (gimplify_return_expr): Mark return temp TREE_NO_WARNING.
+
+2004-06-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa.c (raise_value): Removed.
+ (get_eq_name, check_phi_redundancy): New functions.
+ (kill_redundant_phi_nodes): Use standard ssa minimalization algorithm.
+
+2004-06-18 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <UNORDERED_EXPR, ORDERED_EXPR, UNLT_EXPR,
+ UNLE_EXPR, UNGT_EXPR, UNGE_EXPR, UNEQ_EXPR, LTGT_EXPR>: Add
+ constant folding for unordered comparison tree nodes. If both
+ operands are real constants, call fold_relational_const. If either
+ operand is a NaN, evaluate the other for side-effects and return a
+ constant. Optimize (double)float1 CMP (double)float2 into the
+ equivalent float1 CMP float2.
+ (nondestructive_fold_binary_to_constant) <UNORDERED_EXPR,
+ ORDERED_EXPR, UNLT_EXPR, UNLE_EXPR, UNGT_EXPR, UNGE_EXPR, UNEQ_EXPR,
+ LTGT_EXPR>: Call fold_relational_const for constant operands.
+ (fold_relational_const): Add support for unordered comparison tree
+ nodes. Don't constant fold "ordered" floating point comparisons
+ against NaN if when flag_trapping_math is set.
+
+2004-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ * fold-const.c (build_range_check): If !in_p and recursive call
+ fails, exit immediately. If high - low overflows and etype is
+ a signed type, retry with unsigned etype.
+ (merge_ranges): If !in0_p and !in1_p, handle even range2 adjacent
+ to range1 at TYPE_MAX_VALUE and TYPE_MIN_VALUE.
+
+2004-06-18 Richard Henderson <rth@redhat.com>
+
+ * c-gimplify.c (gimplify_condition): Remove.
+ (gimplify_c_loop, gimplify_if_stmt, gimplify_switch_stmt): Don't
+ call it.
+
+2004-06-18 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c (decide_copy_try_finally): Fix scaling of copy and
+ switch estimates.
+
+2004-06-18 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/i386/darwin.h (HOT_TEXT_SECTION_NAME): Define.
+ (NORMAL_TEXT_SECTION_NAME): Define.
+ (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Define.
+ (SECTION_FORMAT_STRING): Define.
+
+2004-06-18 Steven Bosscher <stevenb@suse.de>
+
+ * config/xtensa/xtensa.c
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE): Define.
+ * xtensa.md: Replace the old pipeline description with a DFA model.
+
+2004-06-18 Steven Bosscher <stevenb@suse.de>
+ Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/s390/s390.md: Remove the generic pipeline description.
+ * config/s390/2064.md: Make all insn reservations apply to
+ the z900, g5 and g6.
+ * config/s390/s390.c (s390_use_dfa_pipeline_interface): Remove.
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE):
+ Define to hook_int_void_1.
+ (s390_adjust_cost): Cleanup. Don't check address dependency here.
+ (s390_first_cycle_multipass_dfa_lookahead): Always return 4.
+
+2004-06-18 Daniel Berlin <dberlin@dberlin.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (create_var_ann): tree_ann -> tree_ann_t.
+ (create_stmt_ann): Ditto.
+ (create_tree_ann): New function.
+ (create_cst_ann): Remove.
+ (create_expr_ann): Ditto.
+
+ * tree-flow-inline.h (cst_ann): Remove.
+ (get_cst_ann): Ditto.
+ (get_expr_ann): Ditto.
+ (expr_ann): Ditto.
+ (get_tree_ann): New function.
+ (tree_ann): Ditto.
+ (ann_type): tree_ann -> tree_ann_t.
+ * tree-flow.h (tree_ann_type): CST_ANN, EXPR_ANN removed.
+ (struct cst_ann_d): Removed.
+ (struct expr_ann_d): Ditto.
+ (union tree_ann_d): Removed cst and expr.
+ (tree_ann): Renamed to tree_ann_t.
+ * tree-ssa-ccp.c (set_rhs): tree_ann -> tree_ann_t.
+ * tree-ssa-pre.c (get_value_handle): Rewrite for single common
+ annotation.
+ (set_value_handle): Ditto.
+ (phi_translate): Ditto.
+ * tree-tailcall.c (adjust_return_value): tree_ann -> tree_ann_t.
+
+2004-06-18 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/t-linux64: New file.
+ * config.gcc: Add it to tmake_file for sh64*-*-linux*.
+
+2004-06-18 Paolo Bonzini <bonzini@gnu.org>
+
+ * emit-rtl.c (unshare_all_rtl_1): New name of unshare_all_rtl.
+ (unshare_all_rtl_again): Call unshare_all_rtl_1.
+ (unshare_all_rtl): New.
+ * function.c (instantiate_virtual_regs): Remove parameters.
+ * function.h (instantiate_virtual_regs): Add prototype.
+ * rtl.h (unshare_all_rtl): Add prototype.
+ * tree.h (instantiate_virtual_regs, unshare_all_rtl): Remove
+ prototype.
+ * passes.c: Remove assertions on the parameters to
+ rest_of_handle_* functions. Remove the parameters to
+ the functions, replacing decl with current_function_decl
+ and insns with get_insns ().
+
+2004-06-17 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (constant_boolean_node): Handle boolean_type_node
+ directly, return either boolean_true_node or boolean_false_node.
+
+2004-06-18 Kelley Cook <kcook@gcc.gnu.org>
+
+ * opts.sh: Delete. Break out generated code to next four files.
+ * opt-gather.awk: New file.
+ * optc-gen.awk: New file.
+ * opth-gen.awk: New file.
+ * opt-functions.awk: New common file.
+ * Makefile.in: Update for above.
+ * configure.ac: Update comment.
+ * configure: Regenerate.
+
+2004-06-17 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (flag_objc_sjlj_exceptions): New.
+ * c-common.h (flag_objc_sjlj_exceptions): Declare.
+ * c-opts.c (c_common_handle_option): Set it.
+ (c_common_post_options): Handle interation of different
+ objective-c exception and runtime switches.
+ * c-decl.c (c_eh_initialized_p): New.
+ (finish_decl): Use it instead of local eh_initialized_p.
+ * c-parse.in (nested_function, notype_nested_function): Record
+ the result of compstmt.
+ (compstmt_or_error): Likewise.
+ (compstmt): Don't add_stmt the result.
+ (stmt): Don't return anything. Rewrite objc try and sync rules.
+ (objc_try_stmt, objc_catch_list): Remove.
+ (objc_catch_block, objc_finally_block): Remove.
+ (objc_catch_prefix, objc_catch_clause, objc_opt_catch_list): New.
+ (objc_try_catch_clause, objc_finally_clause): New.
+ (objc_try_catch_stmt): Rewrite.
+ * c-tree.h (c_eh_initialized_p): Declare.
+ * c-opt (fobjc-sjlj-exceptions): New.
+ * except.c (output_function_exception_table): Don't call cgraph
+ on non-decls.
+ * objc/objc-act.c (UTAG_EXCDATA_VAR, UTAG_CAUGHTEXC_VAR,
+ UTAG_RETHROWEXC_VAR, UTAG_EVALONCE_VAR, struct val_stack,
+ catch_count_stack, exc_binding_stack, if_nesting_count,
+ blk_nesting_count, objc_enter_block, objc_exit_block,
+ objc_declare_variable, val_stack_push, val_stack_pop,
+ objc_build_try_enter_fragment, objc_build_extract_expr,
+ objc_build_try_exit_fragment, objc_build_extract_fragment,
+ objc_build_try_prologue, objc_build_try_epilogue,
+ objc_build_catch_stmt, objc_build_catch_epilogue,
+ objc_build_finally_prologue, objc_build_finally_epilogue,
+ objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
+ objc_build_synchronized_epilogue): Remove.
+ (objc_create_temporary_var, struct objc_try_context, cur_try_context,
+ objc_eh_runtime_type, objc_init_exceptions, objc_build_exc_ptr,
+ next_sjlj_build_try_exit, next_sjlj_build_enter_and_setjmp,
+ next_sjlj_build_exc_extract, next_sjlj_build_catch_list,
+ next_sjlj_build_try_catch_finally, objc_begin_try_stmt,
+ objc_begin_catch_clause, objc_finish_catch_clause,
+ objc_build_finally_clause, objc_finish_try_stmt,
+ objc_build_synchronized): New.
+ (objc_is_object_id, objc_is_class_id): New.
+ (objc_comptypes): Use them.
+ (build_next_objc_exception_stuff): Break NeXT sjlj out from
+ build_objc_exception_stuff.
+ (synth_module_prologue): Update to match.
+ (objc_build_throw_stmt): Use cur_try_context to decide if
+ we're in a @catch.
+ * objc/objc-act.h: Update prototypes.
+ (OCTI_EXCEPTION_BLK_STACK, objc_exception_block_stack): Remove.
+
+2004-06-17 Andrew Pinski <apinski@apple.com>
+
+ * c-typeck.c (tagged_types_tu_compatible_p <case UNION_TYPE>):
+ Use TYPE_FIELDS instead of TYPE_VALUES.
+
+2004-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/16015
+ * gimplify.c (gimplify_target_expr): Handle void initializer.
+ * expr.c (expand_expr_real_1) [TARGET_EXPR]: Likewise.
+ * doc/c-tree.texi (Expression trees): Update TARGET_EXPR
+ and AGGR_INIT_EXPR.
+
+2004-06-17 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_relational_const): Use constant_boolean_node.
+
+2004-06-17 Jan Hubicka <jh@suse.cz>
+
+ PR target/15433
+ * i386.md (SSE SF cmov 0 splitter): The conditional is VOIDmode; fix
+ operand numbering in the output template.
+ (SSE DF cmov 0 splitter): The conditional is VOIDmode.
+
+2004-06-17 Jan Hubicka <jh@suse.cz>
+
+ * except.c (can_throw_internal): Recognize RESX expresisons.
+
+2004-06-17 Jan Hubicka <jh@suse.cz>
+
+ * cfgbuild.c (make_edges): Do not use label_value_list.
+ (find_basic_blocks_1): Do not collect label_value_list.
+ (find_sub_basic_blocks): Update call of make_edges.
+
+2004-06-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (tree_make_forwarder_block): Use SET_PHI_RESULT.
+ * tree-flow-inline.h (get_use_op_ptr): Return a use_operand_p.
+ (get_use_from_ptr, get_def_from_ptr): New. Return operand pointers.
+ (get_def_op_ptr): Return a def_operand_p instead of a 'tree *'.
+ (get_v_may_def_result_ptr): Return a def_operand_p.
+ (get_v_may_def_op_ptr, get_vuse_op_ptr): Return a use_operand_p.
+ (get_v_must_def_op_ptr): Return a def_operand_p.
+ (get_phi_result_ptr): New. Return a pointer to the result of a PHI.
+ (get_phi_arg_def_ptr): New. Return a pointer to an argument of a PHI.
+ (phi_element_for_edge): Remove.
+ * tree-flow.h (propagate_value, replace_exp): Change prototype.
+ (propagate_tree_value): Add new prototype.
+ (phi_element_for_edge): Remove prototype.
+ * tree-into-ssa.c (mark_def_sites): Use new operand types.
+ (prepare_operand_for_rename): Split into two functions.
+ (prepare_use_operand_for_rename): Prepare use operands.
+ (prepare_def_operand_for_rename): Prepare def operands.
+ (rewrite_stmt): Use new operand types.
+ (rewrite_operand): Use new operand types, change parameter type.
+ * tree-outof-ssa.c (replace_variable): Split into two functions.
+ (replace_use_variable): Rewrite uses.
+ (replace_def_variable): Rewrite defs.
+ (rewrite_trees, rewrite_vars_out_of_ssa): Use new operand types.
+ * tree-phinodes.c (make_phi_node, resize_phi_node): Use new types.
+ (add_phi_arg, remove_phi_arg_num): Use new operand types.
+ * tree-ssa-ccp.c (substitute_and_fold): Use new operand types.
+ (ccp_fold, replace_uses_in): Use new operand types.
+ * tree-ssa-copy.c (replace_ssa_names): Rename to replace_ssa_names_ann
+ and no longer set the value, change parameter type.
+ (replace_exp_1): Use new operand types.
+ (propagate_value): Change parameter type, use new operand types.
+ (propagate_tree_value): Propagate_value without SSA operands.
+ (replace_exp, cprop_operand, cprop_into_stmt): Use new operand types.
+ (cprop_into_successor_phis): Use new operand types.
+ * tree-ssa-dom.c (thread_across_edge): Use new operand types.
+ (eliminate_redundant_computations): Use new operand types.
+ * tree-ssa-dse.c (fix_phi_uses): Use new operand_types.
+ (fix_stmt_v_may_defs): Use new operand_types.
+ * tree-ssa-live.c (create_ssa_var_map): Use new operand_types.
+ (build_tree_conflict_graph): Use new operand_types.
+ * tree-ssa-loop.c (duplicate_blocks): Use PHI_ARG_DEF_FROM_EDGE.
+ * tree-ssa-operands.c (struct freelist_d): Remove.
+ (check_optype_freelist, add_optype_freelist): Remove.
+ (allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype,
+ allocate_vuse_optype, allocate_v_must_def_optype): Call ggc_alloc.
+ (free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs):
+ Call ggc_free instead of add_optype_freelist.
+ (init_ssa_operands, fini_ssa_operands): Remove free list code.
+ (finalize_ssa_defs, finalize_ssa_uses): Set new use/def operands.
+ * tree-ssa-operands.h (struct def_optype_d): Change underlying type.
+ (struct use_optype_d): Change underlying type.
+ (def_operand_p, use_operand_p): New types for pointers to operands.
+ (USE_OP, DEF_OP, V_MAY_DEF_RESULT, V_MAY_DEF_OP, VUSE_OP,
+ V_MUST_DEF_OP): Use new pointer type instead of dereferencing directly.
+ (USE_FROM_PTR, DEF_FROM_PTR): New macros to "dereference" operand
+ pointer types.
+ (SET_USE, SET_DEF): New macros to set operands from their pointer.
+ (SET_USE_OP, SET_DEF_OP, SET_V_MAY_DEF_RESULT, SET_V_MAY_DEF_OP,
+ SET_VUSE_OP, SET_V_MUST_DEF_OP): New SET routines for operands.
+ (PHI_RESULT_PTR, PHI_RESULT, SET_PHI_RESULT): Macros to manage the
+ PHI result as an operand.
+ (PHI_ARG_DEF_PTR, PHI_ARG_DEF, SET_PHI_ARG_DEF, PHI_ARG_DEF_FROM_EDGE,
+ PHI_ARG_DEF_PTR_FROM_EDGE): Macros to manage the PHI arguments.
+ * tree-ssa-pre.c (eliminate): Call propagate_tree_value.
+ * tree-tailcall.c (independent_of_stmt_p, propagate_through_phis): Use
+ PHI_ARG_DEF_FROM_EDGE.
+ * tree.h (PHI_RESULT): Renamed to PHI_RESULT_TREE.
+ (PHI_ARG_DEF): Renamed to PHI_ARG_DEF_TREE.
+
+2004-06-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR tree-optimization/15991
+ * tree-cfg.c (tree_block_label): Export.
+ * tree-flow-inline.h (bsi_after_labels): New function.
+ * tree-flow.h (bsi_after_labels, tree_block_label): Declare.
+ * tree-ssa.c (propagate_into_addr): New function.
+ (replace_immediate_uses): Handle propagation of pointer constants.
+ (raise_value): Do not restrict propagation of pointer constants.
+ * tree-ssanames.c (duplicate_ssa_name): New function.
+ * tree.h (duplicate_ssa_name): Declare.
+
+2004-06-17 David Ayers <d.ayers@inode.at>
+
+ * c-parse.in: Unify Objective-C token names.
+
+2004-06-17 Zack Weinberg <zack@codesourcery.com>
+
+ Bug 14610
+ * Makefile.in (min-insn-modes.o): Correct dependencies.
+ * real.c (encode_ieee_extended, decode_ieee_extended): Always
+ produce/consume 12-byte little-endian Intel format.
+ (encode_ieee_extended_128, decode_ieee_extended_128): Delete.
+ (encode_ieee_extended_motorola, decode_ieee_extended_motorola)
+ (encode_ieee_extended_intel_96, decode_ieee_extended_intel_96)
+ (encode_ieee_extended_intel_128, decode_ieee_extended_intel_128):
+ New functions which convert between 12-byte little-endian Intel
+ format and the desired format.
+ (ieee_extended_motorola_format, ieee_extended_intel_96_round_53_format)
+ (ieee_extended_intel_96_format, ieee_extended_intel_128_format):
+ Update.
+
+2004-06-17 Zack Weinberg <zack@codesourcery.com>
+
+ * expmed.c (expand_mult_const): In sanity check, compare only
+ the bits of val and val_so_far that are significant in the
+ result mode.
+
+2004-06-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Update comments.
+ (val_expr_pair_eq): Factor code from here.
+ (expr_pred_trans_eq): and here.
+ (expressions_equal_p): To here.
+ (print_value_set): Print value for expression.
+ (phi_trans_lookup): Rename some variables.
+ (lookup): Ditto.
+ (value_exists_in_set_bitmap): Ditto.
+ (value_remove_from_set_bitmap): Ditto.
+ (value_insert_into_set_bitmap): Ditto.
+
+2004-06-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-modes.def (CCL3mode): New machine mode.
+ * config/s390/s390.c (s390_match_ccmode_set): Support CCL3mode.
+ (s390_alc_comparison, s390_slb_comparison): Likewise.
+ (s390_branch_condition_mask): Likewise.
+ * config/s390/s390.md ("*subdi3_cc2", "*subdi3_cconly2"): New.
+ ("*subsi3_cc2", "*subsi3_cconly2"): New.
+
+ * config/s390/s390.h (PREDICATE_CODE): Accept SIGN_EXTEND and
+ ZERO_EXTEND for s390_alc_comparison and s390_slb_comparison.
+ * config/s390/s390.c (s390_alc_comparison, s390_slb_comparison):
+ Handle SIGN_EXTEND and ZERO_EXTEND.
+
+ * config/s390/s390-protos.h (s390_expand_addcc): New prototype.
+ * config/s390/s390.c (s390_expand_addcc): New function.
+ * config/s390/s390.md ("adddicc", "addsicc"): New expanders.
+ ("*sconddi", "*scondsi", "*sconddi_neg", "*scondsi_neg"): New insns.
+ ("sltu", "sgtu", "sleu", "sgeu"): New expanders.
+
+2004-06-17 Ben Elliston <bje@au.ibm.com>
+
+ * tree-alias-common.c: Add whitespace.
+ * tree-inline.c: Correct comment about this file's purpose.
+ * tree-optimize.c: Likewise.
+ * tree-tailcall.c: Likewise.
+
+ * tree-alias-ander.h: Add standard top-of-file comment.
+ * tree-alias-common.h: Likewise.
+ * tree-alias-type.h: Likewise.
+
+2004-06-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (compute_avail): Value number uses as well.
+ Strip useless type conversions.
+ Casts have to be treated slightly different than normal unaries.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.def (COMPOUND_STMT): Remove.
+ * c-common.c (finish_fname_decls): Don't look through it.
+ * c-typeck.c (c_tree_expr_nonnegative_p): Likewise.
+ * c-common.h (COMPOUND_BODY): Remove.
+ (c_common_stmt_codes): Remove COMPOUND_STMT.
+ * c-dump.c (c_dump_tree): Likewise.
+ * c-gimplify.c (c_gimplify_stmt): Likewise.
+ * c-pretty-print.c (pp_c_statement): Likewise.
+ * tree.h (DECL_SAVED_TREE): Update commentary.
+ * doc/c-tree.texi (ASM_EXPR): Rename from ASM_STMT.
+ (CASE_LABEL_EXPR): Rename from CASE_LABEL.
+ (GOTO_EXPR): Rename from GOTO_STMT.
+ (GOTO_FAKE_P): Remove.
+ (COMPOUND_STMT): Remove.
+ (HANDLER): Update wrt COMPOUND_STMT.
+ (STMT_EXPR): Likewise.
+ (LABEL_EXPR): Rename from LABEL_STMT.
+ (SCOPE_STMT): Remove.
+ * objc/objc-act.c (objc_build_try_catch_finally_stmt): Don't look
+ through COMPOUND_STMT.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.h (c_begin_if_stmt, c_begin_while_stmt,
+ c_finish_while_stmt_cond): Remove decls.
+ * c-parse.in (if_prefix): Don't save c_begin_if_stmt result.
+ * c-typeck.c (c_begin_if_stmt): Return void.
+ (c_begin_else): Tidy. Save stmt_count.
+ * c-tree.h (c_begin_if_stmt): Update decl.
+
+ * objc/objc-act.c (objc_build_try_enter_fragment,
+ objc_build_extract_fragment, objc_build_try_epilogue,
+ objc_build_catch_stmt, objc_build_catch_epilogue,
+ objc_build_finally_prologue, objc_build_finally_epilogue): Update
+ for if builder function changes.
+
+2004-06-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (struct machine_function): New member
+ last_restore_gpr.
+ (s390_frame_info): Add BASE_USED and RETURN_ADDR_USED parameters.
+ Do not modify machine->save_return_addr_p or regs_ever_live.
+ Fill in machine->last_restore_gpr.
+ (s390_optimize_prolog): Use s390_frame_info to compute registers
+ to save/restore, remove duplicated code.
+ (s390_arg_frame_offset): Use s390_frame_info to compute frame
+ size, remove duplicated code.
+ (s390_emit_prologue): Adapt s390_frame_info call. Update
+ machine->save_return_addr_p and regs_ever_live.
+ (s390_emit_epilogue): Use machine->last_restore_gpr instead of
+ machine->last_save_gpr.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * c-parse.in (if_stmt_locus): Remove.
+ (if_prefix): Increment stmt_count; pass it to c_finish_if_cond.
+ (select_or_iter_stmt): Move empty if warnings to c-typeck.c.
+ * c-typeck.c (if_elt): Sort by expected size. Rename locus to
+ empty_locus. Add stmt_count, saw_else.
+ (c_begin_if_stmt): Push if_stack here.
+ (c_finish_if_cond): Rename from c_expand_end_cond. Record stmt_count.
+ (c_finish_then, c_finish_else): Record empty_locus.
+ (c_begin_else): Rename from c_expand_start_else. Record stmt_count.
+ (c_finish_if_stmt): Rename from c_expand_end_cond. Warn for empty
+ if or else body.
+ * c-tree.h: Update prototypes.
+
+2004-06-16 Steven Bosscher <stevenb@suse.de>
+
+ * tree.h (PHI_CHAIN): New.
+ * (tree-cfg.c, tree-dfa.c, tree-flow-inline.h, tree-into-ssa.c,
+ tree-outof-ssa.c, tree-phinodes.c, tree-pretty-print.c,
+ tree-ssa-alias.c, tree-ssa-ccp.c, tree-ssa-dom.c, tree-ssa-dse.c,
+ tree-ssa-live.c, tree-ssa-loop.c, tree-ssa-phiopt.c, tree-ssa-pre.c,
+ tree-ssa.c, tree-tailcall.c): Use PHI_CHAIN instead of TREE_CHAIN
+ when traversing a list of PHI_NODEs.
+
+2004-06-16 Bernardo Innocenti <bernie@develer.com>
+
+ PR target/13292
+ * config/m68k/m68k.h (TARGET_SWITCHES): Don't remove MASK_68040_ONLY
+ on -msoft-float.
+ (TARGET_FLT_EVAL_METHOD): Don't advertise extended precision for
+ 68040 and soft-float.
+ * config/m68k/m68k.md (truncdfsf2): Explicitly require TARGET_68881
+ in the TARGET_68040_ONLY case.
+
+2004-06-16 Peter Barada <peter@the-baradas.com>
+
+ * config/m68k/m68k.md (movsi_cfv4): New pattern to allow mov3q.
+ (movsi_cf): Make named, don't match TARGET_CFV4.
+ (pushexthisi_const): Use mov3q if possible.
+ (extendhisi2, cvf4_extendhisi2): Split extendhisi2 pattern
+ to special case mvz.w for ColdFire V4.
+ (extendqisi2, cvf4_extendqisi2): Split extendhisi2 pattern
+ to special case mvz.b for ColdFire V4.
+ (udivmodhi4, divmodhi4): Use mvz to zero extend arg for
+ divide.
+ (iorsi3, xorsi3, andsi3): Use bitfield instructions if possible.
+ * config/m68k/m68k.c(valid_mov3q_const): New function.
+ (const_method): SWAP is valid for ColdFire.
+ (MULL_COST, MULW_COST): Fix costs for ColdFire V3/V4.
+ * config/m68k/m68k-protos.h (valid_mov3q_const): Prototype here.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.def (CASE_LABEL): Remove.
+ * c-common.c (c_add_case_label): Use CASE_LABEL, not CASE_LABEL_DECL.
+ (match_case_to_enum_1): Likewise.
+ * c-common.h (c_common_stmt_codes): Remove CASE_LABEL.
+ * c-dump.c (c_dump_tree): Likewise.
+ * c-gimplify.c (c_gimplify_stmt): Likewise.
+ * c-pretty-print.c (pp_c_statement): Likewise.
+ * c-semantics.c (build_case_label): Use CASE_LABEL_EXPR.
+ * tree.h (CASE_LOW): Update commentary.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.def (ASM_STMT): Remove.
+ * c-common.h (c_common_stmt_codes): Remove ASM_STMT.
+ * c-dump.c (c_dump_tree): Likewise.
+ * c-gimplify.c (c_gimplify_stmt): Likewise.
+ * c-pretty-print.c (pp_c_statement): Likewise.
+ * c-typeck.c (build_asm_expr): Use ASM_EXPR.
+ * tree.h: Fix commentary.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.def (GOTO_STMT, LABEL_STMT): Remove.
+ * c-common.c (c_add_case_label): Use LABEL_EXPR.
+ * c-common.h (GOTO_FAKE_P, LABEL_STMT_LABEL): Remove.
+ (c_common_stmt_codes): Remove GOTO_STMT, LABEL_STMT.
+ * c-dump.c (c_dump_tree): Likewise.
+ * c-gimplify.c (c_gimplify_stmt): Likewise.
+ * c-pretty-print.c (pp_c_statement): Likewise.
+ * c-parse.in (stmt): Use GOTO_EXPR.
+ (label): Use LABEL_EXPR.
+ * c-semantics.c (build_stmt): Set TREE_TYPE to void.
+ * tree-inline.c (copy_body_r): Don't build empty BLOCKs.
+
+2004-06-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cfgcleanup.c (try_simplify_condjump): Update test to make
+ sure we have a conditional branch around am unconditional branch.
+
+2004-06-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (pass_split_crit_edge): Give it a name and a dump file.
+
+2004-06-16 Dale Johannesen <dalej@apple.com>
+
+ * loop.c (loop_givs_reduce): Avoid miscompilation of
+ loops entered at bottom.
+
+2004-06-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cfglayout.c (fixup_reorder_chain): Handle case where the
+ destination of E_FALL is EXIT_BLOCK_PTR.
+
+2004-06-16 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/15653
+ * config/ia64/ia64.c (ia64_dfa_new_cycle): Do not insert nops
+ after shifts before asm.
+
+2004-06-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR tree-optimization/15993
+ * tree-ssa-dom.c (thread_across_edge): Do not thread edge if its
+ destination is unchanged.
+
+2004-06-16 Andreas Jaeger <aj@suse.de>
+
+ * doc/install.texi (Configuration): Update description for
+ --enable-version-specific-runtime-libs.
+
+2004-06-16 Paolo Bonzini <bonzini@gnu.org>
+
+ * doc/install.texi: boehm-gc now uses automake 1.8.5.
+
+2004-06-16 Paolo Bonzini <bonzini@gnu.org>
+
+ * toplev.h (rest_of_compilation): Adjust prototype.
+
+2004-06-16 Paolo Bonzini <bonzini@gnu.org>
+
+ * coverage.c: Remove argument to rest_of_compilation.
+ * expr.c (execute_expand, set_save_expr_context, pass_expand): New.
+ * passes.c (rest_of_compilation): Remove argument.
+ (pass_rest_of_compilation): New.
+ (rest_of_handle_final, rest_of_handle_delay_slots,
+ rest_of_handle_stack_regs, rest_of_handle_variable_tracking
+ rest_of_handle_machine_reorg, rest_of_handle_regrename
+ rest_of_handle_sched, rest_of_handle_sched2, rest_of_handle_gcse2
+ rest_of_handle_regmove, rest_of_handle_tracer
+ rest_of_handle_if_conversion, rest_of_handle_if_after_combine
+ rest_of_handle_web, rest_of_handle_branch_prob
+ rest_of_handle_value_profile_transformations, rest_of_handle_cfg
+ rest_of_handle_addressof, rest_of_handle_jump_bypass
+ rest_of_handle_life, rest_of_handle_cse, rest_of_handle_cse2):
+ Check that the two arguments are actually superfluous.
+ * tree-optimize.c (register_dump_files): Add properties argument.
+ Track validity of passes. Only initialize dump files for
+ tree-based passes. Store the full set of provided passes in
+ the pass.
+ (init_tree_optimization_passes): Register pass_expand and
+ pass_rest_of_compilation.
+ (execute_one_pass): Do not track the presence of required properties
+ here. Set in_gimple_form. Do not update current_properties.
+ (current_properties): Remove.
+ (set_save_expr_context): Remove.
+ (tree_rest_of_compilation): Do not set in_gimple_form. Do not
+ expand to RTL here, and do not call rest_of_compilation. Push
+ GGC context even before gimplification.
+ * tree-pass.h (PROP_rtl, PROP_trees): New flags.
+ (pass_expand, pass_rest_of_compilation): Declare.
+
+2004-06-15 Jeff Law <law@redhat.com>
+
+ * fold-const.c (swap_tree_comparison): No longer static.
+ (tree_swap_operands_p): Similarly. Return true if both operands
+ are SSA_NAMEs and the first operand has a higher version number than
+ the second operand.
+ * tree.h (swap_tree_comparison): Prototype.
+ (tree_swap_operands_p): Prototype.
+ * tree-ssa-operands.c (get_expr_operands): For commutative
+ operators and relational comparisons, canonicalize the
+ order of the operands.
+
+2004-06-15 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (lang_gimplify_stmt): Remove next_p argument.
+ (if_elt, if_stack, if_stack_space, c_expand_start_cond, c_finish_then,
+ c_expand_end_cond, c_expand_start_else, c_finish_else, c_begin_if_stmt,
+ c_begin_while_stmt, c_finish_while_stmt_cond): Move to c-typeck.c.
+ (finish_fname_decls, fname_decl): Use statement_lists.
+ (c_expand_expr_stmt): Don't set last_expr_type.
+ (c_type_hash): Fix indentation.
+ (c_safe_from_p): Don't follow TREE_CHAIN.
+ (c_tree_chain_matters_p): Remove.
+ * c-common.def (SCOPE_STMT): Remove.
+ (CLEANUP_STMT): Redefine to contain its own body.
+ * c-common.h (struct stmt_tree_s): Remove x_last_stmt,
+ x_last_expr_type, x_last_expr_filename, x_scope_stmt_stack.
+ Add x_cur_stmt_list.
+ (last_tree, last_expr_type, last_expr_filename, RECHAIN_STMTS): Remove.
+ (cur_stmt_list): New.
+ (STATEMENT_LIST_STMT_EXPR): New.
+ (SCOPE_BEGIN_P, SCOPE_END_P, SCOPE_STMT_BLOCK, SCOPE_NULLIFIED_P,
+ SCOPE_NO_CLEANUPS_P, SCOPE_PARTIAL_P, NEW_FOR_SCOPE_P): Remove.
+ (CLEANUP_BODY): New.
+ (CLEANUP_DECL): Move to operand 2.
+ (c_common_stmt_codes): Remove SCOPE_STMT.
+ (COMPOUND_STMT_NO_SCOPE, COMPOUND_STMT_BODY_BLOCK): Remove.
+ * c-decl.c (c_scope_stmt_stack, current_scope_stmt_stack): Remove.
+ (c_push_function_context, c_pop_function_context): Don't save it.
+ (finish_decl): Set TREE_USED on the decl for a cleanup.
+ Use push_cleanup.
+ (store_parm_decls): Use statement lists.
+ (finish_function): Remove compstmt rule workaround. Use statement
+ lists. Call finish_fname_decls after finalizing the body.
+ (c_begin_compound_stmt): Move to c-typeck.c.
+ * c-dump.c (c_dump_tree): Remove SCOPE_STMT.
+ * c-gimplify.c (gimplify_cleanup_stmt, gimplify_cleanup_stmts): New.
+ (c_genericize): Invoke them.
+ (c_gimplify_stmt): Don't look through TREE_CHAIN. Kill SCOPE_STMT.
+ (c_build_bind_expr): Export.
+ (gimplify_block, gimplify_cleanup): Remove.
+ (gimplify_condition): Use gimplify_stmt.
+ (gimplify_for_stmt): Remove FOR_INIT_STMT chaining hack.
+ (gimplify_if_stmt): Remove recursion hack.
+ (c_gimplify_expr): Remove STMT_EXPR handling.
+ (stmt_expr_last_stmt, gimplify_stmt_expr): Remove.
+ (is_last_stmt_of_scope): Remove.
+ * c-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Remove.
+ * c-mudflap.c (mflang_flush_calls): Use c_begin_compound_stmt,
+ c_end_compound_stmt.
+ * c-objc-common.c (build_cdtor): Likewise.
+ * c-parse.in (primary): Use c_finish_stmt_expr.
+ (push_scope, pop_scope): Remove.
+ (c99_block_start, compstmt_start): Use c_begin_compound_stmt.
+ (c99_block_end, compstmt): Use c_end_compound_stmt.
+ (c99_block_lineno_labeled_stmt): Likewise.
+ (compstmt_primary_start): Use c_begin_stmt_expr.
+ (simple_if, select_or_iter_stmt): Update calls to stmt builders.
+ (do_stmt_start): Fill in body directly.
+ (lineno_stmt): Avoid setting lineno on constants.
+ * c-pretty-print.c (pp_c_statement): Handle STATEMENT_LIST.
+ Remove SCOPE_STMT.
+ * c-semantics.c (begin_stmt_tree): Remove.
+ (push_stmt_list, re_push_stmt_list, pop_stmt_list): New.
+ (add_stmt): Use statement lists.
+ (add_scope_stmt, finish_stmt_tree): Remove.
+ (push_cleanup): New.
+ * c-tree.h: Move some decls from c-common.h.
+ * c-typeck.c (c_tree_expr_nonnegative_p): Simplify for statement lists.
+ (do_case, c_finish_case): Likewise.
+ (c_finish_then): Take body for then as argument.
+ (c_finish_else): Similarly.
+ (c_begin_for_stmt, c_finish_for_stmt_init, c_finish_for_stmt_cond,
+ c_finish_for_stmt_incr, c_finish_for_stmt): New.
+ (c_begin_stmt_expr, c_finish_stmt_expr): New.
+ (c_begin_compound_stmt): Do scope management.
+ (c_end_compound_stmt): New.
+ * fold-const.c (tree_expr_nonnegative_p): Fix BIND_EXPR.
+ * gimplify.c (voidify_wrapper_expr): Accept temporary argument.
+ Look through exception handling constructs.
+ (gimplify_bind_expr): Accept temporary argument.
+ (gimplify_target_expr): Special case BIND_EXPR bodies.
+ (gimplify_expr): Handle fallback == fb_none like a statement.
+ * langhooks-def.h (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Kill.
+ * langhooks.c (lhd_tree_inlining_tree_chain_matters_p): Remove.
+ * langhooks.h (tree_chain_matters_p): Remove.
+ * stub-objc.c (objc_clear_super_receiver): New.
+ * tree-gimple.h (voidify_wrapper_expr): Update decl.
+ (append_to_statement_list, append_to_statement_list_force): Move
+ to tree-iterator.h.
+ * tree-inline.c (expand_call_inline): Update call.
+ (clone_body): Use statement lists.
+ (walk_tree): Don't check tree_chain_matters_p.
+ (copy_tree_r): Likewise.
+ * tree-iterator.c (alloc_stmt_list): Clear lang bits.
+ (tsi_link_before, tsi_link_after): Set TREE_SIDE_EFFECTS properly.
+ * tree-iterator.h (append_to_statement_list,
+ append_to_statement_list_force): Moved from tree-gimple.h.
+ * tree-pretty-print.c (dump_generic_node): Clean up TARGET_EXPR dump.
+ * objc/objc-act.c (build_module_descriptor): Use c_begin_compound_stmt.
+ (objc_enter_block): Likewise.
+ (objc_exit_block): Use c_end_compound_stmt.
+ (objc_build_try_enter_fragment): Add #error and comment for
+ rewriting for OBJCPLUS.
+ (objc_build_extract_fragment, objc_build_try_epilogue,
+ objc_build_catch_stmt, objc_build_finally_prologue,
+ objc_build_finally_epilogue): Update for C statement builders.
+ * objc/objc-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P):
+ Remove.
+
+2004-06-15 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * df.c (df_reg_clobber_gen): Removed.
+ (df_bb_rd_local_compute, df_insn_refs_record, df_rd_local_compute):
+ Make more effective for hard regs.
+ * ra-build.c (livethrough_conflicts_bb): Check contains_call.
+
+2004-06-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-pragma.h (c_lex_string_translate): Change type to int.
+ * c-parse.in: Change all assignments of c_lex_string_translate
+ to true and false to 1 and 0.
+ * c-lex.c (c_lex_string_translate): Likewise.
+ (lex_string): Convert string without translation in the -1
+ case.
+
+2004-06-15 Mark G. Adams <mark.g.adams@sympatico.ca>
+
+ * convert.h: Add include guards
+
+2004-06-15 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow-inline.h: Document all functions.
+
+2004-06-15 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow-inline.h (stmt_ann): Remove use of is_essa_node.
+ * tree-dfa.c (create_stmt_ann): Ditto.
+ * tree-pretty-print.c (dump_generic_node): Remove E* node handling.
+ * tree-inline.c (estimate_num_insns_1): Ditto.
+ * tree.c (tree_size): Ditto.
+ (make_node_stat): Ditto.
+ (tree_node_structure): Ditto.
+ (ephi_node_elt_check_failed): Remove.
+ (is_essa_node): Ditto.
+ * tree.def (EPHI_NODE): Ditto.
+ (EEXIT_NODE): Ditto.
+ (EUSE_NODE): Ditto.
+ (EKILL_NODE): Ditto.
+ * tree.h (EREF_NODE_CHECK): Remove.
+ (EPHI_NODE_ELT_CHECK): Ditto.
+ (struct tree_eref_common): Ditto.
+ (struct tree_euse_node): Ditto.
+ (struct ephi_arg_d): Ditto.
+ (struct tree_ephi_node): Ditto.
+ (ephi_node_elt_check_failed): Remove prototype.
+ (is_essa_node): Ditto.
+ (enum tree_node_structure_enum): Remove TS_E*_NODE.
+ (union tree_node): Remove E*_NODE uses.
+
+2004-06-15 Jerry Quinn <jlquinn@optonline.net>
+
+ * alias.c (record_set, record_base_value, canon_rtx, get_addr,
+ nonlocal_mentioned_p_1, init_alias_analysis): Use REG_P.
+ * bt-load.c (find_btr_reference, insn_sets_btr_p, note_btr_set):
+ Likewise.
+ * builtins.c (expand_builtin_setjmp, expand_builtin_apply,
+ expand_builtin_mathfn, expand_builtin_strlen, expand_builtin_memcmp,
+ expand_builtin_strcmp, expand_builtin_strncmp,
+ expand_builtin_frame_address): Likewise.
+ * caller-save.c (mark_set_regs, add_stored_regs, mark_referenced_regs,
+ insert_one_insn): Likewise.
+ * calls.c (prepare_call_address, precompute_register_parameters,
+ precompute_arguments, expand_call, emit_library_call_value_1): Likewise.
+ * cfganal.c (flow_active_insn_p): Likewise.
+ * combine.c (set_nonzero_bits_and_sign_copies, can_combine_p,
+ combinable_i3pat, try_combine, find_split_point, COMBINE_RTX_EQUAL_P,
+ subst, combine_simplify_rtx, simplify_if_then_else, simplify_set,
+ make_extraction, recog_for_combine, gen_lowpart_for_combine,
+ simplify_comparison, record_dead_and_set_regs_1,
+ record_dead_and_set_regs, record_promoted_value,
+ check_promoted_subreg, get_last_value_validate, get_last_value,
+ reg_dead_at_p_1, reg_bitfield_target_p, distribute_notes,
+ unmentioned_reg_p_1): Likewise.
+ * conflict.c (mark_reg): Likewise.
+ * cse.c (HASH, COST, COST_IN, approx_reg_cost_1, notreg_cost,
+ mention_regs, insert_regs, lookup, lookup_for_remove, insert,
+ merge_equiv_classes, flush_hash_table, invalidate,
+ remove_invalid_refs, remove_invalid_subreg_refs, rehash_using_reg,
+ invalidate_for_call, use_related_value, canon_hash, exp_equiv_p,
+ cse_rtx_varies_p, canon_reg, find_best_addr, fold_rtx, equiv_constant,
+ record_jump_cond, cse_insn, addr_affects_sp_p,
+ invalidate_from_clobbers, cse_process_notes, cse_around_loop,
+ cse_set_around_loop, count_reg_usage, set_live_p, cse_change_cc_mode,
+ cse_cc_succs, cse_condition_code_reg): Likewise.
+ * cselib.c (cselib_reg_set_mode, rtx_equal_for_cselib_p,
+ cselib_lookup, cselib_invalidate_regno, cselib_invalidate_rtx,
+ cselib_record_set, cselib_record_sets): Likewise.
+ * dbxout.c (dbxout_symbol_location, dbxout_parms, dbxout_reg_parms,
+ dbxout_block): Likewise.
+ * df.c (df_ref_record, df_def_record_1, df_uses_record): Likewise.
+ * dojump.c (do_jump): Likewise.
+ * dwarf2out.c (dwarf2out_frame_debug_expr, is_pseudo_reg,
+ is_based_loc, rtl_for_decl_location): Likewise.
+ * emit-rtl.c (set_reg_attrs_for_parm, set_decl_rtl,
+ set_decl_incoming_rtl, mark_user_reg): Likewise.
+ * explow.c (copy_all_regs, copy_all_regs, memory_address, force_reg,
+ copy_to_suggested_reg, allocate_dynamic_stack_space,
+ probe_stack_range, hard_function_value): Likewise.
+ * expmed.c (store_bit_field, store_fixed_bit_field,
+ store_split_bit_field, extract_bit_field, extract_fixed_bit_field,
+ extract_split_bit_field, expand_divmod, emit_store_flag_force):
+ Likewise.
+ * expr.c (convert_move, convert_modes,
+ block_move_libcall_safe_for_call_parm, emit_group_load, use_reg,
+ use_group_regs, emit_move_insn, emit_move_insn_1,
+ compress_float_constant, push_block, emit_single_push_insn,
+ emit_push_insn, get_subtarget, expand_assignment, store_expr,
+ store_constructor, store_field, force_operand, safe_from_p,
+ expand_expr_real_1, expand_increment, do_store_flag, do_tablejump):
+ Likewise.
+ * final.c (profile_function, final_scan_insn, alter_subreg,
+ get_mem_expr_from_op, output_asm_operand_names, output_operand,
+ only_leaf_regs_used, leaf_renumber_regs_insn): Likewise.
+ * flow.c (verify_wide_reg_1, mark_regs_live_at_end,
+ find_regno_partial, propagate_one_insn, init_propagate_block_info,
+ insn_dead_p, libcall_dead_p, mark_set_1, not_reg_cond,
+ attempt_auto_inc, find_auto_inc, mark_used_regs,
+ count_or_remove_death_notes_bb): Likewise.
+ * function.c (find_temp_slot_from_address, update_temp_slot_address,
+ preserve_temp_slots, put_var_into_stack, fixup_var_refs_insn,
+ fixup_var_refs_1, fixup_stack_1, optimize_bit_field, flush_addressof,
+ put_addressof_into_stack, purge_addressof_1, insns_for_mem_walk,
+ purge_single_hard_subreg_set, instantiate_decl,
+ instantiate_virtual_regs_1, aggregate_value_p, assign_parms,
+ promoted_input_arg, setjmp_vars_warning, setjmp_args_warning,
+ setjmp_protect, setjmp_protect_args, fix_lexical_addr,
+ expand_function_start, diddle_return_value, clobber_return_register,
+ expand_function_end, keep_stack_depressed, handle_epilogue_set,
+ update_epilogue_consts): Likewise.
+ * genemit.c (gen_exp, gen_insn): Likewise.
+ * genrecog.c (make_insn_sequence): Likewise.
+ * global.c (global_conflicts, expand_preferences, mark_reg_store,
+ mark_reg_conflicts, set_preference, reg_becomes_live,
+ build_insn_chain, mark_reg_change): Likewise.
+ * haifa_sched.c (CONST_BASED_ADDRESS_P, find_set_reg_weight):
+ Likewise.
+ * ifcvt.c (noce_try_abs, noce_get_condition, noce_process_if_block):
+ Likewise.
+ * integrate.c (copy_rtx_and_substitute, try_constants,
+ subst_constants, mark_stores, allocate_initial_values): Likewise.
+ * jump.c (reversed_comparison_code_parts, delete_prior_computation,
+ delete_computation, rtx_renumbered_equal_p, true_regnum,
+ reg_or_subregno): Likewise.
+ * lcm.c (reg_dies, reg_becomes_live): Likewise.
+ * local-alloc.c (validate_equiv_mem_from_store, validate_equiv_mem,
+ update_equiv_regs, no_equiv, block_alloc, combine_regs, reg_is_set,
+ wipe_dead_reg, no_conflict_p): Likewise.
+ * loop-iv.c (simple_reg_p, simple_set_p, kill_sets,
+ iv_get_reaching_def, iv_analyze_biv, altered_reg_used, mark_altered,
+ simple_rhs_p, simplify_using_assignment, implies_p): Likewise.
+ * loop.c (scan_loop, combine_movables, rtx_equal_for_loop_p,
+ move_movables, note_set_pseudo_multiple_uses, consec_sets_invariant_p,
+ find_single_use_in_loop, count_one_set, loop_bivs_init_find,
+ loop_givs_rescan, check_insn_for_bivs, check_insn_for_givs,
+ valid_initial_value_p, simplify_giv_expr, consec_sets_giv,
+ loop_regs_update, check_dbra_loop, maybe_eliminate_biv,
+ maybe_eliminate_biv_1, record_initial, update_reg_last_use,
+ canonicalize_condition, loop_regs_scan, load_mems, try_copy_prop,
+ try_swap_copy_prop): Likewise.
+ * optabs.c (expand_binop, expand_vector_binop, expand_vector_unop,
+ expand_abs, emit_no_conflict_block, emit_libcall_block, expand_float):
+ Likewise.
+ * postreload.c (reload_cse_simplify, reload_cse_simplify_set,
+ reload_cse_simplify_operands, reload_combine,
+ reload_combine_note_store, reload_combine_note_use,
+ reload_cse_move2add, move2add_note_store): Likewise.
+ * print-rtl.c (print_rtx): Likewise.
+ * ra-build.c (copy_insn_p, remember_move, init_one_web_common,
+ contains_pseudo, handle_asm_insn): Likewise.
+ * ra-debug.c (ra_print_rtx_object, dump_constraints,
+ dump_static_insn_cost): Likewise.
+ * ra-rewrite.c (slots_overlap_p, emit_colors,
+ remove_suspicious_death_notes): Likewise.
+ * recog.c (validate_replace_rtx_1, find_single_use_1, find_single_use,
+ register_operand, scratch_operand, nonmemory_operand,
+ constrain_operands): Likewise.
+ * reg-stack (check_asm_stack_operands, remove_regno_note,
+ emit_swap_insn, swap_rtx_condition, subst_stack_regs_pat,
+ subst_asm_stack_regs): Likewise.
+ * regclass.c (scan_one_insn, record_reg_classes, copy_cost,
+ record_address_regs, reg_scan_mark_refs): Likewise.
+ * regmove.c (discover_flags_reg, replacement_quality,
+ copy_src_to_dest, reg_is_remote_constant_p, regmove_optimize,
+ fixup_match_1): Likewise.
+ * regrename.c (note_sets, clear_dead_regs, build_def_use, kill_value,
+ kill_set_value, copyprop_hardreg_forward_1): Likewise.
+ * reload.c (MATCHES, push_secondary_reload, find_reusable_reload,
+ reload_inner_reg_of_subreg, can_reload_into, push_reload,
+ combine_reloads, find_dummy_reload, hard_reg_set_here_p,
+ operands_match_p, decompose, find_reloads, find_reloads_toplev,
+ find_reloads_address, subst_indexed_address, find_reloads_address_1,
+ find_reloads_subreg_address, find_replacement,
+ refers_to_regno_for_reload_p, reg_overlap_mentioned_for_reload_p,
+ refers_to_mem_for_reload_p, find_equiv_reg, regno_clobbered_p): Likewise.
+ * reload1.c (replace_pseudos_in, reload, calculate_needs_all_insns,
+ find_reg, delete_dead_insn, alter_reg, eliminate_regs,
+ elimination_effects, eliminate_regs_in_insn, scan_paradoxical_subregs,
+ forget_old_reloads_1, reload_reg_free_for_value_p, choose_reload_regs,
+ emit_input_reload_insns, emit_output_reload_insns, do_input_reload,
+ do_output_reload, emit_reload_insns, gen_reload,
+ delete_address_reloads_1, inc_for_reload): Likewise.
+ * reorg.c (update_reg_dead_notes, fix_reg_dead_note,
+ update_reg_unused_notes, fill_slots_from_thread): Likewise.
+ * resource.c (update_live_status, mark_referenced_resources,
+ mark_set_resources, mark_target_live_regs): Likewise.
+ * rtlanal.c (nonzero_address_p, get_jump_table_offset,
+ global_reg_mentioned_p_1, reg_mentioned_p, reg_referenced_p,
+ reg_set_p, set_noop_p, find_last_value, refers_to_regno_p,
+ note_stores, dead_or_set_p, dead_or_set_regno_p, find_regno_note,
+ find_reg_fusage, find_regno_fusage, replace_regs, regno_use_in,
+ parms_set, find_first_parameter_load, keep_with_call_p,
+ hoist_test_store, hoist_update_store, address_cost, nonzero_bits1,
+ num_sign_bit_copies1): Likewise.
+ * rtlhooks.c (gen_lowpart_general): Likewise.
+ * sched-deps.c (deps_may_trap_p, sched_analyze_1, sched_analyze_insn,
+ sched_analyze): Likewise.
+ * sched-rgn.c (check_live_1, update_live_1, sets_likely_spilled_1):
+ Likewise.
+ * sdbout.c (sdbout_symbol, sdbout_parms, sdbout_reg_parms): Likewise.
+ * simplify-rtx.c (simplify_replace_rtx, simplify_unary_operation,
+ simplify_binary_operation, simplify_const_relational_operation,
+ simplify_subreg): Likewise.
+ * stmt.c (decl_conflicts_with_clobbers_p, expand_asm_operands,
+ expand_end_stmt_expr, expand_return, expand_decl,
+ expand_anon_union_decl): Likewise.
+ * unroll.c (precondition_loop_p, calculate_giv_inc, copy_loop_body,
+ find_splittable_regs, find_splittable_givs, find_common_reg_term,
+ loop_iterations): Likewise.
+ * var-tracking.c (variable_union, variable_part_different_p,
+ variable_different_p, count_uses, add_uses, add_stores,
+ compute_bb_dataflow, set_variable_part, delete_variable_part,
+ emit_notes_in_bb, vt_get_decl_and_offset, vt_add_function_parameters):
+ Likewise.
+ * varasm.c (assemble_variable): Likewise.
+
+2004-06-15 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/linux.h (ASM_PREFERRED_EH_DATA_FORMAT): Remove
+ definition.
+ * config/mips/linux64.h (ASM_PREFERRED_EH_DATA_FORMAT): Remove
+ #undef and #if 0'd definition.
+
+2004-06-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * combine.c (distribute_notes): Comment typo fix.
+
+2004-06-15 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (synth_mult): Mask bits of the multiplier to the
+ machine mode of the multiplication. Don't consider shifts
+ by more than (or equal to) the width of the operation's mode.
+
+2004-06-15 Paolo Bonzini <bonzini@gnu.org>
+
+ * doc/install.texi: Yet another update for autoconf
+ and automake versions.
+
+2004-06-15 Paolo Bonzini <bonzini@gnu.org>
+
+ * function.h (struct function): Remove cannot_inline field.
+ (current_function_cannot_inline): Remove.
+ * passes.c (rest_of_compilation): Reset DECL_DEFER_OUTPUT.
+ Simplify conditionals to ignore warn_return_type.
+ * tree-optimize.c (tree_rest_of_compilation): Do not reset
+ DECL_DEFER_OUTPUT.
+ * objc/objc-act.c (build_module_descriptor, finish_method_def):
+ Do not set current_function_cannot_inline.
+
+2004-06-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cfglayout.c (fixup_reorder_chain): Handle case where the
+ destination of E_TAKEN is EXIT_BLOCK_PTR.
+
+2004-06-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-copy.c (cprop_into_successor_phis): Fix typo.
+
+2004-06-15 Paolo Bonzini <bonzini@gnu.org>
+
+ * fold-const.c (operand_equal_p): Update comment.
+
+2004-06-15 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (RETURN_ADDR_RTX): Define.
+ (INCOMING_RETURN_ADDR_RTX): Define.
+ * config/m32r/m32r-protos.h (m32r_return_addr): Added.
+ * config/m32r/m32r.c (m32r_exppand_prologue): Changed for
+ __builtin_return_address(0).
+ (m32r_return_addr): Added for __builtin_return_address(0).
+ (m32r_reload_lr): Ditto.
+
+ * longlong.h: Fix macros for m32r add_ssaaaa and sub_ddmmss.
+
+2004-06-15 Paolo Bonzini <bonzini@gnu.org>
+
+ * doc/install.texi (Prerequisites): Update libbanshee,
+ fastjar, libcpp, libjava/libltdl entries to
+ automake 1.8.5.
+
+2004-06-15 Eric Botcazou <ebotcazou@act-europe.fr>
+ Olivier Hainque <hainque@act-europe.fr>
+
+ * function.c (fixup_var_refs): Also adjust the start of sequence
+ after fixing up the insns.
+
+2004-06-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * gccbug.in: Update optimization -> tree-optimization/rtl-optimization.
+
+2004-06-14 Benjamin Kosnik <bkoz@redhat.com>
+
+ * doc/install.texi (Prerequisites): Update libstdc++ entry to
+ automake 1.8.5.
+
+2004-06-14 Eric Christopher <echristo@redhat.com>
+
+ * config/s390/s390.h (TARGET_SWITCHES): Change -mtpf (-mno-tpf)
+ to -mtpf-trace (-mno-tpf-trace).
+ * doc/invoke.texi (S/390 and zSeries Options): Add tpf option
+ documentation.
+
+2004-06-14 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * real.c: Fix bit count in head comment.
+
+2004-06-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (kill_redundant_phi_nodes): More correctly handle
+ PHIs where the destination or an argument is marked with
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
+
+2004-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/15945
+ * simplify-rtx.c (simplify_binary_operation): Don't optimize out
+ Inf + -Inf, Inf - Inf, Inf / Inf and 0 * Inf if flag_trapping_math.
+
+2004-06-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * opts.sh (var_args): Fix regexp.
+
+2004-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/15178
+ * config/i386/sol2.h (ASM_OUTPUT_DEF_FROM_DECLS): Define.
+
+2004-06-14 Paul Brook <paul@codesourcery.com>
+
+ * dwarf2out.c (output_call_frame_info): Support dwarf3 cie entries.
+
+2004-06-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (FLAGS_H): New.
+ (flags.h): Replace by FLAGS_H.
+ * c.opt: Document Var, VarExists, Init and Report attributes.
+ * common.opt: Fill the values of the attributes.
+ * diagnostic.c (flag_fatal_errors): Do not define.
+ * except.c (flag_non_call_exceptions): Do not define.
+ * flags.h: Include options.h. Remove declarations conflicting with
+ the automatically defined ones.
+ * opts.c: Remove automatically defined variables.
+ (handle_option): Perform default initialization.
+ (common_handle_option): Do not handle options covered by the
+ default initialization.
+ * opts.h (struct cl_option): Add flag_var, has_set_value and set_value
+ fields.
+ (CL_REPORT): New.
+ * opts.sh: Generate variable declarations, handle CL_REPORT.
+ * toplev.c: Remove automatically defined variables.
+ (f_options): Removed.
+ (print_switch_values): Use cl_options instead of f_options.
+ * toplev.h (version_flag): Declaration removed.
+
+2004-06-14 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/sparc/sparc.h: Correct comment about availability of
+ little endian option.
+
+ * config.gcc: Remove sparc64-*-aout*.
+ * config/sparc/sparc.c (sparc_aout_select_rtx_section): Remove.
+ * config/sparc/sp64-aout.h: Remove.
+ * config/sparc/aout.h: Remove.
+
+2004-06-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c: Include "tree-gimple.h".
+ (s390_gimplify_va_arg): New function.
+ (TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
+ (s390_va_arg): Remove.
+ * config/s390/s390-protos.h (s390_va_arg): Remove.
+ * config/s390/s390.h (EXPAND_BUILTIN_VA_ARG): Call abort ().
+
+2004-06-14 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * basic-block.h (could_fall_through): Declare.
+ * cfganal.c (can_fallthru): Succeed if the target is EXIT_BLOCK_PTR.
+ Fail if the source already has a fallthrough edge to the exit
+ block pointer.
+ (could_fall_through): New function.
+ * cfgbuild.c (make_edges): Check if we already have a fallthrough
+ edge to the exit block pointer.
+ * cfglayout.c (fixup_fallthru_exit_predecessor): Check that it is
+ not called before reload has completed.
+ Handle special case of first block having a fall-through exit edge.
+ (cfg_layout_finalize): Don't call it before reload or if we have
+ rtl epilogues.
+ (fixup_reorder_chain): A fall through to the exit block does not
+ require the block to come last. Add sanity checks.
+ * cfgrtl.c (rtl_split_edge): Add special handling of fall through
+ edges to the exit block.
+ * function.c (cfglayout.h): #include.
+ (thread_prologue_and_epilogue_insns): If we have neither return nor
+ epilogue, but a fall through to the exit block from mid-function,
+ force a non-fall-through exit.
+ * Makefile.in (function.o): Depend on CFGLAYOUT_H.
+
+2004-06-14 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.h (ASM_CPU_SPEC): Handle -mpowerpc64 and -mcpu
+ for power5 and rs64a. Correct condition for default. Correct power3,
+ 620, 630, 7400, 7450, G4, 970 and G5 -mcpu entries. Add -many.
+
+2004-06-13 Steven Bosscher <stevenb@suse.de>
+
+ * gcse.c (hash_scan_set, hash_scan_insn, mark_set, mark_oprs_set):
+ Revert previous change, don't use CALL_P.
+
+2004-06-13 Jason Merrill <jason@redhat.com>
+
+ * tree.h: Move std_gimplify_va_arg_expr protoype here.
+ * tree-gimple.h: From here.
+
+2004-06-13 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR tree-optimization/15979
+ Fix PR tree-optimization/15981
+ * tree-ssa-pre.c (insert_aux): Fix faulty logic so that we don't
+ try to insert values undefined along some path.
+
+2004-06-13 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (add_to_value): is_gimple_min_invariant things
+ are available everywhere too.
+
+2004-06-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * fold-const.c (fold_checksum_tree <case 't'>): Only
+ look at TREE_VALUES if the EXPR is an ENUMERAL_TYPE.
+ Only look at TYPE_MIN_VALUE and TYPE_MAX_VALUE if
+ EXPR is an INTEGERAL_TYPE or a scalar float type.
+
+2004-06-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-sra.c (tree_sra): Update documentation.
+
+2004-06-13 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (comptypes, tagged_types_tu_compatible_p,
+ function_types_compatible_p, type_lists_compatible_p): Remove
+ flags parameter.
+ * c-tree.h (comptypes): Likewise.
+ (COMPARE_STRICT): Remove.
+ * c-decl.c, c-lang.c, c-parse.in, c-typeck.c, objc/objc-act.c: All
+ callers changed.
+
+2004-06-13 Eric Christopher <echristo@redhat.com>
+
+ * c-decl.c (diagnose_mismatched_decls): Improve error message.
+ Remove unused code.
+ * c-typeck.c (comptypes): Add location in standard we're checking.
+
+2004-06-13 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/libgcc-std.ver: Add __unorddf2 and __unordsf2 with
+ version 3.3.4.
+
+2004-06-12 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (shift_cost, shiftadd_cost, shiftsub_cost): Additionally
+ index by machine mode.
+ (init_expmed): Initialize shift_cost, shiftadd_cost and shiftsub_cost
+ tables inside the loop over machine modes.
+ (synth_mult, expand_mult_highpart_optab, expand_mult_highpart,
+ expand_divmod): Index shift*_cost by the appropriate machine mode.
+
+2004-06-12 Eric Christopher <echristo@redhat.com>
+
+ * config/s390/s390.h: Rename TARGET_TPF to TARGET_TPF_PROFILING.
+ * config/s390/s390.md: Ditto.
+ * config/s390/s390.c: Ditto.
+ (s390_frame_info): Conditionalize frame and setup info on
+ TARGET_TPF_PROFILING.
+ (s390_arg_frame_offset): Ditto.
+
+2004-06-12 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (omit_two_operands): New function.
+ * tree.h (omit_two_operands): Prototype here.
+ * builtins.c (fold_builtin_unordered_cmp): New function to lower
+ C99 unordered comparison builtins to the appropriate tree nodes.
+ (fold_builtin_1): Use fold_builtin_unordered_cmp to lower
+ BUILT_IN_ISGREATER, BUILT_IN_ISGREATEREQUAL, BUILT_IN_ISLESS,
+ BUILT_IN_ISLESSEQUAL and BUILT_IN_ISLESSGREATER. Manually lower
+ BUILT_IN_ISUNORDERED comparisons to an UNORDERED_EXPR tree node.
+ (simplify_builtin_memcmp, simplify_builtin_strncmp,
+ simplify_builtin_strncat, simplify_builtin_strspn): Use the new
+ omit_two_operands function to build the required COMPOUND_EXPRs.
+
+2004-06-12 Steven Bosscher <stevenb@suse.de>,
+ Andreas Jaeger <aj@suse.de>
+
+ * gcse.c (record_set_info): Use predicates like REG_P.
+ (mems_conflict_for_gcse_p): Likewise.
+ (load_killed_in_block_p): Likewise.
+ (hash_expr_1): Likewise.
+ (insert_set_in_table): Likewise.
+ (gcse_constant_p): Likewise.
+ (hash_scan_set): Likewise.
+ (hash_scan_insn): Likewise.
+ (canon_list_insert): Likewise.
+ (record_last_mem_set_info): Likewise.
+ (record_last_set_info): Likewise.
+ (compute_hash_table_work): Likewise.
+ (mark_set): Likewise.
+ (mark_clobber): Likewise.
+ (mark_oprs_set): Likewise.
+ (compute_transp): Likewise.
+ (find_avail_set): Likewise.
+ (cprop_insn): Likewise.
+ (do_local_cprop): Likewise.
+ (cprop): Likewise.
+ (find_implicit_sets): Likewise.
+ (find_bypass_set): Likewise.
+ (bypass_conditional_jumps): Likewise.
+ (insert_insn_end_bb): Likewise.
+ (pre_insert_copy_insn): Likewise.
+ (compute_transpout): Likewise.
+ (next_ls_expr): Likewise.
+ (invalidate_any_buried_refs): Likewise.
+ (compute_ld_motion_mems): Likewise.
+ (reg_set_info): Likewise.
+ (reg_clear_last_set): Likewise.
+ (find_moveable_store): Likewise.
+ (compute_store_table): Likewise.
+ (find_loads): Likewise.
+ (store_killed_in_insn): Likewise.
+ (insert_insn_start_bb): Likewise.
+ (reg_set_between_after_reload_p): Likewise.
+ (reg_used_between_after_reload_p): Likewise.
+ (is_jump_table_basic_block): Likewise.
+ (gcse_after_reload): Likewise.
+ (hash_scan_set_after_reload): Likewise.
+ (compute_hash_table_after_reload): Likewise.
+
+2004-06-12 Steven Bosscher <stevenb@suse.de>
+
+ * rtl.h (MEM_P, NONJUMP_INSN_P, CALL_INSN_P): New predicates.
+ (INSN_P): Don't look at the rtx code class, just explicitly
+ check for one of the tree RTX_INSN codes.
+
+2004-06-11 Zack Weinberg <zack@codesourcery.com>
+
+ * c-typeck.c (default_function_array_conversion): Use
+ build_pointer_type not TYPE_POINTER_TO.
+
+2004-06-11 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.ac: Don't invoke ACX_HEADER_STDBOOL.
+ * configure, config.in: Regenerate.
+ * system.h: Unconditionally define bool as unsigned char,
+ BOOL_BITFIELD as unsigned int.
+ * domwalk.h: Use BOOL_BITFIELD.
+
+2004-06-12 Andreas Jaeger <aj@suse.de>
+
+ * libgcc-std.ver: Add __unorddf2 and __unordsf2 with version 3.3.4.
+ * libgcc-darwin.ver: Likewise.
+
+2004-06-12 Peter Jakubek <peter@laseranimation.com>
+
+ * reload.c (find_reloads): Force reload for pseudo registers on big
+ endian machines.
+
+2004-06-11 Steven Bosscher <stevenb@suse.de>
+
+ * tree-ssa-dce.c (mark_control_dependent_edges_necessary):
+ Don't try to mark anything control dependent on the entry or
+ exit blocks.
+
+2004-06-11 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix Bug 15899
+ Fix Bug 15460
+ * tree.h (SSA_NAME_VALUE): New macro.
+ (struct tree_ssa_name): Add value_handle member.
+ * tree-ssa-pre.c: Replaced.
+ * tree-flow.h (tree_ann_type): Add CST_ANN, EXPR_ANN.
+ (struct cst_ann_d): New.
+ (struct expr_ann_d): New.
+ (union tree_ann_d): Add cst_ann, expr_ann.
+ * tree-dfa.c (create_cst_ann): New function.
+ (create_expr_ann): Ditto.
+ * tree-flow-inline.h (cst_ann): New function.
+ (expr_ann): Ditto.
+ (get_cst_ann): Ditto.
+ (get_expr_ann): Ditto..
+
+2004-06-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_hpux_init_libfunc): Add support for unord_optab.
+ * pa/quadlib.c (enum qfcmp_magic): Define magic values for call to
+ _U_Qfcmp library function.
+ (_U_Qfltgt, _U_Qfunle, _U_Qfunlt, _U_Qfunge, _U_Qfungt, _U_Qfuneq,
+ _U_Qfunord, _U_Qford): Add more TFmode builtin compare functions.
+
+ * pa.c (legitimize_pic_address): Use UNSPEC_DLTIND14R to identify
+ unspec used for loading address from DLT.
+ * pa.md: Define constants for the uses of UNSPEC and UNSPEC_VOLATILE.
+ Change all users of UNSPEC and UNSPEC_VOLATILE to use new constants.
+ Don't use short code sequence when loading the address of a nonlocal
+ label.
+ (nonlocal_goto): New expander.
+ (indirect_goto): New jump pattern for nonlocal gotos.
+ (short_jump): Remove extra whitespace.
+ (builtin_longjmp): Clobber memory and hard frame pointer. Restore
+ frame pointer via virtual_stack_vars_rtx when we have a nonlocal goto
+ pattern.
+
+2004-06-11 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (synth_mult): Add an additional MODE argument for the
+ machine mode of the multiplication. Update recursive calls. Use
+ mode instead of word_mode for determining operation costs.
+ (choose_mult_variant): Update calls to synth_mult with "mode".
+
+2004-06-11 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-operands.c (get_stmt_operands): Clear makes_aliased_loads
+ and makes_aliased_stores.
+
+2004-06-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * doc/install.text (--enable-shared): Fix typo.
+
+2004-06-11 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_gimplify_va_arg_1): Remove post_p
+ argument. Use internal post for call to gimplify_expr. Tidy
+ rounded type size computation.
+ (alpha_gimplify_va_arg): Use get_formal_tmp_var and
+ get_initialized_tmp_var.
+
+2004-06-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * doc/install.texi (--enable-shared): Update libobjc's shared library
+ status. Remove reference to libf2c.
+
+2004-06-11 Jason Merrill <jason@redhat.com>
+
+ * config/i386/i386.h (EXPAND_BUILTIN_VA_ARG): Just abort.
+ * config/i386/i386.c (ix86_va_arg): Remove.
+ * config/rs6000/rs6000.h (EXPAND_BUILTIN_VA_ARG): Just abort.
+ * config/rs6000/rs6000.c (rs6000_va_arg): Remove.
+ * config/alpha/alpha.h (EXPAND_BUILTIN_VA_ARG): Just abort.
+ * config/alpha/alpha.c (alpha_va_arg): Remove.
+ * config/sparc/sparc.h (EXPAND_BUILTIN_VA_ARG): Just abort.
+ * config/sparc/sparc.c (sparc_va_arg): Remove.
+
+ * tree-ssa-operands.c (get_stmt_operands): Use a V_MAY_DEF if the
+ assignment might throw.
+ * tree-eh.c (tree_could_throw_p): Support non-call exceptions in
+ expressions.
+
+2004-06-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR 15886:
+ * sh.h (ALLOCATE_INITIAL_VALUE): Use return_address_pointer_rtx.
+
+2004-06-11 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install.texi (Prerequisites): Update documentation of
+ required versions of autoconf and automake. Remove mention of
+ libf2c.
+
+2004-06-11 Jason Merrill <jason@redhat.com>
+
+ * config/sparc/sparc.c (sparc_gimplify_va_arg): New fn.
+ (TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
+
+2004-06-11 Jerry Quinn <jlquinn@optonline.net>
+
+ * typeclass.h: Add GPL plus exception license. Add include
+ guard.
+
+2004-06-10 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr): Don't force a temporary
+ of an aggregate_value_p type.
+
+2004-06-10 Jeff Law <law@redhat.com>
+
+ * fold-const.c (fold_inf_compare): Avoid creating non-gimple
+ code when we are in gimple form.
+
+2004-06-10 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssanames.o): Depend on TREE_FLOW_H.
+ * tree-flow.h (ssa_names, num_ssa_names, ssa_name): Declare.
+ (highest_ssa_version): Remove.
+ * tree-outof-ssa.c (new_temp_expr_table): Replace
+ highest_ssa_version with num_ssa_names.
+ (dump_replaceable_exprs): Likewise.
+ (rewrite_vars_out_of_ssa): Likewise.
+ * tree-ssa-ccp.c (initialize): Likewise
+ * tree-ssa-copyrename.c (rename_ssa_copies): Likewise.
+ * tree-ssa-dce.c (tree_dce_init): Likewise.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Likewise.
+ * tree-ssa-live.c (create_ssa_var_map): Likewise.
+ (dump_var_map): Likewise.
+ * tree-ssa.c (verify_ssa): Likewise.
+ (kill_redundant_phi_nodes): Likewise.
+ Do not build a local array of SSA_NAMEs. Use the ssa_names table.
+ * tree-ssanames.c: Include tree-flow.h
+ (ssa_names): New varray.
+ (init_ssa_names): Initialize ssa_names.
+ Reserve the first slot of the ssa_names table.
+ (make_ssa_name): Push the newly created SSA_NAME into ssa_names.
+ Assign version numbers using num_ssa_names.
+
+2004-06-10 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/sourcebuild.texi (Front End): Add details of more
+ installation documentation required.
+
+2004-06-10 Brian Booth <bbooth@redhat.com>
+
+ * doc/tree-ssa.texi: Remove references to VDEF and add descriptions
+ of V_MAY_DEF and V_MUST_DEF.
+ * tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename
+ num_vdefs to num_v_may_defs.
+ (compute_immediate_uses_for_stmt): Rename occurences of vdef
+ to v_may_def.
+ (redirect_immediate_uses): Ditto.
+ (dump_dfa_stats): Ditto. Also added code to dump num_v_must_defs.
+ (collect_dfa_stats_r): Rename occurences of vdef to v_may_def.
+ Also add code to sum up the number of v_must_defs.
+ (vdefs_disappeared_p): Replace with...
+ (v_may_defs_disappeared_p): This.
+ (v_must_defs_disappeared_p): New function.
+ (mark_new_vars_to_rename): Rename occurences of vdef to v_may_def.
+ Also add code to mark new variables found in V_MUST_DEFs for
+ renameing.
+ * tree-flow.h (stmt_ann_d): Add v_must_def_ops and replace
+ vdef_ops to v_may_def_ops.
+ (get_vdef_ops): Replace with...
+ (get_v_may_def_ops): This.
+ * tree-flow-inline.h (get_vdef_ops): Replace with...
+ (get_v_may_def_ops): This.
+ (get_v_must_def_ops): New function.
+ (get_vdef_result_ptr): Replace with...
+ (get_v_may_def_result_ptr): This.
+ (get_vdef_op_ptr): Ditto with...
+ (get_v_may_def_op_ptr); This.
+ (get_v_must_def_op_ptr): New function.
+ * tree-into-ssa.c (mark_def_sites): Rename occurences of vdef
+ to v_may_def. Also add code to mark statements with
+ V_MUST_DEFs as definition sites.
+ (rewrite_stmt): Rename occurences of vdef to v_may_def. Also
+ add code to register new V_MUST_DEFs made by the statement.
+ * tree-outof-ssa.c (VIRTUAL_PARTITION): Update comments.
+ (check_replaceable): Rename occurences of vdef to v_may_def. Also
+ add check for V_MUST_DEFs.
+ (find_replaceable_in_bb): Ditto.
+ * tree-pretty-print.c (dump_vops): Rename occurences of vdef
+ to v_may_def. Also add code to dump V_MUST_DEFs.
+ * tree-sra.c (mark_all_vdefs): Replace with...
+ (mark_all_v_may_defs): This.
+ (mark_all_v_must_defs): New function.
+ (create_scalar_copies): Replace call to mark_all_vdefs with
+ calls to mark_all_v_may_defs and mark_all_v_must_defs.
+ (scalarize_structures): Rename occurences of vdef to v_may_def.
+ Also add a check for V_MUST_DEFs.
+ (scalarize_modify_expr): Rename occurences of vdef to v_may_def.
+ * tree-ssa-alias.c (global_var): Update comment.
+ (compute_may_aliases): Ditto.
+ (compute_points_to_and_addr_escape): Rename occurences of vdef
+ to v_may_def. Also add code to mark variables in V_MUST_DEF
+ operands as being written to.
+ (group_aliases): Update comment.
+ (maybe_create_global_var): Ditto.
+ * tree-ssa.c (verify_ssa): Rename occurences of vdef to v_may_def.
+ Also add a check for V_MUST_DEFs on GIMPLE registers.
+ (replace_immediate_uses): Rename occurences of vdef to v_may_def.
+ * tree-ssa-ccp.c (visit_stmt): Rename occurences of vdef
+ to v_may_def. Also add code to mark all V_MUST_DEF operands
+ VARYING.
+ (initialize): Ditto.
+ (set_rhs): Rename occurences of vdef to v_may_def. Also add
+ code to update SSA_NAMEs in V_MUST_DEFs.
+ * tree-ssa-copy.c (cprop_into_stmt): Rename occurences of vdef
+ to v_may_def.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Rename
+ occurences of vdef to v_may_def. Also add code to mark statements
+ with V_MUST_DEFs as necessary.
+ (propagate_necessity): Rename occurences of vdef to v_may_def.
+ * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Rename
+ occurences of vdef to v_may_def. Also add code to mark operands
+ in V_MUST_DEFs for renaming.
+ (eliminate_redundant_computations): Rename occurences of vdef
+ to v_may_def.
+ (record_equivalences_from_stmt): Rename occurences of vdef
+ to v_may_def. Also add code to record VUSEs for V_MUST_DEFs.
+ (optimize_stmt): Remove unnesessary variable vdefs. Update
+ comment.
+ (register_definitions_for_stmt): Rename occurences of vdef
+ to v_may_def. Also add code to register definitions made with
+ V_MUST_DEFs.
+ * tree-ssa-dse.c (fix_stmt_vdefs): Replace with...
+ (fix_stmt_v_may_defs): This.
+ (fix_phi_uses): Rename occurences of vdef to v_may_def.
+ (dse_optimize_stmt): Ditto.
+ * tree-ssa-live.c (create_ssa_var_map): Rename occurences of vdef
+ to v_may_def. Also add code to mark V_MUST_DEF operands as being
+ used in virtual operators.
+ * tree-ssa-loop.c (mark_defs_for_rewrite): Rename occurences of
+ vdef to v_may_def. Also add code to mark V_MUST_DEF operands for
+ renaming.
+ * tree-ssa-operands.c (opf_kill_def): New flag for killing
+ definitions.
+ (build_vdefs): Renamed to...
+ (build_v_may_defs): This.
+ (build_v_must_defs): New variable.
+ (voperands_d): Add v_must_def_ops and replace vdef_ops with
+ v_may_def_ops.
+ (append_vdef): Replace with...
+ (append_v_may_def): This.
+ (append_v_must_def): New function.
+ (NUM_FREE): Increment for V_MUST_DEF
+ (optype_freelist): Increment its size for V_MUST_DEF
+ (allocate_vdef_optype): Replace with...
+ (allocate_v_may_def_optype): This.
+ (allocate_v_must_def_optype): New function.
+ (free_vdefs): Replace with...
+ (free_v_may_defs): This.
+ (free_v_must_defs): New function.
+ (remove_vdefs): Replace with...
+ (remove_v_may_defs): This.
+ (remove_v_must_defs): New function.
+ (init_ssa_operands): Rename occurences of vdef to v_may_def. Also
+ add code to initialize build_v_must_defs.
+ (finalize_ssa_vdefs): Replace with...
+ (finalize_ssa_v_may_defs): This.
+ (finalize_ssa_vuses): Rename occurences of vdef to v_may_def.
+ (finalize_ssa_v_must_defs): New function.
+ (finalize_ssa_stmt_operands): Replace call to finalize_ssa_vdefs
+ with calls to finalize_ssa_v_may_defs and finalize_ssa_v_must_defs.
+ (verify_start_operands): Rename occurences of vdef to v_may_def.
+ Also add check for build_v_must_defs.
+ (get_stmt_operands): Rename occurences of vdef to v_may_def.
+ Also add code to handle V_MUST_DEFs and to use opf_kill_def for
+ killing definitions.
+ (get_expr_operands): Update comment and use opf_kill_def for
+ killing definitions.
+ (add_stmt_operand): Replace code that appends VDEFs with code
+ that appends V_MUST_DEFs when opf_kill_def is set and V_MAY_DEFs
+ otherwise.
+ (add_call_clobber_ops): Update comments.
+ * tree-ssa-operands.h (vdef_optype_d): Replace with...
+ (v_may_def_optype_d): This.
+ (v_must_def_optype_d): New structure.
+ (VDEF_OPS): Replace with...
+ (V_MAY_DEF_OPS): This.
+ (STMT_VDEF_OPS): Same with...
+ (STMT_V_MAY_DEF_OPS): This.
+ (NUM_VDEFS): And...
+ (NUM_V_MAY_DEFS): This.
+ (VDEF_RESULT_PTR): As well as...
+ (V_MAY_DEF_RESULT_PTR): This.
+ (VDEF_RESULT): Same goes for...
+ (V_MAY_DEF_RESULT): This.
+ (VDEF_OP_PTR): And...
+ (V_MAY_DEF_OP_PTR): This.
+ (VDEF_OP): And...
+ (V_MAY_DEF_OP): This.
+ (V_MUST_DEF_OPS): New macro.
+ (STMT_V_MUST_DEF_OPS): Ditto.
+ (NUM_V_MUST_DEFS): Ditto.
+ (V_MUST_DEF_OP_PTR): Ditto.
+ (V_MUST_DEF_OP): Ditto.
+ (remove_vdefs): Replace signature with...
+ (remove_v_may_defs): This.
+ (remove_v_must_defs): New function signature.
+ * tree-ssa-pre.c (subst_phis): Replace call to remove_vdefs
+ with calls to remove_v_may_defs and remove_v_must_defs.
+ (process_left_occs_and_kills): Rename occurences of vdef to v_may_def.
+ Also add code that marks left occurences of operands in V_MUST_DEFs.
+ * tree-tailcall.c (find_tail_calls): Rename occurences of vdef
+ to v_may_def. Also add check for V_MUST_DEFs.
+ (eliminate_tail_call):Rename occurences of vdef to v_may_def.
+
+2004-06-10 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/15653
+ * haifa-sched.c (schedule_block): Finish cycle after issuing asm
+ insn.
+
+2004-06-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR web/15263
+ * doc/install.texi: Remove superfluous linebreak.
+
+2004-06-10 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin): Fall back to library function call for
+ conj, conjf, conjl, creal, crealf, creall, cimag, cimagf and cimagl.
+ (fold_builtin_1): Lower built-ins BUILT_IN_CONJ{,F,L} to CONJ_EXPR,
+ BUILT_IN_CREAL{,F,L} to REALPART_EXPR, and BUILT_IN_CIMAG{,F,L} to
+ IMAGPART_EXPR respectively.
+
+2004-06-10 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (dump_table): New argument start. Changed caller.
+ (fixup_mova): New function.
+ (find_barrier): Use it.
+ (sh_reorg): Likewise. Check for CODE_FOR_casesi_worker_2.
+ If the label a mova refers to is above the mova itself, change
+ the mova into a load.
+ * sh.md (*casesi_worker): Rename to:
+ (casesi_worker_1).
+ (casesi_worker_2): New insn.
+
+2004-06-10 Jason Merrill <jason@redhat.com>
+
+ * target.h (struct gcc_target): Change gimplify_va_arg_expr
+ hook signature.
+ * tree-gimple.h: Adjust.
+ * config/alpha/alpha.c (alpha_gimplify_va_arg): Adjust.
+ * config/i386/i386.c (ix86_gimplify_va_arg): Adjust.
+ Use fold_convert.
+ * config/ia64/ia64.c (ia64_gimplify_va_arg): Adjust.
+ * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust.
+ Use COMPLEX_EXPR for complex numbers. Use fold_convert.
+ * builtins.c (std_gimplify_va_arg_expr): Adjust. Use fold_convert.
+ (gimplify_va_arg_expr): Return GS_ERROR in error case.
+ Gimplify valist rather than calling stabilize_va_list.
+
+2004-06-10 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (df.o): Remove fibheap dependency.
+ * df.h: Do not include sbitmap.h.
+ (struct ref): New field "data".
+ (DF_REF_DATA): New accessor macro.
+ (struct df): Field "dom" removed.
+ (df_analyze_subcfg): New function.
+ (transfer_function_sbitmap, transfer_function_bitmap): Replaced by ...
+ (transfer_function): ... new type.
+ (iterative_dataflow_sbitmap, iterative_dataflow_bitmap): Replaced by ...
+ (iterative_dataflow): ... new function.
+ (enum set_representation, struct dataflow): New.
+ * df.c: Do not include fibheap.h.
+
+ (df_reg_def_chain_clean, df_reg_use_chain_clean,
+ (df_bb_table_realloc, df_analyse_subcfg, free_reg_ref_chain,
+ prune_to_subcfg, df_bb_modify): New functions.
+ (df_bitmaps_alloc, df_reg_def_chain_create, df_reg_use_chain_create,
+ df_refs_update, df_reg_table_realloc, df_ref_create,
+ df_bb_reg_def_chain_create, df_bb_reg_use_chain_create,
+ df_bb_rd_local_compute, df_bb_ru_local_compute, df_bb_lr_local_compute,
+ df_analyse_1, df_insn_modify): Support analysing only a part of the cfg.
+
+ (dataflow_set_a_op_b, dataflow_set_copy): New functions.
+ (df_rd_transfer_function, df_ru_transfer_function,
+ df_lr_transfer_function): Type of bitmaps changed to void *.
+ (hybrid_search_bitmap, hybrid_search_sbitmap): Merge into ...
+ (hybrid_search): ... new function.
+ (iterative_dataflow_bitmap, iterative_dataflow_sbitmap): Merge into ...
+ (iterative_dataflow): ... new function. Avoid use of fibheaps for
+ a worklist. Do not process basic blocks unnecessarily.
+
+2004-06-10 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_abs_const): Make extern.
+ * tree.h (fold_abs_const): Prototype here.
+ * builtins.c (fold_builtin_fabs): New function to transform
+ fabs, fabsf and fabsl builtins into ABS_EXPR tree nodes.
+ (fold_builtin_abs): New function to transform abs, labs, llabs
+ and imaxabs builtins into ABS_EXPR tree nodes.
+ (expand_builtin): Fall back to a function call for abs, labs,
+ llabs and imaxabs builtins that survive constant folding.
+ (fold_builtin_1): Call fold_builtin_fabs for FABS, FABSF and
+ FABSL, and fold_builtin_abs for ABS, LABS, LLABS and IMAXABS.
+
+2004-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/unwind-ia64.c (uw_frame_state_for): Don't assume a
+ leaf function without unwind info at RP 0.
+
+2004-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/14791
+ * tree.h (enum tree_index): Add TI_FILEPTR_TYPE.
+ (fileptr_type_node): Define.
+ * tree.c (build_common_tree_nodes_2): Initialize
+ fileptr_type_node to ptr_type_node.
+ * c-common.c (c_common_nodes_and_builtins): For C++, make
+ fileptr_type_node a distinct type copy.
+ * builtin-types.def (BT_FILEPTR, BT_FN_INT_CONST_STRING_FILEPTR,
+ BT_FN_INT_INT_FILEPTR, BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG,
+ BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
+ BT_FN_INT_FILEPTR_CONST_STRING_VAR): Add.
+ (BT_FN_INT_CONST_STRING_PTR, BT_FN_INT_INT_PTR,
+ BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, BT_FN_INT_PTR_CONST_STRING_VAR,
+ BT_FN_INT_PTR_CONST_STRING_VALIST_ARG): Remove.
+ * builtins.def (BUILT_IN_FPRINTF, BUILT_IN_FPRINTF_UNLOCKED,
+ BUILT_IN_FPUTC, BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS,
+ BUILT_IN_FPUTS_UNLOCKED, BUILT_IN_FSCANF, BUILT_IN_FWRITE,
+ BUILT_IN_FWRITE_UNLOCKED, BUILT_IN_VFPRINTF, BUILT_IN_VFSCANF): Use
+ the above *FILEPTR* types instead of *PTR*.
+
+2004-06-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa.c (verify_ssa): Verify that vdefs/makes_aliased_stores
+ match.
+
+2004-06-09 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_not_const): New function.
+ (fold) <ABS_EXPR>: Don't bother testing wins.
+ (fold) <BIT_NOT_EXPR>: Call fold_not_const.
+ (nondestructive_fold_unary_to_constant) <BIT_NOT_EXPR>: Likewise.
+
+2004-06-09 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/15228
+ * function.c (assign_parms): Always set_mem_align with the computed
+ FUNCTION_ARG_BOUNDARY. Don't clear stack_parm if !STRICT_ALIGNMENT.
+
+2004-06-09 Richard Henderson <rth@redhat.com>
+
+ PR opt/15108
+ * tree-tailcall.c (find_tail_calls): Don't check early for
+ tail_recursion failure.
+
+2004-06-09 Diego Novillo <dnovillo@redhat.com>
+
+ Move SSA_NAME annotations into tree_ssa_name.
+
+ * tree-dfa.c (create_ssa_name_ann): Remove.
+ * tree-flow-inline.h (ssa_name_ann, get_ssa_name_ann): Remove.
+ * tree-flow.h (enum tree_ann_type): Remove SSA_NAME_ANN.
+ (struct ssa_name_ann_d): Remove.
+ (union tree_ann_d): Update.
+ (ssa_name_ann_t): Remove.
+ * tree-ssa-alias.c: (get_ptr_info): New local function.
+ Replace references to ssa_name_ann_t with struct ptr_info_def.
+ * tree-ssa-operands.c (get_expr_operands): Likewise.
+ * tree.h (SSA_NAME_PTR_INFO): Define.
+ (struct ptr_info_def): Declare.
+ (struct tree_ssa_name): Add field 'ptr_info'.
+
+2004-06-09 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (i386_pe_output_labelref): Correct
+ misplaced ')'.
+
+2004-06-09 Steven Bosscher <stevenb@suse.de>
+
+ * config/i386/k6.md: Rewrite using the DFA model.
+ * config/i386/i386.c (ix86_adjust_cost): Don't increase the
+ cost of load-operation insns for the K6.
+ (ia32_use_dfa_pipeline_interface): Add TARGET_K6.
+ (ia32_multipass_dfa_lookahead): Likewise.
+
+2004-06-09 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_gimplify_va_arg_1,
+ alpha_gimplify_va_arg, TARGET_GIMPLIFY_VA_ARG_EXPR): New.
+
+2004-06-09 Richard Henderson <rth@redhat.com>
+
+ * expmed.c (emit_store_flag): Cope with FLOAT_STORE_FLAG_VALUE.
+
+2004-06-09 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (CPPLIB_H): Put files in order of inclusion.
+ (CPP_ID_DATA_H): New.
+ (gtype-desc.o): Update dependencies.
+ (GTFILES): Use CPP_ID_DATA_H.
+
+2004-06-09 Mark Mitchell <mark@codesourcery.com>
+
+ Revert:
+ PR c++/15815
+ 2004-06-07 Mark Mitchell <mark@codesourcery.com>
+ * doc/extend.texi: Deprecate #pragma interface and #pragma
+ implementation.
+
+2004-06-09 David S. Miller <davem@nuts.davemloft.net>
+
+ * config/sparc/sparc.h (MOVE_RATIO): New definition.
+
+2004-06-09 Richard Henderson <rth@redhat.com>
+
+ * basic-block.h (struct edge_def): Add goto_locus.
+ * tree-cfg.c (make_goto_expr_edges): Set it.
+ (disband_implicit_edges): Use it.
+ * tree-pretty-print.c (dump_implicit_edges): Print it.
+
+2004-06-08 Anil Paranjpe <anilp1@kpitcummins.com>
+
+ * h8300.md (ldm_h8300s_4): Fix condition for expander.
+
+2004-06-08 Jason Merrill <jason@redhat.com>
+
+ Gimplify VA_ARG_EXPR into simpler forms.
+ * target.h: Add gimplify_va_arg_expr hook.
+ * target-def.h: Add TARGET_GIMPLIFY_VA_ARG_EXPR.
+ * fold-const.c (build_fold_addr_expr)
+ (build_fold_addr_expr_with_type): Move from gimplify.c.
+ * tree.h: Declare them.
+ * gimplify.c (gimplify_and_add): New fn.
+ (build_addr_expr, build_addr_expr_with_type): Move to fold-const.c.
+ (gimplify_array_ref_to_plus, gimplify_modify_expr)
+ (gimplify_expr): Use build_fold_*.
+ (copy_if_shared_r): Only mark VA_ARG_EXPR volatile if we
+ don't know how to gimplify it.
+ * builtins.c (std_gimplify_va_arg_expr): New fn.
+ (dummy_object): New static fn.
+ (gimplify_va_arg_expr): New fn.
+ (stabilize_va_list): Use build_fold_*.
+ * tree-gimple.h: Declare new fns.
+ * config/i386/i386.c (TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
+ (ix86_gimplify_va_arg): New fn.
+ * config/ia64/ia64.c (TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
+ (ia64_gimplify_va_arg): New fn.
+ * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): New fn.
+ (TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
+ * alias.c (get_varargs_alias_set): Just return 0 for now.
+
+ * c-objc-common.c (c_tree_printer): Improve handling of %T.
+
+2004-06-09 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-complex.c (expand_complex_comparison): Use fold_convert instead
+ of convert.
+ * tree-inline.c (setup_one_parameter): Likewise.
+ * tree-sra.c (csc_build_component_ref): Likewise.
+ * tree-ssa-ccp.c (ccp_fold): Likewise.
+ * tree-ssa-copy.c (cprop_operand): Likewise.
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Likewise.
+ * tree-tailcall.c (tree_optimize_tail_calls_1): Likewise.
+
+2004-06-09 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR rtl-optimization/15521:
+ * sched-int.h (in_post_call_group_p): Change type to enum.
+ * sched-deps.c (sched_analyze_insn):
+ (sched_analyze): When in_post_call_group_p is post_call_initial,
+ don't add a dependency, but still set SCHED_GROUP_P and CANT_MOVE,
+ and also reset in_post_call_group_p to post_call.
+ (sched_analyze): When the previous basic block ended in a CALL_INSN,
+ initialize in_post_call_group_p as post_call_initial.
+ (init_deps): initialize in_post_call_group_p to not_post_call.
+
+2004-06-09 Arnaud Charlet <charlet@act-europe.fr>
+
+ PR ada/6637
+ * doc/install.texi: List ada, libada as options to --enable-shared
+
+2004-06-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * aclocal.m4 (gcc_AC_PROG_LN): Remove.
+ (gcc_AC_CHECK_DECLS): Use AH_TEMPLATE to generate
+ config.in entries.
+ * configure.ac: Call ACX_PROG_LN, falling back to $LN_S
+ if hard links are not available.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2004-06-08 Per Bothner <per@bothner.com>
+
+ * configure.ac: New --enable-mapped-location sets USE_MAPPED_LOCATION.
+
+2004-06-08 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * toplev.c (floor_log2_wide): Correct casts for 64-bit hosts.
+ Correct formatting.
+
+2004-06-08 James E Wilson <wilson@specifixinc.com>
+
+ PR target/15790
+ * config/i386/i386-coff.h (ASM_OUTPUT_ALIGN): Define.
+
+2004-06-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * fold-const.c (fold_convert): Treat OFFSET_TYPE like
+ POINTER_TYPE and INTEGER_TYPE.
+
+2004-06-08 Bernardo Innocenti <bernie@develer.com>
+
+ * modulo-sched.c: Compile only when INSN_SCHEDULING is
+ defined.
+
+2004-06-08 Jeff Law <law@redhat.com>
+
+ * doc/contrib.texi: Add entries for Stefan Olsson and
+ Ola Ronnerup.
+
+2004-06-08 DJ Delorie <dj@redhat.com>
+
+ * toplev.c (floor_log2_wide): Replace loop with faster bit
+ operations.
+ (exact_log2_wide): Define in terms of the above.
+ * toplev.h (floor_log2): Use _builtin_clz family of builtins if
+ available.
+
+2004-06-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (print_operand, <case 'z'>):
+ Make sure that we are in INDIRECT mode when getting the
+ stub name.
+
+2004-06-08 Anil Paranjpe <anilp1@kpitcummins.com>
+
+ * h8300.md (extendqisi2_h8300): Add constraints.
+ (ldm_h8300s_4_normal): Fix typo.
+
+2004-06-08 Richard Henderson <rth@redhat.com>
+
+ * gimple-low.c (struct lower_data): Replace the_return_label and
+ one_return_stmt with return_statements.
+ (lower_function_body): Process the entire list of return_statements.
+ (lower_return_expr): Check source value before unifying return_exprs.
+ * gimplify.c (gimplify_return_expr): Force the use of a temporary
+ for !aggregate_value_p.
+ * tree-gimple.c: Update RETURN_EXPR grammer.
+
+2004-06-08 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/15598
+ * config/ia64/ia64.c (bundling): Add missed TYPE_A.
+
+2004-06-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR rtl-optimization/15717
+ * config/i386/i386.c (legitimate_constant_p): Do not allow
+ x - symbol_ref.
+
+2004-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * gimplify.c (copy_if_shared_r): Revert:
+ 2004-05-21 Richard Henderson <rth@redhat.com>
+ * gimplify.c [...] Don't mark VA_ARG_EXPRs volatile here.
+
+2004-06-07 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (add_cost, neg_cost, sdiv_pow2_cheap, smod_pow2_cheap):
+ Make arrays indexed by machine mode. Rename negate_cost to neg_cost.
+ (init_expmed): Initialize these cost arrays as appropriate.
+ (store_bit_field, extract_bit_field): Correct whitespace.
+ (synth_mult, choose_mult_variant, expand_mult, expand_mult_highpart,
+ expand_mult_highpart_optab, expand_divmod): Update uses of add_cost,
+ neg_cost, sdiv_pow2_cheap, smod_pow2_cheap to index with mode,
+ word_mode or compute_mode as appropriate.
+
+2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/15783
+ * config/sparc/sparc.c (function_arg_union_value): Add 'mode'
+ parameter. Enumerate the registers inside the PARALLEL.
+ (function_arg): Adjust call to function_arg_union_value.
+ (function_value): Likewise.
+
+ * config/sparc/sparc.c (sparc_function_epilogue): Properly format.
+
+2004-06-07 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_copysign): New function to implement libm's copysign.
+ * real.h (real_copysign): Prototype here.
+ * fold-const.c (tree_expr_nonnegative_p): The result of sqrt, sqrtf
+ and sqrtl can be negative, as sqrt(-0.0) = -0.0. Correct whitespace.
+ * builtins.c (fold_builtin_isascii, fold_builtin_toascii,
+ fold_builtin_isdigit): Add function prototypes.
+ (fold_builtin_copysign): New function to fold copysign, copysignf
+ and copysignl. Optimize copysign(x,x) as x. Evaluate copysign of
+ constant arguments at compile-time using real_copysign. Fold
+ copysign(X,Y) as fabs(X) if Y is always non-negative.
+ (fold_builtin_1): Correct minor whitespace/style issues. Call
+ fold_builtin_copysign for BUILT_IN_COPYSIGN{,F,L}.
+
+2004-06-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * tree.c (iterative_hash_expr): Use real_hash.
+
+2004-06-07 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/14765
+ * c-parse.in (compstmt_primary_start): Set last_expr_type to
+ NULL_TREE.
+
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15815
+ * doc/extend.texi: Deprecate #pragma interface and #pragma
+ implementation.
+
+2004-06-07 Alexandre Oliva <aoliva@redhat.com>
+
+ PR middle-end/15666
+ * c-decl.c (finish_decl): Use change_decl_assembler_name for the
+ builtin decl as well.
+
+2004-06-07 Roger Sayle <roger@eyesopen.com>
+
+ PR c/14649
+ * c-typeck.c (require_constant_value, require_constant_elements):
+ Move declarations to the top of the file.
+ (build_function_call): If we require a constant value, fold with
+ fold_initializer. If the result is a constant, and the function
+ wasn't called using __builtin_foo, issue a pedantic warning.
+ (build_unary_op): If we require a constant value, fold tree with
+ fold_initializer.
+ (build_binary_op): Use require_constant_value to determine whether
+ to call fold or fold_initializer.
+
+2004-06-07 Richard Henderson <rth@redhat.com>
+
+ * gimple-low.c (struct lower_data): Add the_return_label and
+ one_return_stmt.
+ (lower_function_body): Initialize and use them.
+ (lower_return_expr): New.
+ (lower_stmt): Call it.
+ * gimplify.c (gimplify_return_expr): Force the argument to be either
+ null or a result_decl.
+ * tree-gimple.c: Update gimple grammer to match.
+ * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Deny
+ coalescing of result_decls.
+
+2004-06-07 Richard Henderson <rth@redhat.com>
+
+ PR rtl-opt/15193
+ * expmed.c (extract_bit_field): Fix vector_extract return.
+
+ * config/i386/i386.md (negv4sf2): New pattern.
+
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15337
+ * c-common.c (c_sizeof_or_alignof_type): Use more detailed error
+ message.
+
+2004-06-06 Paolo Bonzini <bonzini@gnu.org>
+
+ * config.in: Regenerate.
+
+2004-06-06 Steven Bosscher <stevenb@suse.de>
+
+ * tree-cfg.c (tree_verify_flow_info): Make sure that labels in
+ SWITCH_LABELS are always sorted.
+
+2004-06-06 Steven Bosscher <stevenb@suse.de>
+
+ * hooks.c (hook_int_void_1): New generic hook.
+ * hooks.h (hook_int_void_1): Add prototype.
+ * config/c4x/c4x.c (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE):
+ Define to hook_int_void_1.
+ * config/c4x/c4x.md: Replace dummies for the old pipeline model
+ with dummies for the new one.
+
+2004-06-06 Roger Sayle <roger@eyesopen.com>
+
+ * tree.h (lvalue_or_else): Delete function prototype.
+ * c-typeck.c (lvalue_or_else): Make static. Add static prototype.
+
+2004-06-06 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR target/14542
+ * config/m68hc11/m68hc11.md (move peephole2): Emit a use note to avoid
+ a live change of a register after peephole replacement.
+
+2004-06-06 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/13519
+ * c-typeck.c (composite_type, common_pointer_type): New functions.
+ (common_type): Split parts into composite_type and
+ common_pointer_type. Ensure that arithmetic operations return
+ unqualified types without attributes. Don't make composite type
+ of signed enum and compatible integer be unsigned.
+ (build_conditional_expr, build_binary_op): Use
+ common_pointer_type.
+ * c-decl.c (merge_decls): Use composite_type.
+ * c-tree.h (composite_type): Declare.
+
+2004-06-06 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR target/14457
+ * config/m68hc11/m68hc11.c (splitable_operand): New predicate.
+ * config/m68hc11/m68hc11-protos.h (splitable_operand): Declare.
+ * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register it.
+ (inhibit_libc): Must define.
+ * config/m68hc11/m68hc11.md ("movhi_const0"): Use splitable_operand.
+ ("*andhi3_gen", "iorhi3", "*iorhi3_gen"): Likewise.
+ ("xorhi3"): Likewise.
+
+2004-06-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * cgraphunit.c (cgraph_decide_inlining): Adjust dump lines in
+ always_inline pass.
+
+2004-06-05 David S. Miller <davem@nuts.davemloft.net>
+
+ * config/sparc/linux.h (TARGET_C99_FUNCTIONS): Set.
+ * config/sparc/linux64.h (TARGET_C99_FUNCTIONS): Likewise.
+
+2004-06-05 Bernardo Innocenti <bernie@develer.com>
+
+ * regclass.c (init_reg_sets): Check for missing registers in target
+ initializer macros FIXED_REGISTERS and CALL_USED_REGISTERS.
+
+2004-06-05 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (MKDEPS_H): New shorthand.
+ (c-opts.o): Update dependencies.
+ * c-opts.c: Include mkdeps.h.
+ (handle_deferred_opts): Use cpp_get_deps and deps_add_target,
+ not cpp_add_dependency_target.
+
+2004-06-05 Steven Bosscher <stevenb@suse.de>
+
+ * config/v850/v850.c (v850_use_dfa_pipeline_interface): New.
+ * config/v850/v850.md: Convert to DFA scheduler description.
+
+2004-06-05 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15478
+ * doc/install.texi: Document GMP as prerequisite. Document
+ --with-gmp and --with-gmp-dir configure options.
+ * fortran/gfortran.texi: Remove section "Compiling and testing",
+ remove TOC reference to it.
+
+2004-06-05 Graham Stott <graham.stott@btinternet.com>
+
+ * combine.c(simplify_shift_const): Check shift amount is a
+ CONST_INT.
+
+2004-06-05 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * toplev.c (init_asm_output): Add explicit 'b' to mode when
+ opening asm_out_file.
+ * c-pch.c (c_common_write_pch): Remove unnecessary fflush before
+ reading asm_out_file. Replace fflush after reading asm_out_file
+ with fseek.
+ * hosthooks-def.h (HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY): Define
+ default and add to HOST_HOOKS_INITIALIZER.
+ * hosthooks.h (gt_pch_alloc_granularity): Declare hook function.
+ * ggc-common.c (default_gt_pch_alloc_granularity): New function.
+ (gt_pch_save): Use host_hooks.gt_pch_alloc_granularity
+ to set mmi.offset padding.
+ * config.gcc (i[34567]86-*-mingw32*): Set target_gtfiles to
+ $(srcdir)/config/i386/winnt.c.
+ (i[34567]86-*-pe | i[34567]86-*-cygwin*): Likewise.
+ (i[34567]86-*-uwin*): Likewise.
+ *i[34567]86-*-interix3*): Likewise.
+ * config.host (i[34567]86-*-mingw32*): Set out_host_hook_obj.
+ * config/i386/host-mingw32.c: New file.
+ * config/i386/x-mingw32: Add rule for host-mingw32.o.
+ * config/i386/winnt.c: (struct extern_list) Tag as GTY.
+ (extern_head): Likewise.
+ (struct export_list) Likewise.
+ (export_head): Likewise.
+ (i386_pe_record_external_function): Use ggc_alloc.
+ (i386_pe_record_exported_symbol): Likewise.
+ Include "gt-winnt.h" at end.
+ * doc/hostconfig.texi: Document
+ HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY.
+
+2004-06-04 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h: Remove comments copied over from tm.texi.
+ Rename 68000 and 68k to m68k for consistency in comments. Remove
+ trailing whitespace before EOLs and before TABs.
+ (MAX_CODE_ALIGN): Remove unused macro.
+ (CALL_USED_REGISTERS): Reformat and add comments.
+
+2004-06-04 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFLIB_SPEC): Remove library references, to require users
+ to enumerate -lmudflap* and dependencies when linking.
+
+2004-06-04 Paolo Bonzini <bonzini@gnu.org>
+
+ PR target/15822
+ * dojump.c (do_jump): Fix uninitialized variable tcode1.
+
+2004-06-04 Jerry Quinn <jlquinn@optonline.net>
+
+ * Makefile.in (insn-conditions.o): Back out removal of reload.h.
+ * genconditions.c (write_header): Back out removal of reload.h.
+
+2004-06-04 Jan Hubicka <jh@suse.cz>
+
+ Re-apply hopefully fixed patch:
+ * i386.md (UNSPECV_EH_RETURN): Kill.
+ (eh_return): Use jump_insn.
+ (eh_return_si, eh_return_di): Change pattern to jump instruction.
+
+2004-06-04 Jeff Law <law@redhat.com>
+
+ * cfgrtl.c (try_redirect_by_replacing_jump): Fix return value.
+
+2004-06-04 Steven Bosscher <stevenb@suse.de>
+
+ * except.c (for_each_eh_region): New function.
+ * except.h (for_each_eh_region): Add a prototype for it.
+ * tree-cfg.c (update_eh_labels): New function, callback for
+ for_each_eh_region.
+ (label_for_bb): Make global static, unfortunately.
+ (cleanup_dead_labels): Also update label references for
+ exception regions.
+
+2004-06-03 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (struct irix_section_align_entry): Fix
+ GTY marker.
+
+2004-06-03 Geoffrey Keating <geoffk@apple.com>
+
+ * toplev.c (check_global_declarations): Don't ask for
+ DECL_ASSEMBLER_NAME unless the function really is declared
+ static and not defined.
+
+2004-06-03 Matt Austern <austern@apple.com>
+
+ PR c++/15428
+ * default.h (TARGET_WEAK_NOT_IN_ARCHIVE_TOC): New name
+ for TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY, with reversed sense.
+ * config/darwin.h (TARGET_WEAK_NOT_IN_ARCHIVE_TOC): Likewise.
+ * doc/tm.texi (TARGET_WEAK_NOT_IN_ARCHIVE_TOC): Rewrite
+ documentation to reflect the new macro name and to clarify its
+ meaning.
+
+2004-06-03 Steven Bosscher <stevenb@suse.de>
+
+ * rtl.def (VAR_LOCATION): Make RTX_EXTRA.
+
+2004-06-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/darwin.c (machopic_indirect_data_reference): Copy
+ the SYMBOL_REF_DECL from the original RTX for the new
+ non-lazy pointer RTX.
+
+2004-06-03 Mark G. Adams <mark.g.adams@sympatico.ca>
+
+ * tree.h: Remove include of version.h
+ * c-cppbuiltin.c: Include version.h
+ * diagnostic.c: Include version.h
+ * dwarf2out.c: Include version.h
+ * toplev.c: Include version.h
+ * vmsdbgout.c: Include version.h
+ * Makefile.in: Remove dependency on version.h from TREE_H, and
+ add dependencies to required .o targets
+
+2004-06-03 Jerry Quinn <jlquinn@optonline.net>
+
+ * Makefile.in (RA_H, RESOURCE_H, SCHED_INT_H, CFGLAYOUT_H,
+ CFGLOOP_H, DF_H, DDG_H, TREE_SSA_LIVE_H): New.
+ (TARGET_H): Add insn-modes.h.
+ (tree-ssa.o, tree-cfg.o, tree-ssa-loop.o, toplev.o, passes.o,
+ loop.o, loop-doloop.o, unroll.o, cfgloop.o, cfgloopanal.o,
+ loop-iv.o, cfgloopmanip.o, loop-init.o, loop-unswitch.o,
+ loop-unroll.o, ddg.o, modulo-sched.o, predict.o,
+ cfglayout.o, ifcvt.o): Replace cfgloop.h with CFGLOOP_H.
+ (toplev.o, passes.o, cfghooks.o, cfgloopmanip.o, loop-init.o,
+ loop-unswitch.o, loop-unroll.o, ddg.o, modulo-sched.o,
+ bb-reorder.o, tracer.o, cfglayout.o): Replace cfglayout.h with
+ CFGLAYOUT_H.
+ (ra.o, ra-build.o, ra-colorize.o, ra-debug.o, ra-rewrite.o):
+ Replace ra.h with RA_H.
+ (resource.o, regrename.o, insn-conditions.o, insn-emit.o,
+ insn-recog.o): Replace resource.h with RESOURCE_H.
+ (ddg.o, modulo-sched.o, haifa-sched.o, sched-deps.o, sched-rgn.o,
+ sched-ebb.o, sched-vis.o, out_object_file): Replace sched-int.h
+ with SCHED_INT_H.
+ (web.o, lcm.o, df.o, ra.o, ra-build.o, ra-colorize.o, ra-debug.o,
+ ra-rewrite.o): Replace df.h with DF_H.
+ (ddg.o, modulo-sched.o): Replace ddf.h with DDG_H.
+ (tree-outof-ssa.o, tree-ssa-live.o, tree-ssa-copyrename.o):
+ Replace tree-ssa-live.h with TREE_SSA_LIVE_H.
+ (insn-conditions.o): Remove unused reload.h.
+ * cfglayout.h: Add include guard. Include basic-block.h.
+ * cfgloop.h: Add include guard. Include basic-block.h, rtl.h.
+ * ddg.h: Include sbitmap.h, basic-block.h, df.h.
+ * df.h: Add include guard. Include bitmap.h, sbitmap.h,
+ basic-block.h.
+ * genconditions.c: Remove reload.h.
+ * ra.h: Add include guard. Include bitmap.h, sbitmap.h,
+ hard-reg-set.h, insn-modes.h.
+ * resource.h: Add include guard. Include hard-reg-set.h.
+ * sched-int.h: Add include guard. Include insn-attr.h,
+ basic-block.h, rtl.h.
+ * target.h: Add include guard. Include insn-modes.h.
+ * tree-ssa-live.h: Include partition.h.
+
+2004-06-03 Daniel Berlin <dberlin@dberlin.org>
+ Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * tree-ssa-ccp.c (varying_ssa_edges): New worklist.
+ (add_var_to_ssa_edges_worklist): Add value argument.
+ Update callers.
+ Use new worklist.
+ (process_ssa_edge_worklist): New function.
+ (tree_ssa_ccp): Move worklist processing core to
+ process_ssa_edge_worklist, and just call that for the two worklists.
+
+2004-06-03 Steven Bosscher <stevenb@suse.de>
+
+ * basic-block.c (tail_recursion_label_list): Don't declare.
+ (CLEANUP_PRE_SIBCALL): Remove. Renumber the other CLEANUP_*
+ accordingly.
+ * cfgbuild.c (find_label_refs): Remove.
+ (find_basic_blocks_1): Don't handle CALL_PLACEHOLDER insns.
+ * cfgcleanup.c (tail_recursion_label_p): Remove.
+ (merge_blocks_move): Do not check for tail recursion.
+ (try_optimize_cfg): Likewise.
+ (cleanup_cfg): Never handle CLEANUP_PRE_SIBCALL.
+ * cfgrtl.c (tail_recursion_label_list): Remove.
+ * except.c (remove_unreachable_regions): Don't handle
+ CALL_PLACEHOLDER insns.
+ (convert_from_eh_region_ranges_1, can_throw_internal,
+ can_throw_external): Likewise.
+ * function.c (free_after_compilation): Don't clear
+ x_tail_recursion_label.
+ (fixup_var_refs_insns): Don't handle CALL_PLACEHOLDER insns.
+ (identify_blocks_1): Don't recurse for CALL_PLACEHOLDER insns.
+ (reorder_blocks_1): Likewise.
+ * function.h (struct function): Remove x_tail_recursion_label
+ member. Don't define tail_recursion_label.
+ * jump.c (mark_all_labels): Don't handle CALL_PLACEHOLDER insns.
+ * print-rtl.c (print_rtx): Likewise.
+ * rtl.def (CALL_PLACEHOLDER): Remove.
+ * rtl.h (sibcall_use_t): Remove enum.
+ (optimize_sibling_and_tail_recursive_calls,
+ replace_call_placeholder): Remove function prototypes.
+ * stmt.c (tail_recursion_args): Remove.
+ (optimize_tail_recursion): Remove.
+ (expand_return): Don't check for possible tail recursion.
+ * tree.h (optimize_tail_recursion): Remove prototype.
+
+2004-06-02 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (tree_find_edge_insert_loc): Allow inserting before
+ return_stmt.
+
+2004-06-02 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in (TAGS): Don't mess with c-parse.[ch].
+ Do include c-parse.in.
+
+2004-06-02 Eric Christopher <echristo@redhat.com>
+
+ * c-typeck.c (common_type): Don't lose type qualifiers
+ when creating new variants.
+
+2004-06-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR tree-optimization/14042
+ PR tree-optimization/14729
+ PR tree-optimization/14736
+ * tree-ssa.c (tree_ssa_useless_type_conversion_1):
+ Check the type which the pointer points to
+ instead of the pointer types.
+
+2004-06-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR tree-optimization/15738.
+ * builtins.c (fold_builtin_strchr): Transform
+ strrchr (s, '\0') to strchr (s, '\0').
+
+2004-06-02 Steven Bosscher <stevenb@suse.de>
+
+ * i386.c (ix86_adjust_cost): Don't increase the cost for
+ load+operation for PROCESSOR_PENTIUMPRO, it is already
+ modelled in the DFA description
+
+2004-06-01 Jerry Quinn <jlquinn@optonline.net>
+
+ * Makefile.in (EXPR_H): Add insn-config.h, function.h,
+ $(RTL_H), flags.h, $(TREE_H), $(MACHMODE_H), $(EXPR_H).
+ (ALIAS_H, EMIT_RTL_H): New.
+ (cselib.o): Replace EXPR_H with EMIT_RTL_H.
+ (cfgcleanup.o): Add EMIT_RTL_H.
+ (alias.o): Replace EXPR_H with EMIT_RTL_H and ALIAS_H.
+ * alias.c: Replace expr.h with emit-rtl.h and alias.h.
+ * attribs.c, c-lex.c, c-obj-common.c, c-semantics.c: Remove expr.h.
+ * cfgcleanup.c, cselib.c: Replace expr.h with emit-rtl.h.
+ * expr.h: Add include guard. Include function.h, rtl.h, flags.h,
+ tree.h, machmode.h, insn-config.h, alias.h, emit-rtl.h.
+ (get_varargs_alias_set, get_frame_alias_set, record_base_value,
+ record_alias_subset, new_alias_set, can_address_p): Move to alias.h.
+ (set_mem_alias_set, set_mem_align, set_mem_expr, set_mem_offset,
+ set_mem_size): Move to emit-rtl.h.
+ * emit-rtl.h: New.
+ * alias.h: New.
+
+2004-06-01 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * function.c (walk_fixup_memory_subreg): New parameter 'var'.
+ Call fixup_memory_subreg only if the MEM is equal to 'var'.
+ Adjust recursive calls to self.
+ (fixup_var_refs_insn): Pass 'var' to walk_fixup_memory_subreg.
+
+2004-06-01 Richard Henderson <rth@redhat.com>
+ Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-parse.in (OFFSETOF, offsetof_member_designator): New.
+ (primary): Handle offsetof. Add error productions for faux functions.
+ Move component_ref objc checking to build_component_ref.
+ (reswords): Add offsetof.
+ (rid_to_yy): Add offsetof.
+ * c-tree.h (build_offsetof): Declare.
+ * c-common.h (objc_is_public): Declare.
+ * c-typeck.c (build_component_ref): Check objc_is_public.
+ (build_offsetof): New.
+ * stub-objc.c (objc_is_public): New.
+ * objc/objc-act.c, objc/objc-act.h (objc_is_public): Rename
+ from is_public.
+ * ginclude/stddef.h (offsetof): Use __builtin_offsetof.
+ * doc/extend.texi (Offsetof): Move from C++ section to C section
+ and rewrite for __builtin_offsetof.
+
+2004-06-01 Peter Barada <peter@the-baradas.com>
+ Peter Jakubek <peter@laseranimation.com>
+
+ * config/m68k/m68k.c(m68k_output_mi_thunk): For ColdFire, use %d0 as
+ a scratch to perform an add to memory.
+
+2004-06-01 Bernardo Innocenti <bernie@develer.com>
+
+ PR target/14018
+ * config/m68k/m68k.c (m68k_align_loops_string, m68k_align_jumps_string,
+ m68k_align_funcs_string, m68k_align_loops, m68k_align_jumps,
+ m68k_align_funcs): Remove.
+ (override_options): Remove code to handle -malign-* options.
+ * config/m68k/m68k.h (TARGET_OPTIONS): Remove -malign-* options.
+ (FUNCTION_BOUNDARY, LOOP_ALIGN, LOOP_ALIGN_AFTER_BARRIER): Remove.
+ (m68k_align_loops_string, m68k_align_jumps_string,
+ m68k_align_funcs_string, m68k_align_loops, m68k_align_jumps,
+ m68k_align_funcs): Remove definitions.
+
+2004-06-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ PR target/15626
+ * doc/install.texi (sparc-sun-solaris2*): Document messages issued
+ by the Sun linker in conjunction with the Sun assembler.
+ (sparc-sun-solaris2.7): Update revision info for Sun patch 106950.
+
+2004-06-01 Jeff Law <law@redhat.com>
+
+ * stmt.c (expand_decl): Be more selective about calling
+ mark_reg_pointer.
+
+2004-06-01 Nicola Pero <nicola@brainstorm.co.uk>
+
+ PR objc/7993
+ * objc-act.c (is_private): Do not emit the 'instance variable %s
+ is declared private' error.
+ (is_public): Emit the error after calling is_private.
+ (lookup_objc_ivar): If the instance variable is private, return 0
+ - the instance variable is invisible here.
+
+2004-06-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/invoke.texi (-static-libgcc): Explicitly mention
+ non-GNU linkers.
+
+2004-06-01 Bernardo Innocenti <bernie@develer.com>
+
+ PR target/12968
+ * doc/invoke.texi: Document stack alignment side-effect of -mshort.
+
+2004-05-31 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/15749
+ * c-decl.c (grokdeclarator, finish_struct): Don't pedwarn for
+ misuses of structures with flexible array members if
+ in_system_header.
+
+2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/15693
+ * config/sparc/sparc.c (compare_operand): New predicate.
+ * config/sparc/sparc.h (PREDICATE_CODES): Add it.
+ * config/sparc/sparc.md (cmpsi expander): Use it. If the first
+ operand is a ZERO_EXTRACT and the second operand is not zero,
+ force the former to a register.
+ (cmpdi expander): Likewise.
+
+2004-05-31 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype-lex.l: Catch stray GTY markers in the files gengtype
+ looks at.
+ * alias.c (alias_invariant_size): Make alias_invariant_size
+ static, fix GTY marker.
+
+2004-05-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR tree-optimization/15743.
+ * builtins.c (fold_builtin_1): Fold index() and rindex().
+
+2004-05-31 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/15069
+ * fold-const.c (fold_single_bit_test): Only perform "(X & C) != 0"
+ into "X < 0" (where C is the signbit) if X's type is a full mode.
+
+2004-05-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md: Disable the peephole2 patterns that generate indexed
+ floating-point stores when indexing is disabled.
+
+2004-05-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.c (pp_c_left_bracket): Make a function.
+ (pp_c_right_bracket): Likewise.
+ (pp_c_star): Likewise.
+ (pp_c_ampersand): Define.
+ * c-pretty-print.h (pp_c_left_bracket): Declare.
+ (pp_c_right_bracket): Likewise.
+ (pp_c_star): Likewise.
+ (pp_c_ampersand): Likewise.
+
+2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sol2.h (__enable_execute_stack): ANSIfy function
+ definition.
+
+2004-05-31 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * c-incpath.c (add_path): Canonicalize paths to use '/' if
+ HAVE_DOS_BASED_FILESYSTEM.
+
+2004-05-31 Steven Bosscher <stevenb@suse.de>
+
+ * tree-ssa-dom.c (record_equivalences_from_incoming_edge):
+ Only look at case labels if the immediate dominator is also
+ the only predecessor. Don't look for more case labels if the
+ first seen is a case range.
+
+2004-05-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c: Add a prototype for fold_builtin_strchr().
+
+2004-05-31 Paolo Bonzini <bonzini@gnu.org>
+
+ Revert this patch:
+ 2004-05-27 Paolo Bonzini <bonzini@gnu.org>
+
+ * combine.c (gen_binary): Remove.
+ (known_cond, simplify_shift_const
+ find_split_point, combine_simplify_rtx,
+ simplify_if_then_else, simplify_set,
+ simplify_logical, expand_field_assignment,
+ extract_left_shift, force_to_mode,
+ if_then_else_cond, apply_distributive_law,
+ simplify_and_const_int, simplify_shift_const,
+ gen_lowpart_for_combine, simplify_comparison,
+ reversed_comparison): Replace with
+ simplify_gen_binary, simplify_gen_relational or
+ distribute_and_simplify_rtx.
+ (distribute_and_simplify_rtx): New function.
+
+2004-05-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (emit_move_sequence): Fix loading of non 14-bit CONST operands
+ when generating PIC code.
+
+2004-05-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-decl.c (c_expand_body_1): Remove and fold back into ...
+ (c_expand_body): here.
+ (c_expand_decl): Move to ...
+ * c-common.c (c_expand_decl): Here and remove check for nested
+ functions.
+ * c-common.h (c_expand_decl): Add prototype.
+ * c-tree.h (c_expand_decl): Remove.
+
+2004-05-30 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (combine_comparisons, optimize_bit_field_compare,
+ range_binop, fold_truthop, fold_binary_op_with_conditional_arg,
+ fold_mathfn_compare, fold_inf_compare, fold,
+ fold_relational_hi_lo, nondestructive_fold_binary_to_constant):
+ Use constant_boolean_node where appropriate. Don't bother using
+ fold_convert on the second argument to omit_one_operand.
+
+2004-05-30 Roger Sayle <roger@eyesopen.com>
+
+ * doc/c-tree.texi (Expressions): Document FLOOR_DIV_EXPR,
+ CEIL_DIV_EXPR, ROUND_DIV_EXPR, FLOOR_MOD_EXPR, CEIL_MOD_EXPR,
+ ROUND_MOD_EXPR, EXACT_DIV_EXPR. Improve documentation of
+ TRUNC_DIV_EXPR, TRUNC_MOD_EXPR and comparison operations.
+ Add missing (but documented) tree nodes to the index.
+
+2004-05-30 Steven Bosscher <stevenb@suse.de>
+
+ PR tree-optimization/14819
+ * builtins.c (fold_builtin_strchr): New.
+ (fold_builtin_1): Handle BUILT_IN_STRCHR and BUILT_IN_STRRCHR
+ with fold_builtin_strchr().
+
+2004-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bb-reorder.c, builtins.c, c-common.c, c-gimplify.c,
+ c-incpath.c, cgraphunit.c, ddg.c, defaults.h, dwarf2out.c,
+ expmed.c, flags.h, gcc.c, gensupport.c, gimplify.c, global.c,
+ passes.c, reg-stack.c, target.h, toplev.c, tree-alias-ander.c,
+ tree-alias-common.c, tree-cfg.c, tree-complex.c, tree-dfa.c,
+ tree-eh.c, tree-mudflap.c, tree-mudflap.h, tree-outof-ssa.c,
+ tree-phinodes.c, tree-pretty-print.c, tree-ssa-alias.c,
+ tree-ssa-ccp.c, tree-ssa-live.c, tree-ssa-live.h,
+ tree-ssa-pre.c, tree.h, value-prof.h, varasm.c: Fix comment
+ formatting.
+
+2004-05-30 Steven Bosscher <stevenb@suse.de>
+
+ * gimplify.c (sort_case_labels): New. Split out from...
+ (gimplify_switch_expr): ...here. Use it.
+ * tree-eh.c (lower_try_finally_switch): Sort the labels of
+ the SWITCH_EXPR created here before leaving the function.
+ * tree.c (sort_case_labels): Add prototype.
+
+2004-05-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * fold-const.c (fold) [case TRUTH_NOT_EXPR]: Make sure the type is
+ of BOOLEAN_TYPE.
+
+2004-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.c, calls.c, cfgcleanup.c, cgraph.c, cgraphunit.c,
+ ddg.c, ddg.h, df.c, df.h, except.c, expr.c, flags.h,
+ fold-const.c, gcc.c, gimplify.c, haifa-sched.c,
+ modulo-sched.c, tree-inline.c, tree-into-ssa.c, tree-nested.c,
+ tree-nrv.c, tree-ssa-ccp.c, tree-ssa-dom.c, tree-ssa-live.c,
+ tree-ssa-loop.c, tree-ssa-pre.c, tree-tailcall.c, tree.h: Fix
+ comment typos. Follow spelling conventions.
+
+2004-05-29 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype-yacc.y: Add NESTED_PTR token.
+ (option): Record `nested_ptr' option.
+ * gengtype-lex.l: Handle `nested_ptr' keyword.
+ * gengtype.c (walk_type): Process `nested_ptr' option.
+ * gengtype.h (struct nested_ptr_data): New.
+ * doc/gty.texi (GTY Options): Document `nested_ptr' option.
+ * stringpool.c (struct string_pool_data): Make 'entries' point to
+ ht_identifier instead of tree.
+ (gt_pch_save_stringpool): Don't adjust pointers.
+ (gt_pch_restore_stringpool): Call ht_load.
+
+2004-05-29 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_expr): Don't build a statement list
+ if no gimplification was necessary.
+
+2004-05-29 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * pretty-print.c (pp_base_format_text): Support %< instead of %`
+ and %> as well as %'.
+ * c-format.c: Use %< and %>.
+ (gcc_diag_char_table, gcc_cdiag_char_table,
+ gcc_cxxdiag_char_table): Update.
+
+2004-05-29 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (common_type): Correct comment.
+
+2004-05-29 Peter Barada <peter@the-baradas.com>
+
+ * config/m68k/m68k.c (CONST_METHOD): Add MVZ, MVS.
+ * config/m68k/m68k.c (const_method): Likewise.
+ * config/m68k/m68k.c (const_int_cost): Likewise.
+ * config/m68k/m68k.c (const_int_cost): Likewise.
+ * config/m68k/m68k.c (output_move_const_into_data_reg): Likewise.
+
+2004-05-29 Peter Barada <peter@the-baradas.com>
+
+ * config/m68k/m68k.h (EXTRA_CONSTRAINT): add 'U' for register offset
+ addressing.
+ * config/m68k/m68k.md: Add 'U,U' alternative to ColdFire variants of
+ movsi,movhi,movqi insn patterns.
+
+2004-05-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-semantics.c (emit_local_var): Remove code for DECL_INITIAL.
+
+ PR target/15720
+ * config/darwin.c (machopic_indirect_call_target): Copy
+ the SYMBOL_REF_DECL from the original RTX for the new
+ stub RTX.
+
+2004-05-28 DJ Delorie <dj@redhat.com>
+
+ * stor-layout.c (place_field): Revert erroneous commit.
+
+2004-05-28 Ziemowit Laski <zlaski@apple.com>
+
+ * config/rs6000/altivec.h (vec_ctf, vec_vcfsx, vec_vcfux, vec_cts,
+ vec_ctu, vec_dss, vec_dst, vec_dstst, vec_dststt, vec_dstt, vec_ld,
+ vec_ldl, vec_lvsl, vec_lvsr, vec_sld, vec_splat, vec_vspltw,
+ vec_vsplth, vec_vspltb, vec_splat_s8, vec_splat_s16, vec_splat_s32,
+ vec_splat_u8, vec_splat_u16, vec_splat_u32, vec_st, vec_stl,
+ vec_ste): Remove type checks for integral parameters and literals
+ from '..._args_eq' macros.
+
+2004-05-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-common.c (fname_as_string): Fix xcalloc to xmalloc.
+
+2004-05-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/g++.dg/charset/function.cc: New.
+
+ * testsuite/gcc.dg/charset/function.c: New.
+
+ * c-decl.c (c_make_fname_decl): Free return value from
+ fname_as_string.
+
+ * cp/decl.c (cp_make_fname_decl): Free return value from
+ fname_as_string.
+
+ * c-common.c (fname_as_string): Translate if necessary.
+
+2004-05-28 Geoffrey Keating <geoffk@apple.com>
+
+ * stringpool.c: Add comments to PCH saving/restoring routines.
+
+2004-05-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-common.c (c_estimate_num_insns_1): Kill.
+ (c_estimate_num_insns): Kill.
+ * c-common.h (c_estimate_num_insns): Kill.
+
+ * gthr-posix.h: Check for _POSIX_PRIORITY_SCHEDULING
+ when checking for _POSIX_THREAD_PRIORITY_SCHEDULING.
+ Remove comment about not checking for
+ _POSIX_PRIORITY_SCHEDULING.
+ * gthr-posix.c: Likewise.
+
+2004-05-28 Paolo Bonzini <bonzini@gnu.org>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR rtl-optimization/15649
+ Add LTGT_EXPR and improve pretty-printing of unordered
+ comparisons.
+ * c-common.c (c_common_truthvalue_conversion):
+ Handle LTGT_EXPR.
+ * c-typeck.c (build_binary_op): Likewise.
+ * dojump.c (do_jump): Likewise.
+ * expr.c (expand_expr_real_1, do_store_flag): Likewise.
+ * predict.c (tree_predict_by_opcode): Likewise.
+ * real.c (real_compare): Likewise.
+ * tree-cfg.c (verify_expr): Likewise.
+ * tree-inline.c (estimate_num_insns_1): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ Handle ORDERED_EXPR, UNORDERED_EXPR.
+ (op_symbol): Print unordered comparisons differently
+ than ordered ones.
+ * tree.def (LTGT_EXPR): New '<' tree code.
+ * doc/c-tree.texi (Expressions): Document floating-point
+ comparison nodes.
+
+ Fold comparisons between floating point values.
+ * fold-const.c (enum comparison_code): New, from
+ #define'd constants. Define compcodes for unordered
+ comparisons and for invalid transformations.
+ (invert_tree_comparison): Add "honor_nans" parameter.
+ (fold_truthop): Revamp to work on floating-point types too.
+ (comparison_to_compcode): Support unordered comparisons.
+ Use new enum comparison_code.
+ (compcode_to_comparison): Likewise.
+ (combine_compcodes): New function.
+ (invert_truthvalue): Let invert_tree_comparison decide
+ whether it is valid to fold the comparison. Fold ORDERED
+ and UNORDERED even if flag_unsafe_math_optimizations is off,
+ and the remaining even if flag_unsafe_math_optimizations
+ is off but we are under -fno-trapping-math.
+ (fold_relational_const): Integer modes do not honor NaNs.
+
+2004-05-28 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_output_epilogue): Remove redundant code.
+
+2004-05-28 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (thumb_force_lr_save): New function.
+ (arm_get_frame_offsets, thumb_unexpanded_epilogue,
+ thumb_output_function_prologue): Use it.
+ (thumb_expand_prologue): Set lr_save_eliminated.
+
+2004-05-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (extendsidi2): Tie the source and destination
+ of the register alternative. Split it into nothing.
+
+2004-05-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * rtl.h (skip_consecutive_labels): Declare.
+ * emit-rtl.c (skip_consecutive_labels): New function.
+ * reorg.c (relax_delay_slots, dbr_schedule): Use it.
+ * jump.c (follow_jumps): Say what null return values mean.
+
+2004-05-28 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/13250
+ * config/sh/sh.md (rotlsi3): Use emit_move_insn.
+
+2004-05-27 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/t-linux (SHLIB_MAPFILES): Use sh specific
+ libgcc-std.ver.
+ * config/sh/libgcc-std.ver: New file.
+
+2004-05-27 Bryce McKinlay <mckinlay@redhat.com>
+
+ * except.c: Revert change of 2004-05-26.
+ * config/i386/i386.md: Revert change of 2004-05-27.
+
+2004-05-27 Bryce McKinlay <mckinlay@redhat.com>
+
+ * configure.ac: Remove --enable-tree-browser option.
+ Define TREEBROWSER when ac_tree_checking is defined.
+ * configure: Rebuilt.
+
+2004-05-27 Olivier Hainque <hainque@act-europe.fr>
+
+ * expr.c (store_constructor): Restore sanity check on
+ the size of the type before clearing.
+
+2004-05-27 Jan Hubicka <jh@suse.cz>
+
+ * cfgbuild.c (control_flow_insn_p): Notice noreturn call
+
+2004-05-27 Paolo Bonzini <bonzini@gnu.org>
+
+ * combine.c (gen_binary): Remove.
+ (known_cond, simplify_shift_const
+ find_split_point, combine_simplify_rtx,
+ simplify_if_then_else, simplify_set,
+ simplify_logical, expand_field_assignment,
+ extract_left_shift, force_to_mode,
+ if_then_else_cond, apply_distributive_law,
+ simplify_and_const_int, simplify_shift_const,
+ gen_lowpart_for_combine, simplify_comparison,
+ reversed_comparison): Replace with
+ simplify_gen_binary, simplify_gen_relational or
+ distribute_and_simplify_rtx.
+ (distribute_and_simplify_rtx): New function.
+ * simplify-rtx.c (simplify_binary_operation):
+ Use nonzero_bits to simplify ANDs where we are
+ turning off bits already known to be off in OP0.
+
+2004-05-27 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14478
+ * config/rs6000/rs6000.c (reg_or_neg_short_operand): Don't allow zero.
+
+2004-05-27 Josef Zlomek <zlomekj@suse.cz>
+
+ PR middle-end/14084
+ * emit-rtl.c (gen_rtx_REG_offset): Adjust the offset according
+ to size of decl.
+
+2004-05-26 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/14924
+ * config/rs6000/rs6000.c (spe_expand_stv_builtin): New.
+
+2004-05-26 Roger Sayle <roger@eyesopen.com>
+
+ * tree.h: Fix comment typo.
+
+2004-05-27 Steven Bosscher <stevenb@suse.de>
+
+ * gimplify.c (compare_case_labels): New function.
+ (gimplify_switch_expr): Sort case labels, and make sure the
+ last label in the label vector is the default case.
+ * tree-cfg.c (group_case_labels): New function.
+ (build_tree_cfg): Cleanup redundant labels and group case labels
+ before creating edges.
+ (cleanup_dead_labels): Handle GOTO_EXPRs.
+ (find_case_label_for_value): Use a binary search to find the
+ case label for the given value.
+ * tree-gimple.c: Mention that labels are sorted, and that the
+ last label must be the default.
+
+2004-05-27 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_optimize_cfg): Do not merge across jumptables.
+
+2004-05-27 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (UNSPECV_EH_RETURN): Kill.
+ (eh_return): Use jump_insn.
+ (eh_return_si, eh_return_di): Change pattern to jump instruction.
+
+2004-05-26 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_forward_edges): Do not check loop structure when
+ not loop optimizing.
+
+2004-05-26 Jan Hubicka <jh@suse.cz>
+
+ * except.c (can_throw_internal): Notice RESX instructions.
+
+2004-05-26 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * varasm.c (output_constant) <INTEGER_TYPE>: Pass the minimum
+ of the two sizes to assemble_integer.
+
+2004-05-25 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (thumb_exit, thumb_unexpanded_epilogue): Remove
+ pointless #ifdef.
+
+2004-04-25 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.in (top_builddir): Define to .
+
+2004-05-25 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.ac (gcc_cv_ld): Prefer in-tree ld over whatever the
+ top-level detects, except when in-tree ld is being cross-built.
+ (gcc_cv_as): Likewise for as. Use AS_FOR_TARGET otherwise, and
+ then AS only if target is host.
+ * configure: Rebuilt.
+
+2004-05-25 Vladimir Makarov <vmakarov@redhat.com>
+
+ * global.c (global_alloc): Call make_accurate_live_analysis.
+ (record_one_conflict): Remove dead code.
+ (mark_reg_clobber): Remove ATTRIBUTE_UNUSED for parameter data.
+ (bb_info): New structure.
+ (BB_INFO, BB_INFO_BY_INDEX): New macros.
+ (allocate_bb_info, free_bb_info, mark_reg_change,
+ calculate_local_reg_bb_info, set_up_bb_rts_numbers, rpost_cmp,
+ modify_bb_reg_pav, calculate_reg_pav,
+ make_accurate_live_analysis): New functions.
+
+2004-05-25 Devang Patel <dpatel@apple.com>
+
+ * alias.c (init_alias_analysis): Use ggc_calloc instead of
+ xrealloc.
+ (end_alias_analysis): Use ggc_free instead fo free.
+
+2004-05-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/15546
+ * config/ia64/ia64.h (ASM_OUTPUT_FDESC): Mark the DECL
+ as needed to be outputted.
+
+2004-05-25 Jan Hubicka <jh@suse.cz>
+
+ * builtins.def (__builtin_expect): Mark the function as const&nothrow.
+
+2004-05-25 Ayal Zaks <zaks@il.ibm.com>
+ Mostafa Hagog <mustafa@il.ibm.com>
+
+ * Makefile.in (modulo-sched.o, ddg.o): New.
+ * ddg.h, ddg.c, modulo-sched.c: New files.
+ * cfglayout.c (duplicate_insn_chain): Remove "static" and push
+ internals to "dupicate_insn".
+ (duplicate_insn): New function.
+ * cfglayout.h (duplicate_insn_chain, duplicate_insn): New
+ declarations.
+ * common.opt (fmodulo-sched): New flag.
+ * df.c (df_bb_regno_last_use_find, df_bb_regno_first_def_find):
+ Remove static and forward declaration.
+ (df_find_def, df_reg_used, df_bb_regno_last_def_find): New
+ functions.
+ * df.h (df_bb_regno_last_use_find, df_bb_regno_first_def_find,
+ df_bb_regno_last_def_find, df_find_def, df_reg_used): New
+ declarations.
+ * flags.h (flag_modulo_sched): New flag.
+ * opts.c (common_handle_option): Handle modulo-sched flag.
+ * params.def (max-sms-loop-number, sms-max-ii-factor,
+ sms-dfa-history, sms-loop-average-count-threshold): New
+ parameters.
+ * params.h (MAX_SMS_LOOP_NUMBER, SMS_MAX_II_FACTOR,
+ SMS_DFA_HISTORY, SMS_LOOP_AVERAGE_COUNT_THRESHOLD): New
+ parameters.
+ * passes.c ("sms", "sms-vcg"): New dumps.
+ (rest_of_handle_sched): Call sms_schedule.
+ * rtl.h (sms_schedule): New declaration.
+ * timevar.def (TV_SMS): New.
+ * toplev.c (flag_modulo_sched): Initialize.
+ (f_options): Handle -fmodulo-sched option.
+ * docs/invoke.texi: Document -fmodulo-sched & -dm options.
+ * docs/passes.texi: Document new SMS pass.
+
+2004-05-25 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.in (OBJS): Add rtlhooks.o.
+ (rtlanal.o): Depend on function.h.
+ (cse.o): Depend on rtlhooks-def.h.
+ (combine.o): Depend on rtlhooks-def.h.
+ (rtlhooks.o): New rule.
+ * combine.c: Include rtlhooks-def.h.
+ (nonzero_bits, cached_nonzero_bits, nonzero_bits1,
+ num_sign_bit_copies, cached_num_sign_bit_copies,
+ num_sign_bit_copies1): Move most of the code to rtlanal.c.
+ (reg_nonzero_bits_for_combine,
+ reg_num_sign_bit_copies_for_combine): New functions holding
+ the remnants of the above.
+ (combine_rtl_hooks): New.
+ (combine_instructions): Set rtl_hooks instead of gen_lowpart.
+ * cse.c: Include rtlhooks-def.h.
+ (cse_rtl_hooks): New.
+ (cse_main): Set rtl_hooks instead of gen_lowpart.
+ * emit-rtl.c (gen_lowpart): Remove.
+ (gen_lowpart_general): Move to rtlhooks.c.
+ * rtl.h (nonzero_bits, num_sign_bit_copies,
+ struct rtl_hooks, rtl_hooks, general_rtl_hooks): New.
+ (gen_lowpart_general): Remove.
+ (gen_lowpart): Temporarily redefine as a macro.
+ * rtlanal.c: Include function.h.
+ (nonzero_bits, cached_nonzero_bits, nonzero_bits1,
+ num_sign_bit_copies, cached_num_sign_bit_copies,
+ num_sign_bit_copies1): New, from combine.c.
+ * rtlhooks.c: New file.
+ * rtlhooks-def.h: New file.
+
+2004-05-25 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/avr/avr.h (LONG_LONG_TYPE_SIZE): Changed long long type
+ to support 32-bit -mint8 mode.
+
+ * doc/invoke.texi (-mint8): Added documentation for the -mint8
+ option in the AVR architecture.
+
+2004-05-24 Mike Stump <mrs@apple.com>
+
+ * doc/install.texi: Document that dejagnu 1.4.4 is required.
+
+2004-05-24 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * intl.h (open_quote, close_quote): New.
+ * intl.c (open_quote, close_quote): New.
+ (gcc_init_libintl): Set them.
+ * pretty-print.c: Include "intl.h".
+ (pp_base_format_text): Support 'q' format flag and %` and %'
+ formats. Use ' instead of ` in comments.
+ * c-format.c (gcc_diag_flag_specs, gcc_cxxdiag_flag_specs,
+ gcc_diag_char_table, gcc_cdiag_char_table, gcc_cxxdiag_char_table,
+ foramt_types_orig): Describe these new formats.
+ (decode_format_attr, check_function_format,
+ check_format_info_main): Use these new formats.
+ (status_warning): Use ATTRIBUTE_GCC_DIAG.
+ * toplev.c (ATTRIBUTE_GCC_DIAG): Increase required GCC version to
+ check these formats to 3.5.
+
+2004-05-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Makefile.in (CPPLIBS): Renamed to CPPLIB.
+ (BACKEND): Reflect this.
+ (LIBDEPS): Move CPPLIB before LIBIBERTY.
+ (LIBS): Likewise.
+
+2004-05-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR tree-optimization/14197
+ * builtins.c: Include "tree-gimple.h"
+ (readonly_data_expr): Use get_base_address. Make sure to call
+ decl_readonly_section only on trees it can handle.
+ * tree-gimple.c (get_base_address): Accept STRING_CST and
+ CONSTRUCTOR expressions.
+ * Makefile.in: Update dependencies.
+
+2004-05-23 Paolo Bonzini <bonzini@gnu.org>
+
+ Move libcpp to the toplevel.
+ * Makefile.in: Remove references to libcpp files,
+ use CPPLIBS instead of libcpp.a. Define SYMTAB_H
+ and change hashtable.h to that.
+ * aclocal.m4 (gcc_AC_HEADER_STDBOOL,
+ gcc_AC_HEADER_STRING, gcc_AC_C__BOOL): Remove.
+ * configure.ac (gcc_AC_C__BOOL, HAVE_UCHAR): Remove tests.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * c-ppoutput.c: Include ../libcpp/internal.h instead of cpphash.h.
+ * cppcharset.c: Removed.
+ * cpperror.c: Removed.
+ * cppexp.c: Removed.
+ * cppfiles.c: Removed.
+ * cpphash.c: Removed.
+ * cpphash.h: Removed.
+ * cppinit.c: Removed.
+ * cpplex.c: Removed.
+ * cpplib.c: Removed.
+ * cpplib.h: Removed.
+ * cppmacro.c: Removed.
+ * cpppch.c: Removed.
+ * cpptrad.c: Removed.
+ * cppucnid.h: Removed.
+ * cppucnid.pl: Removed.
+ * cppucnid.tab: Removed.
+ * hashtable.c: Removed.
+ * hashtable.h: Removed.
+ * line-map.c: Removed.
+ * line-map.h: Removed.
+ * mkdeps.c: Removed.
+ * mkdeps.h: Removed.
+ * stringpool.h: Include symtab.h instead of hashtable.h.
+ * tree.h: Include symtab.h instead of hashtable.h.
+ * system.h (O_NONBLOCK, O_NOCTTY): Do not define.
+
+2004-05-23 Paolo Bonzini <bonzini@gnu.org>
+
+ * gcc.c (struct prefix_list): Add forward declaration.
+ (do_spec_path): New function, extracted from...
+ (do_spec_1) <'D'>: ... here. Drop support for
+ SPACE_AFTER_L_OPTION.
+ (do_spec_1) <'I'>: Use do_spec_path.
+ (process_command): Do not store the 'include' suffix
+ in include_prefixes.
+ * system.h: Poison SPACE_AFTER_L_OPTION.
+
+2002-05-23 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (non_lvalue): Explicitly list the tree codes that
+ need to be wrapped by NON_LVALUE_EXPR, instead of those that don't.
+
+2004-05-23 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/gcc.texi, doc/gccint.texi, doc/include/gcc-common.texi:
+ Update based on printed manual. Enable setting of offsets for
+ FSFPRINT and move it to gcc-common.texi.
+ * doc/gcc.texi: Update FSF printing details.
+ * doc/gccint.texi: Remove FSF printing details.
+
+2004-05-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/t-rs6000: Remove the disabling -Werror.
+
+2004-05-22 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_strstr, expand_builtin_strchr,
+ expand_builtin_strrchr, expand_builtin_strpbrk,
+ expand_builtin_mempcpy, expand_builtin_memcmp,
+ expand_builtin_strcmp, expand_builtin_strncmp,
+ expand_builtin_strcat, std_expand_builtin_va_start,
+ std_expand_builtin_va_arg, expand_builtin_va_copy,
+ expand_builtin_signbit, fold_builtin_cabs,
+ fold_builtin_logarithm, fold_builtin_mempcpy,
+ fold_builtin_signbit, fold_builtin_isascii,
+ fold_builtin_toascii, fold_builtin_isdigit,
+ fold_builtin_1, build_function_call_expr,
+ simplify_builtin_strchr, simplify_builtin_strrchr,
+ simplify_builtin_strpbrk, simplify_builtin_strncpy,
+ simplify_builtin_memcmp, simplify_builtin_strcmp,
+ simplify_builtin_strncmp, simplify_builtin_strncat,
+ simplify_builtin_strspn, simplify_builtin_strcspn,
+ simplify_builtin_fputs, simplify_builtin_sprintf): Replace calls
+ to build with calls to build2, build3 or omit_one_operand.
+
+2004-05-22 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_file_start): Emit a .gcc_compiled_longXX
+ section when generating EABI code.
+
+2004-05-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR 15546
+ * config/i386/i386.c (output_pic_addr_const <case SYMBOL_REF>):
+ Call mark_decl_referenced on the SYMBOL_REF_DECL.
+
+2004-05-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-common.c (c_common_truthvalue_conversion): Handle
+ UNEQ_EXPR, UNLE_EXPR, UNGE_EXPR, UNLT_EXPR, UNGT_EXPR,
+ ORDERED_EXPR, and UNORDERED_EXPR as comparison operators,
+ i.e. set the type to truthvalue_type_node and return.
+
+2004-05-22 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.h (struct tree_decl): Add possibly_inlined bit.
+ (DECL_POSSIBLY_INLINED): New accessor macro.
+ * cgraph.h: Remove declaration of cgraph_inline_hash.
+ * cgraph.c: Remove definition of cgraph_inline_hash.
+ (hash_node): Revert to hashing DECL_UID.
+ (eq_node): Take two pointers to cgraph_node structures.
+ Compare DECL_UIDs.
+ (cgraph_remove_node): Pass the node directly to htab_find_slot.
+ (cgraph_varpool_hash_node): Rename hash_varpool_node;
+ hash on DECL_UID.
+ (eq_cgraph_varpool_node): Rename eq_varpool_node; take two
+ pointers to cgraph_varpool_node structures; compare DECL_UIDs.
+ (cgraph_node): Allocate a temporary node on the stack, fill in
+ its DECL field, and pass that to htab_find_slot.
+ (cgraph_varpool_node): Likewise.
+ (cgraph_function_possibly_inlined_p): If global info is ready,
+ return the DECL_POSSIBLY_INLINED bit.
+ * cgraphunit.c (cgraph_mark_inline_edge): Set DECL_POSSIBLY_INLINED
+ instead of mucking with cgraph_inline_hash.
+
+2004-05-22 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/contrib.texi: Add g77 contributors.
+
+2004-05-22 Richard Sandiford <rsandifo@redhat.com>
+
+ * calls.c (initialize_argument_information): Forbid sibcalls if a
+ callee-copied argument is stored in the current function's frame.
+
+2004-05-22 Eric Christopher <echristo@redhat.com>
+
+ * fix-header.c (read_scan_file): Update for add_path change.
+
+2004-05-22 Ben Elliston <bje@au.ibm.com>
+
+ * c.opt (Wmissing-include-dirs): New.
+ * c-opts.c (c_common_handle_option): Pass true for user_supplied_p
+ to add_path () for -I, but false for OPT_idirafter, OPT_iquote and
+ OPT_isystem. Handle case OPT_Wmissing_include_dirs.
+ * c-incpath.h (add_path): Add fourth (bool) argument.
+ * c-incpath.c (add_env_var_paths): Pass false to add_path ().
+ (add_standard_paths): Likewise.
+ (remove_duplicates) [REASON_NOENT]: Warn if -Wmissing-include-dirs
+ is used and the directory was user-supplied via -I.
+ (add_path): Set p->user_supplied_p. Remove duplicated code by
+ using add_cpp_dir_path ().
+ * cpplib.h (struct cpp_options): Add warn_missing_include_dirs.
+ (struct cpp_dir): Add user_supplied_p.
+ * doc/invoke.texi (Warning Options): Document new option.
+
+2004-05-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * fold-const.c (fold_read_from_constant_string): Convert result to
+ requested type.
+
+2004-05-21 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (mostly_copy_tree_r): Don't attempt to copy decls.
+ (copy_if_shared_r): Don't copy decls, types, constants, BINDs.
+ Don't mark VA_ARG_EXPRs volatile here.
+ (gimplify_modify_expr): Unshare TYPE_SIZE_UNIT.
+
+2004-05-21 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (tree-dump.o): Depend on tree-iterator.h.
+ * tree-dump.c (dequeue_and_dump): Dump STATEMENT_LISTs.
+
+2004-05-21 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold, fold_relational_hi_lo,
+ nondestructive_fold_binary_to_constant,
+ fold_read_from_constant_string): Use fold_convert instead of convert.
+ * builtins.c (simplify_builtin, simplify_builtin_strstr,
+ simplify_builtin_strchr, simplify_builtin_strrchr,
+ simplify_builtin_strpbrk): Use fold_convert instead of convert.
+
+2004-05-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow-inline.h (num_immediate_uses): Don't abort if DF
+ is NULL.
+
+2004-05-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/linux64.h (OPTION_DEFAULT_SPECS): If SPARC_BI_ARCH,
+ override sparc.h definition.
+
+2004-05-20 Roger Sayle <roger@eyesopen.com>
+
+ * tree.c (array_type_nelts, save_expr, substitute_in_expr,
+ get_unwidened, get_narrower): Replace build with build2.
+ * fold-const.c (negate_expr, associate_trees, size_binop,
+ fold_convert, eval_subst, omit_one_operand, invert_truthvalue,
+ pedantic_omit_one_operand, distribute_bit_expr,
+ make_bit_field_ref, optimize_bit_field_compare,
+ decode_field_reference, range_binop, make_range,
+ build_range_check, fold_range_test, fold_truthop,
+ optimize_minmax_comparison, extract_muldiv_1,
+ fold_binary_op_with_conditional_arg, fold_mathfn_compare,
+ fold_inf_compare, fold_single_bit_test, fold,
+ fold_relational_hi_lo, nondestructive_fold_binary_to_constant):
+ Likewise replace build with either build2 or build3.
+
+2004-05-20 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * system.h: Poison NO_RECURSIVE_FUNCTION_CSE.
+ * calls.c (prepare_call_address): Don't test
+ NO_RECURSIVE_FUNCTION_CSE.
+ * config/arc/arc.h (NO_RECURSIVE_FUNCTION_CSE): Don't define.
+ * config/arm/arm.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/avr/avr.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/frv/frv.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/i386/i386.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/ip2k/ip2k.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/iq2000/iq2000.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/m32r/m32r.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/m68k/m68k.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/mcore/mcore.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/mips/mips.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/stormy16/stormy16.h (NO_RECURSIVE_FUNCTION_CSE):
+ Likewise.
+ * config/xtensa/xtensa.h (NO_RECURSIVE_FUNCTION_CSE): Likewise.
+ * config/sh/sh.h: Remove NO_RECURSIVE_FUNCTION_CSE comment.
+ * doc/tm.texi (Costs): Remove documentation for
+ NO_RECURSIVE_FUNCTION_CSE.
+
+2004-05-20 Paul Brook <paul@codesourcery.com>
+
+ * unwind-dw2-fde.c (get_cie_encoding): Handle dwarf3 CIE format.
+ * unwind-dw2.c (extract_cie_info): Ditto.
+ (_Unwind_FrameState): Change retaddr_column to word type.
+
+2004-05-20 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/3074
+ * fold-const.c (strip_compound_expr): Delete function.
+ (count_cond): Delete function.
+ (fold_binary_op_with_conditional_arg): Only perform transformations
+ "a + (b?c:d) -> b ? a+c : a+d" and "(b?c:d) + a -> b ? c+a : d+a"
+ when a is constant. This greatly simplifies this routine.
+
+ * tree.c (saved_expr_p): Delete function.
+ * tree.h (saved_expr_p): Delete function prototype.
+
+2004-05-20 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * common.opt (ftree-loop-optimize): Remove.
+
+2004-05-20 Daniel Jacobowitz <dan@debian.org>
+
+ * Makefile.in (AR_FOR_TARGET, RANLIB_FOR_TARGET)
+ (NM_FOR_TARGET): Use := and $(shell).
+ (mainversion): Remove unused variable.
+
+2004-05-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * reorg.c (delete_from_delay_slot): If we have a barrier after the
+ sequence containing the insn to be deleted, always reemit it.
+
+2004-05-20 Richard Henderson <rth@redhat.com>
+
+ PR 15454
+ * tree-nested.c (get_chain_decl): Create a PARM_DECL by hand.
+ * function.c (expand_function_start): Expand static_chain_decl by hand.
+ * gimplify.c (create_tmp_var_name): Export.
+ * tree-gimple.h (create_tmp_var_name): Declare.
+
+2004-05-20 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * rs6000.c (print_operand) <case 'z'>: Call
+ mark_decl_referenced before assemble_name.
+
+2004-05-20 Zack Weinberg <zack@codesourcery.com>
+
+ * cgraph.c (hash_node, eq_node, cgraph_node, cgraph_remove_node)
+ (cgraph_varpool_hash_node, eq_cgraph_varpool_node)
+ (cgraph_varpool_node): Hash on the pointer to the decl, not
+ the DECL_UID. Fixes 64-bit bootstrap failure.
+
+2004-05-20 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (ite_ne_zeroextractsi, ite_ne_zeroextractsi_shifted): Ensure
+ we don't earlyclobber operands used in the second insn.
+
+2004-05-20 Steven Bosscher <stevenb@suse.de>
+
+ * tree-mudflap.c: Formatting fixes.
+
+2004-05-20 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * Makefile.in (GTFILES): Add $(srcdir)/reload.h.
+ * gengtype.c (open_base_files): Include reload.h in ifiles.
+ * reload.h (reg_equiv_memory_loc_varray): Declare.
+ * reload1.c (reg_equiv_memory_loc_varray): New variable.
+ (init_reload): Initialize it.
+ (reload): Instead of freeing reg_equiv_memory_loc, 'grow'
+ reg_equiv_memory_loc_varray to size 0.
+ * ra.c (reg_alloc): Allocate reg_equiv_memory_loc by
+ growing reg_equiv_memory_loc_varray to the desired size.
+ * passes.c (rest_of_handle_old_regalloc): Likewise.
+ * reload.c: Amend comment on calling init_reload.
+
+2004-05-20 Nick Clifton <nickc@redhat.com>
+
+ * config/c4x/c4x.h (INITIALIZE_TRAMPOLINE): Replace 'tramp'
+ with 'TRAMP' in the body of the macro definition.
+
+2004-05-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/15383
+ * config/ia64/ia64.c (ia64_expand_compare): Don't check
+ TARGET_HPUX for TFmode compare. Abort if op0 is in TFmode and
+ cmptf_libfunc isn't set.
+ (ia64_init_libfuncs): Rename TFmode libfuncs using the HPUX
+ conventions.
+ (ia64_sysv4_init_libfuncs): New.
+
+ * config/ia64/sysv4.h (TARGET_INIT_LIBFUNCS): New. Defined as
+ ia64_sysv4_init_libfuncs.
+
+2004-05-20 Falk Hueffner <falk@debian.org>
+
+ PR other/15526
+ * libgcc2.c (__mulvsi3): Fix overflow test.
+
+2004-05-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/14171
+ * reg-stack.c (nan): Rename to ...
+ (not_a_num): Here.
+ (reg_to_stack): Rename nan to not_a_num.
+ (subst_stack_regs_pat): Likewise.
+ (convert_regs_entry): Likewise.
+ (convert_regs_1): Likewise.
+
+ * tree-cfg.c (find_case_label_for_value): Replace call to
+ simple_cst_equal with tree_int_cst_equal.
+
+2004-05-19 Jeff Law <law@redhat.com>
+
+ * tree-into-ssa.c (prepare_operand_for_rename): New argument is_use.
+ If the operand is for a use, then strip away the SSA_NAME, do not
+ strip away the SSA_NAME for a set. Never call release_ssa_name.
+ (mark_def_sites): Appropriately pass additional argument to
+ prepare_operand_for_rename. If a VDEF_RESULT is not an SSA_NAME,
+ then set the VDEF_RESULT to the VDEF_OP.
+ (set_def_block): Strip away any SSA_NAME to get to the real
+ underlying variable.
+
+ * tree-ssa-phiopt.c (value_replacement): Handle the case where
+ the desired edge out of COND_BLOCK reaches OTHER_BLOCK rather than
+ BB directly.
+
+2004-05-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR c++/15463
+ * loop-iv.c (iv_number_of_iterations): Use trunc_int_for_mode on
+ result of inverse.
+
+ PR rtl-optimization/15274
+ * loop-iv.c (determine_max_iter, shorten_into_mode,
+ iv_number_of_iterations): Handle constants correctly.
+ * rtl.h (get_mode_bounds): Declaration changed.
+ * stor-layout.c (get_mode_bounds): Return a constant suitable for
+ the target mode.
+
+ PR rtl-optimization/14692
+ * loop-unswitch.c (may_unswitch_on): Try folding the result.
+ (unswitch_single_loop): Work correctly when may_unswitch_on
+ returns a folded constant.
+
+ * loop-iv.c (implies_p): Handle A < B ==> A + 1 <= B.
+ * simplify-rtx.c (simplify_const_relational_operation): Optimize
+ comparisons with mode bounds.
+
+ * function.c (struct temp_slot): Add new field prev.
+ (free_after_compilation, init_temp_slots): Free new fields.
+ (cut_slot_from_list, insert_slot_to_list,
+ temp_slots_at_level, max_slot_level, move_slot_to_level,
+ make_slot_available): New functions.
+ (assign_stack_temp_for_type, combine_temp_slots,
+ find_temp_slot_from_address, preserve_temp_slots,
+ preserve_rtl_expr_result, free_temp_slots,
+ free_temps_for_rtl_expr, pop_temp_slots): Work with
+ the new structure of lists.
+ (mark_all_temps_used): Removed.
+ * function.h (struct function): Field x_temp_slots
+ replaced by x_used_temp_slots and x_avail_temp_slots.
+ (temp_slots): Replaced by ...
+ (used_temp_slots, avail_temp_slots): New.
+ * tree.h (mark_all_temps_used): Declaration removed.
+
+ * loop-iv.c (mark_single_set, get_biv_step_1, iv_analyze,
+ simplify_using_assignment): Take the expression out of
+ the expr_list wrapper.
+
+ * loop-iv.c (iv_number_of_iterations): Improve clasification of
+ infinite loops.
+
+2004-05-19 Roger Sayle <roger@eyesopen.com>
+
+ * doc/tm.texi (TARGET_RTX_COSTS): Document that instruction
+ costs should be based on code size when optimizing for size.
+
+2004-05-19 Paolo Bonzini <bonzini@gnu.org>
+
+ * fold-const.c: Remove non-printable character 160.
+
+2004-05-19 Nick Clifton <nickc@redhat.com>
+
+ * doc/invoke.texi (ARM Options): Fix typo.
+ Remove descrption of -mshort-load-bytes and
+ -mno-short-load-bytes.
+
+ * config/ip2k/ip2k.c (ip2k_composite_xexp_not_uses_reg_p): Add
+ missing parenthesis.
+ * config/ip2k/ip2k.c (ip2k_unary_operator): Likewise.
+ * config/ip2k/ip2k.c (ip2k_binary_operator): Likewise.
+
+2004-05-19 Steven Bosscher <stevenb@suse.de>
+
+ * expr.c (store_constructor): Build loop start and end by hand
+ instead of via loop functions from stmt.c.
+ (expand_expr_real_1): Abort if we see an EXIT_EXPR or a LOOP_EXPR.
+ Remove the code to expand them.
+
+ * stmt.c (loop_stack): Remove this and everything related.
+ (struct nesting, enum nesting_desc): Update.
+ (expand_fixup): Likewise.
+ (expand_loop_start, expand_start_loop_continue_elsewhere,
+ expand_start_null_loop, expand_loop_continue_here, expand_end_loop,
+ expand_end_null_loop, expand_continue_loop, expand_exit_loop,
+ expand_exit_loop_if_false, expand_exit_loop_top_cond,
+ expand_exit_something): Remove.
+ * tree.h: Remove prototypes.
+
+2004-05-18 Mike Stump <mrs@apple.com>
+ Devang Patel <dpatel@apple.com>
+
+ * doc/tm.texi (TARGET_ASM_EMIT_UNWIND_LABEL): Add argument to indicate
+ if this label is for eh.
+ * config/darwin-protos.h (darwin_emit_unwind_label): Likewise.
+ * config/darwin.c (darwin_emit_unwind_label): Likewise.
+ * dwarf2out.c (output_call_frame_info): Likewise.
+ * output.h (default_emit_unwind_label): Likewise.
+ * target.h (unwind_label): Likewise.
+ * varasm.c (default_emit_unwind_label): Likewise.
+
+ * config/darwin.h (DWARF2_DEBUGGING_INFO, PREFERRED_DEBUGGING_TYPE,
+ DEBUG_FRAME_SECTION, DEBUG_INFO_SECTION, DEBUG_ABBREV_SECTION,
+ DEBUG_ARANGES_SECTION, DEBUG_MACINFO_SECTION, DEBUG_LINE_SECTION,
+ DEBUG_LOC_SECTION, DEBUG_PUBNAMES_SECTION, DEBUG_STR_SECTION,
+ DEBUG_RANGES_SECTION): Define.
+
+2004-05-18 Zack Weinberg <zack@codesourcery.com>
+
+ * cgraph.c (hash_node, eq_node, cgraph_node, cgraph_remove_node)
+ (cgraph_varpool_hash_node, eq_cgraph_varpool_node)
+ (cgraph_varpool_node):
+ Use DECL_UID for the key, not DECL_ASSEMBLER_NAME.
+ (cgraph_function_possibly_inlined_p): Use the decl itself for
+ the key, not DECL_ASSEMBLER_NAME.
+ (change_decl_assembler_name): No need to muck with the hash tables.
+ (cgraph_node_for_identifier, cgraph_varpool_node_for_identifier):
+ Delete.
+ * cgraphunit.c (cgraph_mark_inline_edge): Use the decl itself
+ for the key, not DECL_ASSEMBLER_NAME.
+ * cgraph.h: Remove prototypes of deleted functions.
+ * varasm.c (mark_referenced): Just set TREE_SYMBOL_REFERENCED.
+ (mark_decl_referenced): New function.
+ * tree.h: Prototype mark_decl_referenced.
+ * final.c (output_addr_const) <case SYMBOL_REF>: Call
+ mark_decl_referenced before assemble_name.
+ * c-decl.c (finish_decl): Use mark_decl_referenced.
+
+2004-05-18 Andrew Pinski <pinskia@physics.uc.edu>
+ Jeff Law <law@redhat.com>
+
+ * tree-ssa-phiopt.c (abs_replacement): New function.
+ (empty_block_p): New function extracted from...
+ (candidate_bb_for_phi_optimization): Break out empty block test.
+ (conditional_replacement): Use empty_block_p.
+ (value_replacement): Similarly.
+
+ * Makefile.in (tree-ssa-phiopt.o): Depends on flags.h.
+ * tree-ssa-phiopt.c: Include flags.h.
+ (conditional_replacement): Remove argument names from prototype.
+ Minor formatting and comment fixes.
+ (tree_ssa_phiopt): If conditional_replacement returns false, then
+ call value_replacement.
+ (value_replacement): New function.
+
+2004-05-18 Jeff Law <law@redhat.com>
+
+ * tree-ssa-phiopt.c (replace_phi_with_stmt): New function extracted
+ from conditional_replacement.
+ (candidate_bb_for_phi_optimization): Similarly.
+ (conditional_replacement): Use replace_phi_with_stmt and
+ candidate_bb_for_phi_optimization.
+
+ * tree-ssa-phiopt.c: Fix various formatting issues.
+
+2004-05-18 Steven Bosscher <stevenb@suse.de>
+
+ * config/s390/s390.c (s390_expand_movstr, s390_expand_clrstr,
+ s390_expand_cmpmem): Do not use expand_start_loop and
+ expand_end_loop, instead build the loop manually.
+
+2004-05-18 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md (ctrsi_internal3): Delete.
+ (ctrsi_internal4, ctrdi_internal3, ctrdi_internal4): Delete.
+
+2004-05-17 Jeff Law <law@redhat.com>
+
+ * toplev.h (flag_delete_null_pointer_checks): Move from here to...
+ * flags.h (flag_delete_null_pointer_checks): Here.
+ * tree-flow.h (cprop_into_successor_phis): Add argument to prototype.
+ * tree-phinodes.c (resize_phi_node): Initialize PHI_ARG_NONZERO.
+ (add_phi_arg, remove_phi_arg_num): Similarly.
+ * tree-ssa-copy.c (cprop_into_successor_phis): Propagate nonzero
+ property into PHI nodes.
+ * tree-ssa-dom.c: Remove redundant inclusion of flags.h.
+ (record_equivalences_from_phis): If all PHI arguments are known to be
+ nonzero, then the result must be nonzero as well.
+ (cprop_into_phis): Pass nonzero_vars bitmap to cprop_into_successor_phis.
+ (record_equivalences_from_stmt): Check flag_delete_null_pointer_checks
+ appropriately. Walk the USE-DEF chains and propagate nonzero property
+ as appropriate.
+ * tree.h (PHI_ARG_NONZERO): Define.
+ (phi_arg_d): Add nonzero flag.
+
+2004-05-17 Zack Weinberg <zack@codesourcery.com>
+
+ * f: Entire directory removed
+
+ * c-common.h (CTI_G77_INTEGER_TYPE, CTI_G77_UINTEGER_TYPE)
+ (CTI_G77_LONGINT_TYPE, CTI_G77_ULONGINT_TYPE)
+ (g77_integer_type_node, g77_uinteger_type_node)
+ (g77_longint_type_node, or g77_ulongint_type_node): Delete.
+ * c-common.c (c_common_nodes_and_builtins): Do not initialize
+ the above set of variables.
+
+ * config/i386/uwin.h: No need to define WIN32_UWIN_TARGET.
+ * doc/invoke.texi, doc/standards.texi: Remove cross-references
+ to g77 manual.
+
+2004-05-17 Steven Bosscher <stevenb@suse.de>
+
+ PR tree-optimization/15438
+ * tree-ssa-operands.c (get_expr_operands): Do not treat malloc
+ attributed functions as pure or const.
+
+2004-05-17 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_register_decls): Tolerate decl trees resulting
+ from source code with errors.
+
+2004-05-17 Ranjit Mathew <rmathew@hotmail.com>
+
+ Enable tree browser for all front ends.
+ * Makefile.in (cc1): Moved @TREEBROWSER@ from here...
+ (BACKEND): ...to here.
+
+2004-05-17 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (construct_container): Do not produce BLKmode registers.
+ (classify_argument): Properly compute alignment of complex types.
+
+2004-05-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/15084
+ * config/i386/i386.md (*movsi_insv_1_rex64): Changed to DImode
+ and renamed to movdi_insv_1_rex64.
+ (insv): Support SImode for 32bit and DImode for 64bit.
+
+2004-05-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MASK_DEBUG_G, TARGET_DEBUG_G_MODE): Delete.
+ (TARGET_SWITCHES): Remove debugg.
+ * config/mips/mips.md (adddi3, ashldi3, ashrdi3, lshrdi3): Only handle
+ TARGET_64BIT.
+ (subdi3): Replace the define_expand with a define_insn, the latter
+ renamed from subdi3_internal_3.
+ (negdi2): Likewise negdi2_internal_2.
+ (adddi3_internal_[12], subdi3_internal, ashldi3_internal{,2,3})
+ (ashrdi3_internal{,2,3}, lshrdi3_internal{,2,3}): Remove patterns
+ and associated define_splits.
+ (adddi3_internal): Renamed from adddi3_internal_3.
+ (ashldi3_internal): Likewise ashldi3_internal4.
+ (ashrdi3_internal): Likewise ashrdi3_internal4.
+ (lshrdi3_internal): Likewise lshrdi3_internal4.
+
+2004-05-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * optabs.c (expand_unop): Try implementing negation using subtraction
+ from zero.
+
+2004-05-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md: Fix typo from last change. Remove DFmode move to and from
+ SAR register.
+
+2004-05-16 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/10982
+ * arm.md (ne_zeroextractsi): Convert to insn-and-split.
+ (ne_zeroextractsi_shifted): New pattern.
+ (ite_ne_zeroextractsi): New pattern.
+ (ite_ne_zeroextractsi_shifted): New pattern.
+
+2004-05-15 Steven Bosscher <stevenb@suse.de>
+
+ * c-gimplify.c (c_genericize):
+ Replace calls via (*lang_hooks.foo) with lang_hooks.foo.
+ * c-parse.in <expr_no_commas>: Likewise.
+ <if_prefix>: Likewise.
+ <select_or_iter_stmt>: Likewise.
+ * expr.c (expand_var, expand_expr_real_1): Likewise.
+ * expr.h (expand_expr): Make it a static inline function.
+ Move prototype for expand_expr_real up before this.
+ * fold-const.c (fold_relational_hi_lo, fold_relational_const):
+ Likewise.
+ * gimplify.c (gimple_boolify, gimplify_addr_expr,
+ gimplify_asm_expr, gimplify_expr): Likewise.
+ * tree-cfg.c (dump_tree_cfg, dump_cfg_stats, tree_cfg2vcg,
+ dump_function_to_file): Likewise.
+ * tree-dfa.c (dump_immediate_uses, dump_dfa_stats): Likewise.
+ * tree-inline.c (remap_block, save_body, walk_tree): Likewise.
+ * tree-into-ssa.c (dump_tree_ssa): Likewise.
+ * tree-mudflap.c (mf_varname_tree, mf_file_function_line_tree):
+ Likewise.
+ * tree-optimize.c (execute_one_pass): Likewise.
+ * tree-pretty-print.c (dump_generic_bb_buff): Likewise.
+ * tree-ssa-alias.c (dump_alias_stats, dump_alias_info): Likewise.
+
+ * objc/objc-act.c (objc_build_try_enter_fragment,
+ objc_build_try_epilogue, objc_build_catch_stmt,
+ objc_build_finally_prologue): Replace calls via (*lang_hooks.foo)
+ with lang_hooks.foo ().
+
+2004-05-15 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (simplify_builtin_strcpy): Avoid use of chainon, so
+ that simplify_builtin doesn't destructively modify its argument.
+
+2004-05-15 Richard Earnshaw <reanrsha@arm.com>
+
+ * arm/lib1funcs.asm (_lshrdi3, _ashrdi3, _ashldi3): Add ASM
+ implementations for ARM and Thumb.
+ * arm/t-arm-elf (LIB1ASMFUNCS): Use them.
+
+2004-05-15 Thomas Quinot <quinot@act-europe.fr>
+
+ * prefix.c (update_path): Replace PREFIX with KEY only
+ when it matches a full directory name in PATH.
+
+2004-05-15 Richard Earnshaw <reanrsha@arm.com>
+
+ * arm.h (TARGET_APCS_32): Delete.
+ (TARGET_MMU_TRAPS): Delete.
+ (TARGET_CPU_CPP_BUILTINS): Unconditionally define __APCS_32__. Never
+ define __APCS_26__.
+ (CPP_SPEC): Remove checking of -mapcs-{26,32}.
+ (ARM_FLAG_APCS_32, ARM_FLAG_MMU_TRAPS): Delete.
+ (TARGET_SWITCHES): Remove alignment_traps and apcs-{26,32} switches.
+ (prog_mode_type): Delete.
+ (PROMOTE_MODE): Always promote unsigned for HImode.
+ (SECONDARY_INPUT_RELOAD_CLASS): Simplify.
+ (MASK_RETURN_ADDR): Simplify.
+ * arm.c (arm_prgmode): Delete.
+ (arm_override_options, arm_gen_rotated_half_load): Simplify.
+ (print_multi_reg, output_return_instruction): Simplify.
+ (arm_output_epilogue, arm_final_prescan_insn): Simplify.
+ (arm_return_addr): Simplify.
+ * arm.md (prog_mode): Delete.
+ (conds): Simplify.
+ (zero_extendhisi2, extendhisi2, movhi, movhi_bytes): Simplify.
+ (rotated_loadsi, movhi_insn_littleend, movhi_insn_bigend): Delete.
+ (loadhi_si_bigend, loadhi_preinc, loadhi_shiftpreinc): Delete.
+ (loadhi_shiftpredec): Delete.
+ (peephole for post-increment on HImode load): Delete.
+ * arm/crtn.asm: (FUNC_END): Simplify.
+ * arm/lib1funcs.asm: Remove APCS-26 return macros.
+ * arm/aof.h, arm/coff.h arm/elf.h arm/linux-elf.h arm/netbsd-elf.h
+ * arm/netbsd.h arm/pe.h arm/semi.h arm/semiaof.h arm/unknown-elf.h
+ * arm/vxworks.h arm/wince-pe.h: Tidy TARGET_DEFAULTS and
+ MULTILIB_DEFAULTS as required.
+ * arm/t-arm-elf arm/t-linux arm/t-pe arm/t-semi arm/t-wince-pe
+ * arm/t-xscale-coff arm/t-xscale-elf arm/uclinux-elf: Tidy MULTILIB
+ variables as required.
+ * doc/invoke.texi (ARM Options): Remove obsolete flags.
+
+2004-05-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_va_arg <ABI_V4>): Don't use
+ UNITS_PER_WORD to calculate gpr size. Re-instate code to set reg
+ count to 8 to handle n_reg > 2.
+
+2004-05-15 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/extend.texi: Update WG14 URL.
+
+2004-05-15 Steven Bosscher <stevenb@suse.de>
+
+ * basic-block.h (life_analysis, delete_noop_moves):
+ Update prototypes.
+ * bt-load.c (branch_target_load_optimize): Don't take the
+ insns stream as an argument. Update the life_analysis calls.
+ * combine.c (combine_instructions): Update delete_noop_moves
+ calls.
+ * flow.c (notice_stack_pointer_modification): Don't take the
+ insns stream as an argument. Work on the flow graph.
+ (life_analysis): Likewise.
+ (delete_noop_moves): Likewise.
+ * passes.c (rest_of_handle_stack_regs): Update reg_to_stack call.
+ (rest_of_handle_life): Update life_analysis call.
+ (rest_of_compilation): Likewise, and also update
+ branch_target_load_optimize call.
+ * ra.c (reg_alloc): Update life_analysis call.
+ * reg-stack.c (reg_to_stack): Likewise. Also, don't take
+ the insns stream as an argument.
+ * regrename.c (copyprop_hardreg_forward): Update delete_noop_moves
+ call.
+ * rtl.c (branch_target_load_optimize, reg_to_stack): Update
+ prototypes.
+ * value-profile.c (branch_prob): Update life_analysis call.
+ * web.c (web_main): Work on the CFG, not on the insns stream.
+
+ * config/ip2k/ip2k.c (ip2k_reorg): Update life_analysis calls.
+ * config/m68hc11/m68hc11.c (m68hc11_reorg): Likewise.
+ * config/sh/sh.c (sh_output_mi_thunk): Likewise.
+
+2004-05-15 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/15444
+ * c-format.c (avoid_dollar_number): New function.
+ (check_format_info_main): Call avoid_dollar_number when operand
+ numbers might occur but has_operand_number == 0.
+
+2004-05-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (all peephole2 patterns): Use predicates that validate
+ register classes as appropriate.
+
+2004-05-14 Steven Bosscher <stevenb@suse.de>
+
+ PR opt/14472
+ * tree-tailcall.c (process_assignment): Use STRIP_NOPS to
+ ignore type conversions that do not inhibit tail calling.
+ (find_tail_calls): Likewise.
+
+2004-05-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Don't even
+ bother marking bypassed virtuals for out-of-ssa. Instead merge
+ bypassed virtuals into vars_to_rename just before into-ssa pass.
+
+ * 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.kazuhiro@renesas.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.
+
+2004-04-12 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (output_387_reg_move): New function.
+ * config/i386/i386-protos.h (output_387_reg_move): Prototype here.
+ * config/i386/i386.md (*movsf_1, *movsf1_nointerunit,
+ *movdf_nointeger, *movdf_integer, *movxf_nointeger, *movxf_integer,
+ *extendsfdf2_1, *extendsfxf2_1, *extenddfxf2_1, truncdfsf2_noop,
+ truncxfsf2_noop, truncxfdf2_noop): Call output_387_reg_move.
+
+2004-04-12 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * c-decl.c (finish_decl): Make a decl_stmt for a variable-sized
+ TYPE_DECL.
+ * c-semantics.c (genrtl_decl_stmt): Handle TYPE_DECL.
+ * stmt.c (expand_decl): Remove redundant expansion of TYPE_DOMAIN.
+ * stor-layout.c (variable_size): Don't check for MINUS_EXPR.
+ Use skip_simple_arithmetic to find SAVE_EXPR.
+ (force_type_save_exprs, force_type_save_exprs_1): New functions.
+ * tree-inline.c (remap_type, case POINTER_TYPE, case REFERENCE_TYPE):
+ Properly chain multiple pointers.
+ (copy_tree_r): Copy a TYPE_DECL.
+ * tree.c (variably_modified_type_p): Add some missing tests and
+ make some other minor changes.
+ * tree.h (force_type_save_exprs): New declaration.
+
+2004-04-12 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_binary_operation) <UDIV, DIV, UMOD, MOD>:
+ Remove fall throughs. Convert 0/x and 0%x into x&0 when x has
+ side-effects. Don't convert x/1.0 into x if we honor signaling NaNs.
+ Convert x/-1.0 into -x if we don't honor signaling NaNs. Convert
+ x/-1 into -x. Optimize x%1 into x&0 if x has side-effects. Optimize
+ x%-1 into 0 (or x&0 if x has side-effects).
+
+2004-04-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md: Document why a pattern is not
+ available.
+
+ * config/rs6000/rs6000.c (rs6000_emit_cmove): Disable comparisons
+ of floats on the E500.
+ (branch_positive_comparison_operator): Do not allow NE even on the
+ E500.
+
+2004-04-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_assemble_integer): Change
+ in_text_unlikely_section to in_unlikely_text_section.
+
+2004-04-11 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_binary_op_with_conditional_arg): Tweak
+ calling convention to allow a NULL_TREE to be returned. Factor
+ sanity checks from callers, return NULL_TREE when appropriate.
+ (fold): Handle COMPOUND_EXPR operands of binary expressions
+ before COND_EXPR operands. Use reorder_operands_p(a,b) to check
+ whether a op (b,c) can be rewritten as (b, a op c). Simplify
+ calls to fold_binary_op_with_conditional_arg.
+
+2004-04-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/iris5.h (current_section_flags): Add
+ in_unlikely_executed_text and default case.
+
+2004-04-11 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * bb-reorder.c (fix_crossing_conditional_branches): Fix bootstrap
+ failure on solaris. Place ifdef HAVE_return around gen_ret call.
+ * cfgrtl.c (force_nonfallthru_and_redirect): Remove ifdef
+ HAVE_return and place it around the place where it is needed.
+
+2004-04-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * varasm.c (text_section): Use TEXT_SECTION_ASM_OP and
+ ASM_OUTPUT_ALIGN instead of SECTION_FORMAT_STRING
+ and NORMAL_TEXT_SECTION_NAME.
+ (unlikely_text_section): Check targetm.have_named_sections
+ instead of TARGET_ASM_NAMED_SECTION and use TEXT_SECTION_ASM_OP
+ instead of SECTION_FORMAT_STRING.
+ * config/mips/iris5.h (current_section_name): Add
+ in_unlikely_executed_text case and move the abort into the switch.
+ * config/rs6000/sysv4.h (HOT_TEXT_SECTION_NAME): Remove.
+ (NORMAL_TEXT_SECTION_NAME): Remove.
+ (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove.
+ (SECTION_FORMAT_STRING): Remove.
+ * defaults.h (SECTION_FORMAT_STRING): Remove.
+ * tm.texi (NORMAL_TEXT_SECTION_NAME): Remove.
+ (SECTION_FORMAT_STRING): Remove.
+
+2004-04-10 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (common_type): Prefer long long to long when same
+ precision.
+
+2004-04-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR 14887
+ * config/ia64/hpux.h (MEMBER_TYPE_FORCES_BLK): Look only at
+ mode argument.
+ * config/ia64/ia64.c (ia64_hpux_file_end): Check
+ TREE_SYMBOL_REFERENCED on DECL_ASSEMBLER_NAME, not DECL_NAME.
+
+2004-04-09 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (mode_signbit_p): New function to check whether
+ an RTX is an immediate constant that represents the most significant
+ bit of a given machine mode.
+ (simplify_unary_operation) <NOT>: Optimize ~(X+C) as X ^ ~C, where
+ C is the sign bit.
+ (simplify_binary_operation) <PLUS>: Optimize (X^C1) + C2 as X^(C1^C2)
+ when C2 is the sign bit.
+ (simplify_binary_operation) <XOR>: Canonicalize X^C as X+C when C
+ is the sign bit. Optimize (X+C1) ^ C2 as X^(C1^C2) when C1 is the
+ sign bit.
+
+2004-04-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (mathfn_built_in): Check TYPE_MAIN_VARIANT, not
+ TYPE_MODE.
+
+2004-04-09 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-common.c (handle_noreturn_attribute): Use TYPE_READONLY instead
+ of TREE_READONLY for types.
+
+2004-04-09 Caroline Tice <ctice@apple.com>
+
+ * basic-block.h (struct edge_def): Add new field, crossing_edge.
+ (struct basic_block_def): Add new field, partition.
+ (UNPARTITIONED, HOT_PARTITION, COLD_PARTITION): New constant macro
+ definitions.
+ (partition_hot_cold_basic_blocks): Add extern function
+ declaration.
+ * bb-reorder.c (function.h, obstack.h, expr.h, regs.h): Add four new
+ include statements.
+ (N_ROUNDS): Increase the maximum number of rounds by 1.
+ (branch_threshold): Add array value for new round.
+ (exec_threshold): Add array value for new round.
+ (push_to_next_round_p): New function.
+ (add_unlikely_executed_notes): New function.
+ (find_rarely_executed_basic_blocks_and_crossing_edges): New function.
+ (mark_bb_for_unlikely_executed_section): New function.
+ (add_labels_and_missing_jumps): New function.
+ (add_reg_crossing_jump_notes): New function.
+ (fix_up_fall_thru_edges): New function.
+ (find_jump_block): New function.
+ (fix_crossing_conditional_branches): New function.
+ (fix_crossing_unconditional_branches): New function.
+ (fix_edges_for_rarely_executed_code): New function.
+ (partition_hot_cold_basic_blocks): New function.
+ (find_traces): Add an extra round for partitioning hot/cold
+ basic blocks.
+ (find_traces_1_round): Add a parameter. Modify to push all cold blocks,
+ and only cold blocks, into the last (extra) round of collecting traces.
+ (better_edge_p): Add a parameter. Modify to favor non-crossing edges
+ over crossing edges.
+ (bb_to_key): Add code to correctly identify cold blocks when
+ doing partitioning.
+ (connect_traces): Modify to connect all the non-cold traces first, then
+ go back and connect up all the cold traces.
+ (reorder_basic_blocks): Add call to add_unlikely_executed_notes.
+ * cfg.c (entry_exit_blocks): Add initialization for partition field in
+ entry and exit blocks.
+ * cfgbuild.c (make_edges): Update current_function_has_computed_jump
+ if we are doing hot/cold partitioning.
+ * cfgcleanup.c (cfglayout.h): Add new include statement.
+ (try_simplify_condjump): Modify to not attempt on blocks with jumps
+ that cross section boundaries.
+ (try_forward_edges): Likewise.
+ (merge_blocks_move_predecessor_nojumps): Likewise.
+ (merge_blocks_move_successor_nojumps): Likewise.
+ (merge_blocks_move): Likewise.
+ (try_crossjump_to_edge): Modify to not attempt after we have done
+ the block partitioning.
+ (try_crossjump_bb): Modify to not attempt on blocks with jumps that
+ cross section boundaries.
+ (try_optimize_cfg): Likewise.
+ * cfghooks.c (tidy_fallthru_edges): Modify to not remove indirect
+ jumps that cross section boundaries.
+ * cfglayout.c (flags.h): Add new include statement.
+ (update_unlikely_executed_notes): New function.
+ (fixup_reorder_chain): Add code so when a new jumping basic block is
+ added, it's UNLIKELY_EXECUTED_CODE and REG_CROSSING_JUMP notes are
+ updated appropriately.
+ (duplicate_insn_chain): Add code to duplicate the new NOTE insn
+ introduced by this optimization.
+ * cfglayout.h (scan_ahead_for_unlikely_executed_note): Add new
+ extern function declaration.
+ * cfgrtl.c (can_delete_note_p): Add NOTE_INSN_UNLIKELY_EXECUTED_CODE to
+ list of notes that can be deleted.
+ (create_basic_block_structure): Add initialization for partition field.
+ (rtl_can_merge_blocks): Modify to test blocks for jumps that cross
+ section boundaries.
+ (try_redirect_by_replacing_jump): Modify to not attempt on jumps that
+ cross section boundaries.
+ (commit_one_edge_insertion): Add code so newly created basic block
+ ends up in correct (hot or cold) section. Modify to disallow
+ insertions before NOTE_INSN_UNLIKELY_EXECUTED_CODE notes.
+ (rtl_verify_flow_info_1): Add code to verify that no fall_thru edge
+ crosses section boundaries.
+ (cfg_layout_can_merge_blocks_p): Modify to test blocks for jumps that
+ cross section boundaries.
+ (force_nonfallthru_and_redirect): Modify to make sure new basic block
+ ends up in correct section, with correct notes attached.
+ * common.opt (freorder-blocks-and-partition): Add new flag for this
+ optimization.
+ * dbxout.c (dbx_function_end): Add code to make sure scope labels at
+ the end of functions are written into the correct (hot or cold)
+ section.
+ (dbx_source_file): Add code so writing debug file information
+ doesn't incorrectly change sections.
+ * defaults.h (NORMAL_TEXT_SECTION_NAME): New constant macro, for use
+ in partitioning hot/cold basic blocks into separate sections.
+ (SECTION_FORMAT_STRING): New constant macro, for linux/i386 hot/cold
+ section partitioning.
+ (HAS_LONG_COND_BRANCH): New constant macro, indicating whether or not
+ conditional branches can span all of memory.
+ (HAS_LONG_UNCOND_BRANCH): New constant macro, indicationg whether or not
+ unconditional branches can span all of memory.
+ * final.c (scan_ahead_for_unlikely_executed_note): New function.
+ (final_scan_insn): Add code to check for NOTE instruction indicating
+ whether basic block belongs in hot or cold section, and to make sure
+ the current basic block is being written to the appropriate section.
+ Also added code to ensure that jump table basic blocks end up in the
+ correct section.
+ * flags.h (flag_reorder_blocks_and_partition): New flag.
+ * ifcvt.c (find_if_case_1): Modify to not attempt if conversion if
+ one of the branches has a jump that crosses between sections.
+ (find_if_case_2): Likewise.
+ (ifcvt): Modify to not attempt to mark loop exit edges after
+ hot/cold partitioning has occurred.
+ * opts.c (decode_options): Code to handle new flag,
+ flag_reorder_blocks_and_partition; also to turn it off if
+ flag_exceptions is on.
+ (common_handle_option): Code to handle new flag,
+ flag_reorder_blocks_and_partition.
+ * output.h (unlikely_text_section): New extern function declaration.
+ (in_unlikely_text_section): New extern function declaration.
+ * passes.c (rest_of_handle_stack_regs): Add
+ flag_reorder_blocks_and_partition as an 'or' condition for calling
+ reorder_basic_blocks.
+ (rest_of_handle_reorder_blocks): Add flag_reorder_blocks_and_partition
+ as an 'or' condition for calling reorder_basic_blocks.
+ (rest_of_compilation): Add call to partition_hot_cold_basic_blocks.
+ * print-rtl.c (print_rtx): Add code for handling new note,
+ NOTE_INSN_UNLIKELY_EXECUTED_CODE
+ * rtl.c (NOTE_INSN_UNLIKELY_EXECUTED_CODE): New note insn (see below).
+ (REG_CROSSING_JUMP): New kind of reg_note, to mark jumps that
+ cross between section boundaries.
+ * rtl.h (NOTE_INSN_UNLIKELY_EXECUTED_CODE): New note instruction,
+ indicating the basic block containing it belongs in the cold section.
+ (REG_CROSSING_JUMP): New type of reg_note, to mark jumps that cross
+ between hot and cold sections.
+ * toplev.c (flag_reorder_blocks_and_partition): Add code to
+ initialize this flag, and to tie it to the command-line option
+ freorder-blocks-and-partition.
+ * varasm.c (cfglayout.h): Add new include statement.
+ (unlikely_section_label_printed): New global variable, used for
+ determining when to output section name labels for cold sections.
+ (in_section): Add in_unlikely_executed_text to enum data structure.
+ (text_section): Modify code to use SECTION_FORMAT_STRING and
+ NORMAL_TEXT_SECTION_NAME macros.
+ (unlikely_text_section): New function.
+ (in_unlikely_text_section): New function.
+ (function_section): Add code to make sure beginning of function is
+ written into correct section (hot or cold).
+ (assemble_start_function): Add code to make sure stuff is written to
+ the correct section.
+ (assemble_zeros): Add in_unlikely_text_section as an 'or' condition
+ to an if statement that was checking 'in_text_section'.
+ (assemble_variable): Add 'in_unlikely_text_section' as an 'or'
+ condition to an if statement that was checking 'in_text_section'.
+ (default_section_type_flags_1): Add check: if in cold section
+ flags = SECTION_CODE.
+ * config/darwin.c (darwin_asm_named_section): Modify to use
+ SECTION_FORMAT_STRING if we are partitioning hot/cold blocks.
+ * config/i386/i386.h (HAS_LONG_COND_BRANCH): Defined this macro
+ specifically for the i386.
+ (HAS_LONG_UNCOND_BRANCH): Defined this macro specifically for the i386.
+ * config/rs6000/darwin.h (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Change
+ text string to something more informative.
+ (NORMAL_TEXT_SECTION_NAME): Add new definition.
+ (SECTION_FORMAT_STRING): Add new definition.
+ * config/rs6000/rs6000.c (rs6000_assemble_integer): Add
+ '!in_unlikely_text_section' as an 'and' condition to an if statement
+ that was already checking '!in_text_section'.
+ * config/rs6000/sysv4.h (HOT_TEXT_SECTION_NAME,NORMAL_TEXT_SECTION_NAME,
+ UNLIKELY_EXECUTED_TEXT_SECTION_NAME,SECTION_FORMAT_STRING): Make
+ sure these are properly defined for linux on ppc.
+ * doc/invoke.texi (freorder-blocks-and-partition): Add documentation
+ for this new flag.
+ * doc/rtl.texi (REG_CROSSING_JUMP): Add documentation for new
+ reg_note.
+ * doc/tm.texi (NORMAL_TEXT_SECTION_NAME, SECTION_FORMAT_STRING,
+ HAS_LONG_COND_BRANCH, HAS_LONG_UNCOND_BRANCH): Add documentation for
+ these new macros.
+
+2004-04-08 Roger Sayle <roger@eyesopen.com>
+
+ * function.c (gen_mem_addressof): When changing the RTX from a REG
+ to a MEM, clear MEM_VOLATILE_P which was formerly REG_USERVAR_P.
+
+2004-04-08 Roger Sayle <roger@eyesopen.com>
+
+ PR target/14888
+ * config/i386/i386.md (truncdfsf2_noop, truncxfsf2_noop,
+ truncxfdf2_noop): Provide dummy "fmov" implementations.
+
+2004-04-08 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * gcc.c (default_compilers): Add missing initializers.
+
+ * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address):
+ Return 1 if file was successfully mapped.
+
+2004-04-08 Geoffrey Keating <geoffk@apple.com>
+
+ PR pch/13419
+ PR pch/14137
+ Radar #: 3315288
+ * doc/invoke.texi (Precompiled Headers): Suggest -o
+ to put an output file in a particular place. Be more detailed
+ about which options affect PCH validity and which options
+ might not work.
+ * c-pch.c (pch_matching): New.
+ (MATCH_SIZE): New.
+ (struct c_pch_validity): New field 'match'.
+ (pch_init): Handle pch_matching.
+ (c_common_valid_pch): Check pch_matching.
+
+ * explow.c: Fix typo defining default of PROMOTE_FUNCTION_MODE.
+
+2004-04-08 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi (Precompiled Headers): Warn about known
+ problems.
+
+2004-04-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/14808
+ * defaults.h (TARGET_USE_LOCAL_THUNK_ALIAS_P): New macro. Default
+ to 1 if ASM_OUTPUT_DEF is defined.
+ * doc/tm.texi (TARGET_USE_LOCAL_THUNK_ALIAS_P): Document.
+ * config/i386/cygming.h (TARGET_USE_LOCAL_THUNK_ALIAS_P): Define.
+ Set to non-zero iff not a one_only decl.
+
+2004-04-08 Paul Brook <paul@codesourcery.com>
+
+ * arm.h (CLASS_LIKELY_SPILLED_P): Define.
+
+2004-04-08 Paul Brook <paul@codesourcery.com>
+
+ * explow.c (promote_mode): Use PROMOTE_FUNCTION_MODE instead of
+ PROMOTE_FOR_CALL_ONLY.
+ * config/arm/arm-protos.h (arm_function_value): Declare.
+ * config/arm/arm.h (TARGET_PROMOTE_FUNCTION_ARGS): Define.
+ (TARGET_PROMOTE_PROTOTYPES): Return false.
+ (arm_function_value): New function.
+ * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Define.
+ (FUNCTION_VALUE): Call arm_function_value.
+ * config/cris/cris.h (PROMOTE_MODE): Rename ...
+ (PROMOTE_FUNCTION_MODE): ... to this.
+ (PROMOTE_FOR_CALL_ONLY): Remove.
+ * config/mmix/mmix.h: Likewise.
+ * config/s390/s390.h: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/sparc/sparc.c: Update comments about PROMOTE_MODE.
+ * doc/tm.texi (PROMOTE_FUNCTION_MODE): Document.
+ (TARGET_PROMOTE_FUNCTION_MODE, TARGET_PROMOTE_FUNCTION_RETURN): Update.
+ (PROMOTE_FOR_CALL_ONLY): Remove.
+
+2004-04-08 Joel Sherrill <joel@oarcorp.com>
+
+ PR ada/14538
+ * ada/5rosinte.adb: Remove fake mprotect() body.
+ * ada/5rosinte.ads: Add SA_SIGINFO.
+ * ada/5rtpopsp.adb: Rewrite to use new interface.
+ * ada/init.c: Reorder so the simple single OS conditional __rtems__
+ is tested before more complex ones which mix UNIX and embedded
+ systems in the conditional.
+
+2004-04-08 Joel Sherrill <joel@oarcorp.com>
+
+ PR ada/14665
+ * ada/osint.adb (Find_Program_Name): Rework to properly handle
+ filenames which end in .exe or have versioning suffixes like VMS.
+
+2004-04-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/10129
+ * config/darwin.c (darwin_encode_section_info): When the decl has
+ a DECL_INITIAL, it is only defined also when it is not a common.
+
+2004-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_isascii, fold_builtin_toascii): New.
+ (fold_builtin): Handle BUILT_IN_ISASCII and BUILT_IN_TOASCII.
+
+2004-04-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/ia64/ia64.c (ia64_encode_section_info): Don't prod
+ global register variables.
+
+2004-04-07 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * fixinc/inclhack.def (rpc_xdr_lvalue_cast_a,
+ rpc_xdr_lvalue_cast_b): New fixes.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/rpc/xdr.h: Add new tests.
+
+2004-04-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Add MASK_MFCRF
+ to power4 and power5 entries.
+
+2004-04-06 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.h (pending_lang_change): Mark for PCH.
+
+2004-04-07 Caroline Tice <ctice@apple.com>
+
+ * gcc.c (main): Move 'break' in main loops (on an error)
+ to wait until error processing has occurred.
+
+2004-04-06 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Stop changing enable_threads midstream.
+ Replace uses of enable_threads_flag with enable_threads.
+ * configure.ac: Replace uses of enable_threads_flag with
+ enable_threads. Improve autoconf quotation in one place.
+ * configure: Regenerate.
+
+2004-04-06 Uros Bizjak <uros@kss-loka.si>
+
+ * builtins.c: Implement support for sincos function.
+ (expand_builtin_mathfn): Remove BUILT_IN_SIN{,F,L} and
+ BUILT_IN_COS{,F,L}.
+ (expand_builtin_mathfn_3): New function.
+ (expand_builtin): Expand BUILT_IN_SIN{,F,L} and
+ BUILT_IN_COS{,F,L} using expand_builtin_mathfn_3 if
+ flag_unsafe_math_optimization is set.
+
+ * optabs.h (enum optab_index): Add new OTI_sincos.
+ (sincos_optab): Define corresponding macro.
+
+ * optabs.c (init_optabs): Initialize sincos_optab.
+ (expand_twoval_unop): New function.
+
+ * genopinit.c (optabs): Implement sincos_optab using sincos?f3
+ patterns.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_SINCOS_COS
+ and UNSPEC_SINCOS_SIN.
+
+ * config/i386/i386.md (sincosdf3, sincossf3, *sincosextendsfdf3,
+ sincosxf3): New patterns to implement sincos, sincosf and sincosl
+ built-ins as inline x87 intrinsics. Define splits for
+ sindf2, sinsf2, *sinextendsfdf2, sinxf2, cosdf2,
+ cossf2, *cosextendsfdf2 and cosxf2 patterns from corresponding
+ sincos patterns.
+ (sindf2, sinsf2, sinxf2): Rename to *sindf2, *sinsf2, *sinxf2.
+ (cosdf2, cossf2, cosxf2): Rename to *cosdf2, *cossf2, *cosxf2.
+
+ (UNSPEC_SINCOS_SIN, UNSPEC_SINCOS_COS): New unspecs to represent
+ x87's fsincos insn.
+
+2004-04-06 Devang Patel <dpatel@apple.com>
+
+ PR 14467
+ * config/darwin.h (LINK_COMMAND_SPEC): Use c++filt instead of c++filt3.
+
+2004-04-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * doc/install.texi: Update HP-UX 11 installation procedure.
+
+2004-04-06 Paul Brook <paul@codesourcery.com>
+
+ * doc/sourcebuild.texi: Remove obsolete contraint on testcases.
+
+2004-04-05 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (prepare_move_operands): Use emit_call_insn
+ when the TLS address is generated by a function call.
+ * config/sh/sh.md (tls_global_dynamic): Use a call expression.
+ (tls_local_dynamic): Likewise.
+
+2004-04-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree.c (reconstruct_complex_type): Use TYPE_READONLY
+ and TYPE_VOLATILE.
+
+2004-04-05 Caroline Tice <ctice@apple.com>
+
+ * gcc.c (combine_flag): New global variable, for new driver option.
+ (struct compiler): Add two new fields, to be used when
+ combining multiple input files in a single pass (IMA).
+ (default_compilers): Add values for the new fields to all
+ compiler entries. Modify the "@c" compiler entry for doing IMA
+ properly with "-save-temps" and the "combine" flag.
+ (option_map): Add new driver option, "--combine", to tell driver
+ to pass multiple input files to compiler at one time.
+ (have_o_argbuf_index): New global variable.
+ (store_arg): Modify to assign value to have_o_argbuf_index.
+ (struct infile): Add three new fields, to help with IMA.
+ (display_help): Add help for new "combine" option.
+ (process_command): Remove local variable have_o; add code to check
+ for new "combine" option; remove assignment to combine_inputs.
+ (do_spec_1): Modify to deal with IMA better.
+ (main): Make variable 'lang_n_infiles' local to entire function
+ rather than to a single block. Use flag combine_flag to
+ determine whether to do IMA or not; Modify loop initializing
+ infiles to deal properly with linker files.
+ Add code for doing preprocessing in presence of
+ IMA with "-save-temps" flag. Modify "main" loop to handle
+ multiple input files, in multiple languages, with or without
+ preprocessing, gracefully.
+ * toplev.c (set_src_pwd): Modify to not complain if attempting to
+ re-set it to same directory it's previously been set to (avoid
+ irritating, meaningless warning messages when doing IMA with
+ save-temps).
+ * doc/invoke.texi: Add "-combine" to list of Overall Options;
+ remove documentation about IMA that is no longer accurate; Add
+ documentation explaining what "-combine" does.
+ * ada/lang-specs.h: Add initialization values for new fields in
+ "struct compiler".
+ * cp/lang-specs.h: Likewise.
+ * f/lang-specs.h: Likewise.
+ * java/lang-specs.h: Likewise.
+ * objc/lang-specs.h: Likewise.
+ * treelang/lang-specs.h: Likewise.
+
+2004-04-05 David Edelsohn
+
+ * config/rs6000/rs6000.c (VTABLE_NAME_P): Add _ZTI to special
+ symbol handling.
+
+2004-04-05 Jakub Jelinek <jakub@redhat.com>
+ John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/13424 (hppa), bootstrap/14462, c/14828
+ * pa.md: Use replace_equiv_address to retain the attributes of the
+ memory operands used in the split and peephole2 patterns for optimizing
+ the pre-reload movstrsi, movstrdi, clrstrsi and clrstrdi patterns.
+
+2004-04-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * c-decl.c (build_compound_literal): Use TYPE_READONLY.
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
+ * objc/objc-act.c (adorn_decl, gen_declspecs): Likewise.
+ * c-typeck.c (decl_constant_value): Don't access DECL_INITIAL of a
+ PARM_DECL.
+ * calls.c (flags_from_decl_or_type): Use TYPE_READONLY and do so only
+ for a type.
+ * print-tree.c (print_node): Properly handle side-effects, readonly,
+ and constant flags.
+ * tree.c (build1_stat, build_expr_wfl): Only look at TREE_SIDE_EFFECTS
+ and TREE_CONSTANT if not a type.
+ * tree.h (IS_NON_TYPE_CODE_CLASS): New macro.
+ (IS_EXPR_CODE_CLASS): Write 'E', not 'e'.
+ (NON_TYPE_CHECK): New macro.
+ (TREE_SIDE_EFFECT, TREE_READONLY, TREE_CONSTANT: Add check.
+
+2004-04-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sol2-bi.h (PREFERRED_DEBUGGING_TYPE): Set
+ to DWARF2_DEBUG unconditionally.
+ (ASM_DEBUG_SPEC): Set the default to --gdwarf2 unconditionally.
+
+2004-04-04 Ian Lance Taylor <ian@wasabisystems.com>
+ Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR target/14548
+ * config.host: Set the shell variable host_can_use_collect2.
+ Set it to yes by default, and to no for alpha*-dec-*vms*,
+ i[34567]86-*-mingw32*, and powerpc-*-beos*.
+ * configure.ac: Set and substitute the shell variable collect2.
+ Give an error if use_collect2 is yes and host_can_use_collect2 is
+ no.
+ * Makefile.in (COLLECT2): Rename from USE_COLLECT2. Change all
+ uses. Initialize to @collect2@.
+ (STAGESTUFF): Remove $(USE_COLLECT2).
+ * config/alpha/x-vms (USE_COLLECT2): Don't set.
+ * config/i386/t-mingw32 (USE_COLLECT2): Likewise.
+ * config/rs6000/t-beos (USE_COLLECT2): Likewise.
+ * config/pa/t-pa64: Remove commented out USE_COLLECT2.
+ * configure: Regenerate.
+
+2004-04-04 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_binary_operation): Constant fold
+ DIV, MOD, UDIV and UMOD using div_and_round_double.
+
+2004-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14804
+ * varasm.c (initializer_constant_valid_p): Allow NOP_EXPRs to
+ RECORD_TYPEs.
+
+2004-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi (-mabi=o64): Create link to O64 ABI
+ documentation.
+
+2004-04-04 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (cse_insn): Correct usage of simplify_replace_rtx when
+ updating the REG_EQUAL note on an insn's libcall_insn.
+
+2004-04-04 Roger Sayle <roger@eyesopen.com>
+
+ * df.h: Tidy up whitespace in the definitions of the DF_ flags.
+
+2004-04-03 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <PLUS_EXPR>: Guard (-A)+B -> B-A transformation
+ with reorder_operands_p.
+
+2004-04-03 Jan Hubicka <jh@suse.cz>
+
+ * md.texi (vec_set, vec_extract, vec_init): Document.
+
+2004-04-02 Gabor Loki <loki@inf.u-szeged.hu>
+
+ * opts.c (decode_options): Do function inlining with very small
+ max-inline-insns-* parameters when optimizing for size.
+
+2004-04-02 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/i386/i386.h (TARGET_NOCONA): New macro.
+ (TARGET_CPU_CPP_BUILTINS): Add code for Nocona.
+ (processor_type): Add PROCESSOR_NOCONA.
+
+ * config/i386/i386.md (cpu): Add nocona to the attribute values.
+
+ * config/i386/i386.c (nocona_cost): New variable.
+ (m_NOCONA): New macro.
+ (x86_push_memory, x86_movx, x86_cmove, x86_deep_branch,
+ x86_branch_hints, x86_use_sahf, x86_single_stringop,
+ x86_sub_esp_4, x86_sub_esp_8, x86_add_esp_4, x86_add_esp_8,
+ x86_integer_DFmode_moves, x86_partial_reg_dependency,
+ x86_memory_mismatch_stall, x86_accumulate_outgoing_args,
+ x86_decompose_lea, x86_arch_always_fancy_math_387,
+ x86_sse_partial_reg_dependency, x86_sse_load0_by_pxor,
+ x86_ext_80387_constants, x86_four_jump_limit):
+ (override_options): Add nocona_cost to processor_target_table.
+ Set up PROCESSOR_NOCONA for Nocona entry in processor_alias_table.
+ (incdec_operand): Prevent inc/dec generation for Nocona too.
+ (ix86_issue_rate): Add PROCESSOR_NOCONA.
+
+2004-04-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * rtlanal.c (find_reg_note): Manually
+ unswitch the loop.
+
+2004-04-01 Mark Mitchell <mark@codesourcery.com>
+
+ * genemit.c (gen_split): Change prototype of generated code.
+ * genrecog.c (write_action): Adjust prototype for and calls to
+ gen_split_*.
+ * gensupport.c (struct queue_elem): Add split field.
+ (queue_pattern): Return a value. Clear the split field.
+ (process_rtx): Maintain an association between an insn and the
+ split generated from it for a define_insn_and_split.
+ (process_one_cond_exec): Generate a new split for a
+ define_insn_and_split.
+ * config/arm/arm-protos.h (arm_split_constant): Add insn
+ parameter.
+ (emit_constant_insn): New function.
+ (arm_gen_constant): Use it.
+ * config/arm/arm.md: Adjust calls to arm_split_constant.
+
+2004-04-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c: Add overall comment.
+ (cgraph_inline_hash): New global variable.
+ (cgraph_create_node): Break out from ...
+ (cgraph_node): ... here.
+ (cgraph_edge): New function.
+ (cgraph_create_edge): New CALL_EXPR argument; some sanity checking.
+ (cgraph_remove_edge): Accept edge, intead of source and destination.
+ (cgraph_redirect_edge_callee): New.
+ (cgraph_remove_node): Update all new datastructures.
+ (cgraph_record_call, cgraph_remove_call): Kill.
+ (dump_cgraph_node): Break out from ... ; dump new datastructures.
+ (dump_cgraph): ... here.
+ (cgraph_function_possibly_inlined_p): Use new hashtable.
+ (cgraph_clone_edge, cgraph_clone_node): New.
+ * cgraph.h: Include hashtab.h
+ (struct cgraph_global_info): Kill cloned_times, inline_once, will_be_output
+ fields, add inlined_to pointer.
+ (cgraph_node): Add pointer to next_clone.
+ (cgraph_remove_edge, cgraph_create_edge): Update prototype.
+ (cgraph_remove_call, cgraph_record_call): Kill.
+ (cgraph_inline_hash): Declare.
+ (dump_cgraph_node, cgraph_edge, cg4raph_clone_edge, cgraph_clone_node,
+ cgraph_redirect_edge_callee): Declare.
+ (cgraph_create_edges, cgraph_inline_p): Update prorotype.
+ (cgraph_preserve_function_body_p, verify_cgraph, verify_cgraph_node,
+ cgraph_mark_inline_edge, cgraph_clone_inlined_nodes): Declare.
+ * cgraphunit.c: Add overall comment.
+ (cgraph_optimize_function): Kill.
+ (cgraph_assemble_pending_functions): Do not assemble inline clones.
+ (cgraph_finalize_function): Update call of cgraph_remove_node
+ (record_call_1): Record call sites.
+ (cgraph_create_edges): Accept node instead of decl argument.
+ (error_found): New static variable.
+ (verify_cgraph_node_1, verify_cgraph_node, verify_cgraph): New functions.
+ (cgraph_analyze_function): Update for new datastructures.
+ (cgraph_finalize_compilation_unit): Plug memory leak.
+ (cgraph_optimize_function): Kill.
+ (cgraph_expand_function): Do not use cgraph_optimize_function.
+ (INLINED_TIMES, SET_INLINED_TIMES, cgraph_inlined_into,
+ cgraph_inlined_callees): Kill.
+ (cgraph_remove_unreachable_nodes): Verify cgraph; update handling of
+ clones.
+ (estimate_growth): Simplify.
+ (cgraph_clone_inlined_nodes): New function.
+ (cgraph_mark_inline_edge): Re-implement.
+ (cgraph_mark_inline): Likewise.
+ (cgraph_check_inline_limits): Simplify.
+ (cgraph_recursive_inlining_p): New.
+ (update_callee_keys): Break out from ...
+ (cgraph_decide_inlining_of_small_functions): ... here; simplify.
+ (cgraph_decide_inlining, cgraph_decide_inlining_incrementally):
+ Likewise.
+ (cgraph_expand_all_functions): Remove inline clones from the ordered
+ list.
+ (cgraph_preserve_function_body_p): New predicate.
+ (cgraph_optimize): Verify cgraph.
+ * function.h (struct function): Add fields saved_tree/saved_args.
+ * timevar.def (TV_CGRAPH_VERIFY): Use verifier.
+ * toplev.c (rest_of_compilation): Do not free cfun.
+ * tree-inline.c: Include function.h
+ (struct inline_data): Add saving_p field; replace decl/current_decl by
+ node/current_node.
+ (insert_decl_map): New function.
+ (copy_body_r): Handle saving; update cgraph datastructure.
+ (copy_body): Handle recursive inlining.
+ (initialize_inlined_parameters): Likewise.
+ (expand_call_inline): Propagate node attributes; update cgraph.
+ (optimize_inline_calls): Verify that datastructure still match.
+ (save_body): New function.
+ * tree-inline.h (save_body): New.
+ * tree-optimize.c (tree_rest_of_compilation): preserve function body; do inlining.
+ * langhooks-def.c (LANG_HOOKS_UPDATE_DECL_AFTER_SAVING): New.
+ * langhooks.c (lang_hooks): Add update_decl_after_saving.
+
+2004-04-01 Serge Belyshev <1319@bot.ru>
+
+ PR target/14702
+ * config/i386/i386.md: fix source operand constraints in
+ mmx_pshufw, sse2_pshufd, sse2_pshuflw, sse2_pshufhw
+
+2004-04-01 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * fold-const.c (folda): Preserve types of comparisons.
+
+2004-04-01 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (backend_init): Move init_optimization_passes call ...
+ (lang_dependent_init): ... here.
+
+2004-04-01 Alan Modra <amodra@bigpond.net.au>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.c (init_gcc_specs): If HAVE_LD_AS_NEEDED, link with
+ -lgcc --as-needed -lgcc_s --no-as-needed by default.
+ * configure.ac (HAVE_LD_AS_NEEDED): Check for ld --as-needed.
+ * configure: Rebuilt.
+ * config.in: Rebuilt.
+ * Makefile.in (stage1-start): Copy also libgcc_s*$(SHLIB_EXT).
+ (stage2-start, stage3-start, stage4-start): Likewise.
+ (stageprofile-start, stagefeedback-start): Likewise.
+
+2004-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.h (DITF_CONVERSION_LIBFUNCS): Define to 0.
+ * config/sparc/linux.h (DITF_CONVERSION_LIBFUNCS): Redefine to 1.
+ * config/sparc/linux64.h (DITF_CONVERSION_LIBFUNCS): Redefine to 1.
+ * config/sparc/sol2.h (DITF_CONVERSION_LIBFUNCS): Redefine to 1.
+ (SOLARIS_CONVERSION_LIBFUNCS): Rename to SUN_CONVERSION_LIBFUNCS.
+ * config/sparc/sparc.c (sparc_init_libfuncs): Initialize optabs
+ with _Q_qtoll, _Q_qtoull and _Q_lltoq if DITF_CONVERSION_LIBFUNCS.
+ * config.gcc (sparc-*-linux*): Revert 2004-03-23 change.
+ * config/sparc/t-linux64 (TARGET_LIBGCC2_CFLAGS): Likewise.
+ * config/sparc/t-linux: Removed.
+
+2004-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/14755
+ * fold-const.c (fold) <EQ_EXPR>: Properly compute newconst in
+ "bitfld++ == const" to "++bitfld == const + incr" transformations.
+
+2004-04-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (get_inner_reference): Use DECL_UNSIGNED, not TREE_UNSIGNED.
+ * stor-layout.c (layout_decl): Likewise.
+ * tree.c (get_narrower): Likewise and also use BIT_FIELD_REF_UNSIGNED.
+ * fold-const.c (make_bit_field_ref): Use BIT_FIELD_REF_UNSIGNED.
+ * print-tree.c (print_node): Handle various used of unsigned_flag.
+ * tree.def (BIT_FIELD_REF): Update comment.
+ * tree.h (TREE_UNSIGNED): Deleted.
+ (DECL_UNSIGNED, BIT_FIELD_REF_UNSIGNED): New macros.
+
+2004-03-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * builtins.c, c-aux-info.c, c-common.c, c-cppbuiltin.c, c-decl.c:
+ Change most occurrences of TREE_UNSIGNED to TYPE_UNSIGNED.
+ * c-format.c, c-opts.c, c-pretty-print.c, c-typeck.c: Likewise.
+ * calls.c, convert.c, dbxout.c, dojump.c, dwarf2out.c: Likewise.
+ * expmed.c, expr.c, fold-const.c, function.c, integrate.c: Likewise.
+ * optabs.c, sdbout.c, stmt.c, stor-layout.c, tree-dump.c: Likewise.
+ * tree.c, config/iq2000/iq2000.c, config/m32r/m32r.c: Likewise.
+ * config/mips/mips.c, config/rs6000/rs6000.c: Likewise.
+ * config/s390/s390.c, config/sparc/sparc.c, objc/objc-act.c: Likewise.
+ * stor-layout.c (layout_type, case COMPLEX_TYPE): Test for
+ REAL_TYPE, not INTEGER_TYPE.
+ (layout_type, case VECTOR_TYPE): Simplify code.
+ * tree.c (build_vector_type_for_mode): Remove dup unsigned setting.
+ * tree.h: Update comments.
+ (STRIP_NOPS): Use TYPE_UNSIGNED.
+ (TYPE_UNSIGNED): New macro.
+ (TYPE_TRAP_SIGNED): Remove now redundant check.
+ (SAVE_EXPR_NOPLACEHOLDER): Don't use TREE_UNSIGNED.
+
+2004-03-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * function.c (put_var_into_stack): Properly set orig_reg for indirect.
+
+2004-03-31 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/t-darwin (LIB2FUNCS_STATIC_EXTRA):
+ Add darwin-fpsave.asm, darwin-vecsave.asm,
+ and darwin-world.asm.
+ (TARGET_LIBGCC2_CFLAGS): Add -Wa,-force_cpusubtype_ALL
+ as the asm files contain altivec instructions.
+ * config/rs6000/darwin-fpsave.asm: New file.
+ * config/rs6000/darwin-vecsave.asm: New file.
+ * config/rs6000/darwin-world.asm: New file.
+
+2004-03-31 Zack Weinberg <zack@codesourcery.com>
+
+ * gengtype-yacc.y (option, stringseq): Add missing
+ terminating semicolon.
+
+2004-03-30 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (tls_gd_32, tls_gd_64,
+ tls_ld_32, tls_ld_64, tls_dtprel_32, tls_dtprel_64,
+ tls_dtprel_ha_32, tls_dtprel_ha_64,
+ tls_dtprel_lo_32, tls_dtprel_lo_64,
+ tls_got_dtprel_64, tls_tprel_32, tls_tprel_64,
+ tls_tprel_ha_32, tls_tprel_ha_64,
+ tls_tprel_lo_32, tls_tprel_lo_64,
+ tls_got_tprel_32, tls_got_tprel_64,
+ tls_tls_32, tls_tls_64): Replace register_operand with
+ gpc_reg_operand.
+
+2004-03-30 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * config/rs6000/rs6000.md (*ctrsi_internal1, *ctrsi_internal2,
+ *ctrdi_internal1, *ctrdi_internal2, *ctrsi_internal3,
+ *ctrsi_internal4, *ctrdi_internal3, *ctrdi_internal4,
+ *ctrsi_internal5, *ctrsi_internal6, *ctrdi_internal5,
+ *ctrdi_internal6): Replace register_operand with
+ nonimmediate_operand.
+
+2004-03-29 Fariborz Jahanian <fjahanian@apple.com>
+
+ * fold-const.c (fold): Reassociate multiply expression
+ with an adjacent non-multiply expression to use
+ architecture's multiply-add instruction.
+
+2004-03-30 Zack Weinberg <zack@codesourcery.com>
+
+ * gengtype.c (create_option): New function.
+ * gengtype.h: Prototype it.
+ * gengtype-yacc.y (stringseq): New rule.
+ (option): Use create_option. Add new bare ID production. Use
+ stringseq, not STRING directly.
+
+ * alias.c, bitmap.c, c-decl.c, cgraph.h, cpplib.h, cselib.h
+ * dwarf2out.c, emit-rtl.c, function.h, lists.c, tree.h
+ * varray.h, config/alpha/alpha.c:
+ Use new shorter form of GTY markers.
+
+ * doc/gty.texi: Rewrite.
+
+2004-03-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/darwin.c (machopic_function_base_name):
+ Remove current_name and getting the name of the
+ current function.
+
+2004-03-30 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.md (thumb_jump): Reduce the backward branch
+ range, and increase the forward branch range, to allow for
+ the fact that the PC will be off by 4.
+
+2004-03-30 Alan Modra <amodra@bigpond.net.au>
+
+ * .cvsignore: Add GPATH, GRTAGS, GSYMS and GTAGS (GNU GLOBAL)
+
+2004-03-30 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/rs6000/rs6000.c (output_vec_const_move):
+ Find all cases of EASY_VECTOR_15_ADD_SELF.
+ (easy_vector_constant_add_self): Accept
+ all vector constant loadable by vsplt* and vadd*.
+ (easy_vector_same): Use easy_vector_splat_const.
+ (easy_vector_const): Use easy_vector_splat_const.
+ (easy_vector_splat_const): New function.
+ (gen_easy_vector_constant_add_self): New function.
+
+ * config/rs6000/rs6000-protos.c (gen_easy_vector_constant_add_self):
+ New prototype.
+
+ * config/rs6000/altivec.md (movv4si splitter): Change to
+ emit move insn with halfed vector constant.
+ (*movv8hi splitter): Likewise.
+ (*movv16qi splitter): Likewise.
+
+2004-03-30 Hartmut Penner <hpenner@de.ibm.com>
+
+ PR 11591
+ * config/rs6000/rs6000.c (rs6000_legitimate_address):
+ Allow any offset to argument pointer in no-strict case.
+
+2004-03-30 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (backend_init): Add missing call to inint_optimization_passes.
+ * passes.c (init_optimization_passes, finish_optimization_passes): Output cgraph
+ dump file in non-unit-at-a-time mode.
+
+2004-03-29 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/cris.h: Correct #ifdef to test for
+ HAVE_AS_NO_MUL_BUG_ABORT_OPTION, not
+ HAVE_AS_MUL_BUG_ABORT_OPTION.
+
+2004-03-29 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * function.c (put_var_into_stack): If old RTL was ADDRESSOF, update
+ the address inside the old RTL.
+
+2004-03-28 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c: Verify that C_SIZEOF_STRUCT_LANG_IDENTIFIER is correct.
+ (struct c_binding, struct c_scope): Add chain_next
+ attributes to GTY markers.
+ (struct lang_identifier, struct lang_tree_node): Define
+ here...
+ * c-tree.h: ... not here. No longer need to declare struct
+ c_binding either. Do define C_SIZEOF_STRUCT_LANG_IDENTIFIER.
+ * c-lang.c, objc/objc-lang.c: Set LANG_HOOKS_IDENTIFIER_SIZE
+ to C_SIZEOF_STRUCT_LANG_IDENTIFIER.
+
+ PR 14734, 11944
+ * c-decl.c (get_parm_info): If error_mark_node is encountered
+ in the bindings chain, unbind and discard it; don't abort.
+
+2004-03-28 Olga Golovonevsky <olga@il.ibm.com>
+ Dorit Naishlos <dorit@il.ibm.com>
+
+ * config/rs6000/altivec.md: (andvv16qi3, andv8hi3, one_cmplv16qi2,
+ one_cmplv8hi2, one_cmplv4si2, iorv16qi3, iorv8hi3,): New modelling.
+
+2004-03-28 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11-protos.h (m68hc11_page0_symbol_p): Declare.
+
+ * config/m68hc11/m68hc11.c (m68hc11_handle_page0_attribute): New.
+ (m68hc11_attribute_table): New attribute "page0" to mark a global
+ variable as being allocated from within page0 section.
+ (m68hc11_encode_label): New function.
+ (m68hc11_strip_name_encoding): New function.
+ (m68hc11_page0_symbol_p): New function.
+ (m68hc11_indirect_p): Accept global variables marked in page0.
+ (m68hc11_encode_section_info): Lookup "page0" attribute.
+
+ * config/m68hc11/m68hc11.h (EXTRA_CONSTRAINT): 'R' constraint also
+ represents access to page0 variables.
+
+ * config/m68hc11/m68hc11.md ("*logicalsi3_zexthi"): Use gen_rtx_REG.
+ ("*logicalsi3_silshl16_zext"): Likewise.
+ ("*ashldi3_const32"): Likewise.
+ (peephole2 ashift): Likewise.
+
+2004-03-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-tree.h (C_DECL_REGISTER): New.
+ * c-aux-info.c (gen_decl), c-decl.c (objc_mark_locals_volatile,
+ finish_decl, grokdeclarator, get_parm_info), c-typeck.c
+ (build_array_ref, c_mark_addressable): Set and use it.
+ * c-decl.c (grokdeclarator), c-typeck.c (c_mark_addressable):
+ Allow structures with volatile fields to be declared register.
+ Don't check TREE_ADDRESSABLE before warning about taking address
+ of register.
+ * c-decl.c (finish_decl): Don't allow structures with volatile
+ fields to be placed in named register.
+ * doc/trouble.texi: Remove reference to structures with volatile
+ fields in registers.
+
+2004-03-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * function.c (thread_prologue_and_epilogue): Move
+ NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG notes
+ before the epilogue.
+
+2004-03-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * expr.c (store_constructor): Use gen_int_mode to correctly
+ sign-extend CONST_INT value.
+
+2004-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_WINT, BT_FN_INT_WINT, BT_FN_WINT_WINT): New.
+ * builtins.def (DEF_C94_BUILTIN): New. Add wctype builtins.
+ * doc/extend.texi: Likewise.
+
+2004-03-26 Diego Novillo <dnovillo@redhat.com>
+
+ * c-typeck.c (comptypes): Replace calls to TYPE_DOMAIN
+ with TYPE_ORIG_SIZE_TYPE.
+
+2004-03-25 Aldy Hernandez <aldyh@redhat.com>
+
+ PR 14219
+ * c-typeck.c (build_binary_op): Do not allow comparisons of
+ vectors.
+
+2004-03-26 James A. Morrison <ja2morri@uwaterloo.ca>
+
+ * config.gcc: Remove sparc-tti-*.
+ * config/sparc/pbd.h: Delete.
+
+ * config/sparc/sol2.h: Remove note about Sun OS 4.x.
+ * config/sparc/aout.h: Likewise.
+
+ * config/sparc/sparc.h: Remove if 0'd code.
+ * config/sparc/sparc.md (call): Remove if 0'd code.
+ (call_value): Likewise.
+ (nonlocal_goto): Likewise.
+ (unimp_insn): Delete.
+
+2004-03-25 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (tree_expr_nonnegative_p): Handle BIT_XOR_EXPR like
+ BIT_IOR_EXPR; A^B is nonnegative when A and B are nonnegative.
+
+2004-03-25 Richard Henderson <rth@redhat.com>
+
+ PR 11527
+ * c-typeck.c (pop_init_level): Emit pending init elements earlier
+ rather than later.
+
+2004-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin): Fix error in last change.
+
+2004-03-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h: Formatting fix.
+
+2004-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Add ctype builtins.
+ * doc/extend.texi: Likewise.
+
+2004-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin): Add new builtin optimizations for
+ sqrt and/or cbrt.
+ * fold-const.c (fold): Likewise.
+
+2004-03-25 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_always_hint): New variable.
+ (rs6000_sched_groups): New variable.
+ (processor_target_table): Add power5.
+ (rs6000_override_options): Set rs6000_sched_insert_nops,
+ rs6000_sched_costly_dep and rs6000_sched_restricted_insns_priority
+ from rs6000_sched_groups.
+ (output_cbranch): Use rs6000_always_hint.
+ (rs6000_variable_issue): Use rs6000_sched_groups.
+ (rs6000_adjust_cost): Add CPU_POWER5.
+ (is_microcoded_insn): Use rs6000_sched_groups.
+ (is_dispatch_slot_restricted): Use rs6000_sched_groups.
+ Return 2 for POWER5 cracked instructions.
+ (is_cracked_insn): Use rs6000_sched_groups.
+ (is_branch_slot_insn): Use rs6000_sched_groups.
+ (rs6000_issue_rate): Add CPU_POWER5.
+ (rs6000_sched_finish): Use rs6000_sched_groups.
+ (rs6000_rtx_costs): Add PROCESSOR_POWER5.
+ * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_POWER5.
+ (DEFAULT_SCHED_COSTLY_DEP): Delete.
+ (DEFAULT_RESTRICTED_INSNS_PRIORITY): Delete.
+ (DEFAULT_SCHED_FINISH_NOP_INSERTION_SCHEME): Delete.
+ * config/rs6000/rs6000.md (define_attr "cpu"): Add power5.
+ * config/rs6000/power5.md: New file.
+ * doc/invoke.texi: Add power5 option.
+
+2004-03-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cfgrtl.c, dbxout.c, tree.def, config/darwin.h,
+ config/arm/arm.c, objc/objc-act.c: Fix comment typos.
+ * doc/invoke.texi: Fix a typo.
+
+2004-03-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR optimization/9707.
+ * stmt.c (emit_case_nodes): Emit equality comparisons instead
+ of recursing if both children are single-valued cases with no
+ children.
+
+2004-03-25 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (vfp_print_multi): Remove.
+ (arm_output_fldmx): New function.
+ (vfp_emit_fstmx): Return block size, not insn. Add ARM10 VFPr1 bugfix.
+ (arm_expand_prologue): Update to match.
+ (arm_get_vfp_saved_size): New Function.
+ (arm_get_frame_offsets): Use it.
+ (arm_output_epilogue): Use new functions.
+
+2004-03-24 Richard Henderson <rth@redhat.com>
+
+ * alias.c (alias_invariant, alias_invariant_size): Mark GTY.
+ (reg_known_value, reg_known_value_size): Likewise; make static.
+ (reg_known_equiv_p): Make static.
+ (clear_reg_alias_info): Update for new indexing.
+ (get_reg_known_value, set_reg_known_value): New.
+ (get_reg_known_equiv_p, set_reg_known_equiv_p): New.
+ (canon_rtx): Use them.
+ (init_alias_analysis): Likewise. Allocate reg_known_value with gc.
+ Don't play queer offsetting games with reg_known_value and
+ reg_known_equiv_p.
+ (end_alias_analysis): Free reg_known_value with gc.
+ * rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
+ * sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
+ (deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
+ functions instead.
+
+2004-03-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dwarf2asm.c, loop.h, pretty-print.c, pretty-print.h,
+ config/i386/mmintrin.h: Update copyright.
+
+2004-03-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Add --enable-werror-always (for top level bootstrap
+ support).
+ * configure: Regenerate.
+
+2004-03-24 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (objc_comptypes): Treat comparisons
+ between 'Class' and '<class> *' as explicitly invalid.
+
+2004-03-24 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/invoke.texi (-frename-registers): Add enabled at -O3.
+ (-fprofile-values): Add enabled with profile-{generate,use}.
+ (-fvpt): Same.
+ (-ftracer): Add enabled with profile-use.
+ (-funit-at-a-time): Add enabled at -O2,-O3.
+ (-funroll-loops): Add enabled with profile-use.
+ (-funswitch-loops): Add enabled with profile-use. Remove duplicates.
+ (max-gcse-passes): Mention default.
+ (max-cse-path-length): Mention default.
+
+2004-03-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in (STRICT2_WARN): Reorder.
+ * configure.ac: Check for -Wold-style-definition, and use it
+ in strict1_warn if it's available.
+ * configure: Regnerate.
+
+2004-03-24 Paul Brook <paul@nowt.org>
+
+ * config.gcc <arm>: Add --with-abi=
+ * config/arm/arm-protos.h (arm_get_frame_size, thumb_get_frame_size,
+ thumb_far_jump_used): Remove prototypes.
+ (arm_needs_doubleword_align): Add prototype.
+ (thumb_compute_initial_elimination_offset): Ditto.
+ * config/arm/arm.c (arm_get_frame_offsets): New function.
+ (use_return_insn, output_return_instruction, arm_output_epilogue,
+ arm_output_function_epilogue, arm_compute_initial_elimination_offset,
+ arm_expand_prologue, thumb_expand_epilogue): Use it.
+ (arm_abi, target_abi_name, all_arm_abis): New variables.
+ (arm_override_options): Set them. Set structure padding for AAPCS.
+ (arm_return_in_memory): Update ABI check.
+ (arm_init_cumulative_args): Initialize can_split.
+ (arm_needs_doubleword_align): New function.
+ (arm_function_arg): Don't split args after pushing to stack. Handle
+ doubleword/even reg alignment.
+ (arm_va_arg): Handle all doubleword aligned args.
+ (add_minpoolforward ref, dump_minpool, push_minpool_fix): Align based
+ on ABI, not CPU.
+ (arm_compute_save_reg0_reg12_mask): Fix comment.
+ (thumb_get_frame_size, thumb_get_frame_size): Remove.
+ (thumb_jump_far_used_p): Remove superfluous argument. Return save
+ value for alignment.
+ (thumb_unexpanded_epilogue, thumb_output_function_prologue): Change
+ to match.
+ (thumb_compute_initial_elimination_offset): New function.
+ (thumb_expand_prologue): Use arm_get_frame_offsets. Remove
+ unneccessary rounding.
+ * config/arm/arm.h (target_abi_name): Declare.
+ (ARM_DOUBLEWORD_ALIGN, DOUBLEWORD_ALIGNMENT, TARGET_IWMMXT_ABI,
+ arm_abi_type, ARM_DEFAULT_ABI): Define.
+ (ARM_FLAG_ATPCS): Remove.
+ (TARGET_OPTIONS, OPTION_DEFAULT_SPECS): Add -mabi=.
+ (BIGGEST_ALIGNMENT, PREFERRED_STACK_BOUNDARY, STACK_BOUNDARY): Use it.
+ (ADJUST_FIELD_ALIGN, DATA_ALIGNMENT, LOCAL_ALIGNMENT,
+ TYPE_NEEDS_IWMMXT_ALIGNMENT): Remove.
+ (LIBCALL_VALUE, FUNCTION_VALUE_REGNO_P, FUNCTION_ARG_REGNO_P):
+ Contitionalize on ABI, not CPU.
+ (struct arm_stack_offsets): Define.
+ (struct machine_function): Add stack_offsets. Remove frame_size.
+ (FUNCTION_ARG_PARTIAL_NREGS): Don't split if previous args have been
+ pushed.
+ (FUNCTION_ARG_ADVANCE, FUNCTION_ARG_BOUNDARY): Handle general
+ doubleword alignment.
+ (THUMB_INITIAL_ELIMINATION_OFFSET,
+ ARM_INITIAL_ELIMINATION_OFFSET): Remove.
+ (INITIAL_ELIMINATION_OFFSET): Call functions directly.
+ * config/arm/arm.md (align_8): Enable for all targets.
+ * config/arm/netbsd-elf.h (TARGET_DEFAULT): Remove TARGET_ATPCS.
+ (ARM_DEFAULT_ABI): Define.
+ * doc/invoke.texi <ARM>: Document -mabi=. Update documentation for
+ -mstructure-size-boundary.
+
+2004-03-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Check for -Wno-variadic-macros; don't use
+ -pedantic (in stage 1 or a simple 'make all') unless it's available,
+ and if it's available, use it. Also, clean up check for
+ -Wno-long-long.
+ * configure: Regenerate.
+
+2004-03-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config.gcc (mips64vr-*-elf*, mips64vrel-*-elf*): Remove tm_defines.
+ * config/mips/vr.h (DEFAULT_VR_ARCH): New macro, defined to vr4130.
+ (MULTILIB_DEFAULTS): Use it.
+ (MIPS_CPU_STRING_DEFAULT): Remove.
+ (MIPS_ABI_DEFAULT, MIPS_MARCH_CONTROLS_SOFT_FLOAT): Define.
+ (DRIVER_SELF_SPECS): Make -mfix-vr4122-bugs imply -march=vr4120. Make
+ EABI64 -mlong32 the default ABI. Enforce the default architecture.
+ * config/mips/t-vr (MULTILIB_OPTIONS): Add mfix-vr4122-bugs,
+ march=vr4130, march=vr4300, march=vr5000 and march=vr5500.
+ (MULTILIB_MATCHES): Use -mfix-vr4122-bugs multilibs for -march=vr4120.
+ (MULTILIB_EXCEPTIONS): Change choice of multilibs. Update comments
+ accordingly.
+
+2004-03-24 DJ Delorie <dj@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MASK_FIX_VR4122, TARGET_FIX_VR4122): New macros.
+ (TARGET_SWITCHES): Add -mfix-vr4122-bugs and -mno-fix-vr4122-bugs.
+ (ASM_SPEC): Pass down -mfix-vr4122-bugs.
+ * config/mips/mips.c (mips_avoid_hazards): Don't emit whole functions
+ in .set noreorder and .set nomacro if TARGET_FIX_VR4122.
+ (mips_init_libfuncs): Use special functions for divsi3 and modsi3
+ if TARGET_FIX_VR4122.
+ * config/mips/mips.md (define_attr length): Account for nops inserted
+ after macc and dmult when using -mfix-vr4122-bugs.
+ (umuldi3_highpart, divmodsi4, divmoddi4): Disable if TARGET_FIX_VR4122.
+ * config/mips/t-vr (LIB2FUNCS_STATIC_EXTRA): Define instead of
+ LIB2FUNCS_EXTRA. Add config/mips/vr4122-div.S.
+ * config/mips/vr4122-div.S: New file.
+ * doc/invoke.texi: Document -mfix-vr4122-bugs.
+
+2004-03-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R4130): New processor_type.
+ (TARGET_MIPS4130): New macro.
+ (ISA_HAS_MACC): Return true if TARGET_MIPS4130 && !TARGET_MIPS16.
+ * config/mips/mips.c (mips_cpu_info_table): Add a vr4130 entry.
+ (override_options): Extend MIPS_MARCH_CONTROLS_SOFT_FLOAT to deal
+ with PROCESSOR_R4130.
+ * config/mips/mips.md (define_attr cpu): Add r4130.
+ * doc/invoke.texi: Document vr4130 as a supported MIPS architecture.
+
+2004-03-24 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Apply missed hunk from 2004-03-03 change.
+
+2004-03-24 Alexandre Oliva <aoliva@redhat.com>
+
+ PR preprocessor/14438
+ * cpplib.c (do_pragma): Remove line_change call after pragma
+ handler.
+
+2004-03-23 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * doc/extend.texi (ARM Built-in Functions): Replace with correct
+ declarations.
+
+2004-03-23 Roger Sayle <roger@eyesopen.com>
+
+ * reg-stack.c (get_true_reg): Handle FLOAT_TRUNCATE like FLOAT_EXTEND
+ if flag_unsafe_math_optimizations.
+ * config/i386/i386.md (truncdfsf2): If flag_unsafe_math_optimizations
+ and TARGET_80387 expand using truncdfsf2_noop pattern.
+ (truncxfsf2): Likewise using truncxfsf2_noop.
+ (truncxfdf2): Likewise using truncxfdf2_noop.
+ (truncdfsf2_noop, truncxfsf2_noop, truncxfdf2_noop): New patterns.
+
+2004-03-23 Ziemowit Laski <zlaski@apple.com>
+
+ * hooks.c (hook_constcharptr_tree_null): New hook.
+ * hooks.h (hook_constcharptr_tree_null): New prototype.
+ * target-def.h (TARGET_MANGLE_FUNDAMENTAL_TYPE): New target hook.
+ * target.h (mangle_fundamental_type): New target hook.
+ * config/rs6000/rs6000.c (TARGET_MANGLE_FUNDAMENTAL_TYPE): Point
+ target hook at rs6000_mangle_fundamental_type.
+ (rs6000_mangle_fundamental_type): New function.
+ * doc/tm.texi (TARGET_MANGLE_FUNDAMENTAL_TYPE): Document.
+
+2004-03-23 Zack Weinberg <zack@codesourcery.com>
+
+ PR 12267, 12391, 12560, 13129, 14114, 14133
+ * c-tree.h: Forward declare struct c_binding. Declare
+ c_override_bindings_to_false. Update prototypes.
+ (struct lang_identifier): Update comments. Change fields to be
+ struct c_binding *.
+ (IDENTIFIER_SYMBOL_VALUE, IDENTIFIER_TAG_VALUE)
+ (IDENTIFIER_LABEL_VALUE, C_DECL_INVISIBLE)
+ (KEEP_NO, KEEP_YES, KEEP_MAYBE): Delete.
+ (C_DECL_IN_EXTERNAL_SCOPE, C_DECL_DECLARED_BUILTIN): New.
+ * c-common.h: Update prototypes.
+ * c-decl.c (struct c_scope): Update commentary. Remove names,
+ names_last, parms, parms_last, tags, and shadowed fields. Add
+ bindings and depth fields.
+ (scope_freelist): Move to more appropriate location.
+ (c_print_identifier): Update for changes to struct lang_identifier.
+ (objc_mark_locals_volatile): Update for new bindings structures.
+ (global_bindings_p): Honor c_override_global_bindings_to_false.
+ (pushlevel): Rename to push_scope; take no arguments; use the
+ scope_freelist; initialize scope->depth and check for overflow.
+ (poplevel): Rename to pop_scope; totally rewritten for new bindings
+ structures.
+ (diagnose_mismatched_decls): Use C_DECL_DECLARED_BUILTIN, not
+ C_DECL_INVISIBLE, for certain decisions. Adjust some diagnostics.
+ Improve some commentary. Adjust handling of forward parm decls.
+ (merge_decls): Set C_DECL_DECLARED_BUILTIN when appropriate.
+ Preserve C_DECL_IN_EXTERNAL_SCOPE.
+ (warn_if_shadowing): Correct indentation. Improve diagnostics.
+ (pushdecl): Remove unnecessary assertion. Short-circuit anonymous
+ decls. Rewrite for new bindings structures. Improve commentary.
+ Eliminate the copy_node call.
+ (implicit_decl_warning): Use the "diag" idiom (as seen in
+ locate_old_decl) to reduce code duplication; call locate_old_decl
+ if appropriate. Relocate to remove need for forward declaration.
+ (implicitly_declare): Adjust for new bindings structures. Kludge
+ around Objective-C not-really-builtin functions.
+ (undeclared_variable): Improve diagnostics. If current_function_decl
+ is nonnull but current_function_scope is null, use current_scope.
+ Use bind.
+ (lookup_tag): Adjust for new bindings structures. Kludge around
+ Objective-C's tag declarations that wind up in the external scope.
+ (lookup_name): Adjust for new bindings structures. Kludge around
+ c-common.c's pseudo-typedefs that wind up in the external scope.
+ (lookup_name_current_level): Rename lookup_name_in_scope; take a
+ second argument indicating the scope to examine; rewrite for
+ new bindings structures.
+ (c_init_decl_processing): Adjust for renamed functions. Do not
+ initialize current_file_decl, first_builtin_decl, last_builtin_decl.
+ First scope pushed is the external scope, not the global scope.
+ (builtin_function): Use bind, not pushdecl. Adjust other bits
+ for new data structures. Keep track of builtins that should be
+ made visible automatically.
+ (start_decl): Adjust diagnostics. Remove unnecessary call to
+ expand_decl.
+ (grokparms): Return 0 if arg_types is error_mark_node.
+ (get_parm_info): Rename "void_at_end" argument to "ellipsis", with
+ reversed sense. Rewrite for new bindings structures. Do not
+ leave any decls in the scope, to prevent pop_scope from doing
+ contradictory things with them.
+ (finish_struct, finish_enum): Remove redundant diagnostics.
+ (build_enumerator): Don't cascade diagnostics for error_mark_node.
+ Mark location where -pedantic changes the meaning of the program.
+ (store_parm_decls_newstyle, store_parm_decls_oldstyle): Load the
+ parameter decls into the function's scope structure using bind.
+ Warn here about function definitions in the wrong style.
+ Adjust diagnostics.
+ (store_parm_decls): Correct the determination of whether a
+ function was defined with a prototype.
+ (c_write_global_declarations): Operate on all file decls and on
+ the external scope. Split body of the loop to...
+ (c_write_global_declarations_1): ... this new function, to avoid
+ code duplication.
+ (truly_local_externals, first_builtin_decl, last_builtin_decl)
+ (make_scope, pop_scope, in_parm_level_p, set_block)
+ (any_external_decl, record_external_decl, bind_label, getdecls)
+ (link_hash_hash, link_hash_eq, merge_translation_unit_decls)
+ (c_reset_state): Delete.
+ (visible_builtins, c_override_global_bindings_to_false)
+ (c_binding, I_SYMBOL_BINDING, I_SYMBOL_DECL, I_TAG_BINDING)
+ (I_TAG_DECL, I_LABEL_BINDING, I_LABEL_DECL, file_scope)
+ (external_scope, binding_freelist, bind, free_binding_and_advance)
+ (push_file_scope, pop_file_scope): New.
+ (pushtag, pushdecl_top_level, lookup_label, declare_label)
+ (define_label, c_make_fname_decl, finish_decl)
+ (mark_forward_parm_decls, build_compound_literal)
+ (grokdeclarator, start_function, check_for_loop_decls)
+ (identifier_global_value, record_builtin_type): Minor adjustments
+ for new bindings structures. Improve diagnostics and commentary.
+ * c-objc-common.c (start_cdtor, finish_cdtor): Adjust calls to
+ pushlevel/poplevel respectively.
+ (c_objc_common_finish_file): Don't call merge_translation_unit_decls.
+ * c-opts.c (c_common_parse_file): Remove spurious ATTRIBUTE_UNUSED.
+ Warn about YYDEBUG not being defined only if -dy. Remove no-longer-
+ correct loop over multiple translation units; call fatal_error if
+ requested to compile more than one file at once. (This disables
+ IMA temporarily - an up-front error being preferable to a crash.)
+ * c-parse.in (pushlevel, poplevel rules): Rename push_scope, pop_scope.
+ (all actions): Adjust calls to pushlevel/poplevel.
+ (parsing_iso_function_signature): Delete.
+ (extdef_1): Fold into extdef.
+ (old_style_parm_decls_1): Fold into old_style_parm_decls. Don't
+ warn here about function definitions in the wrong style.
+ (after_tyle_declarator, parm_declarator_starttypename)
+ (parm_declarator_nostarttypename, notype_declarator): Remove
+ commented-out productions.
+ (parmlist_1, parmlist_2): Use make_node, not tree_cons, to create
+ an empty TREE_LIST node. Adjust calls to get_parm_info.
+ (parmlist_2 : ELLIPSIS): Tag the arg-info block with error_mark_node
+ to suppress -Wold-style-definition after this error.
+ (c_parse_file): Don't clear the binding stack or call
+ finish_fname_decls here. Correct comment.
+ * c-typeck.c (same_translation_unit_p): Export.
+ (common_type): Use c_override_global_bindings_to_false, not
+ pushlevel/poplevel/declare_parm_level.
+ * c-lang.c: Override LANG_HOOKS_CLEAR_BINDING_STACK,
+ LANG_HOOKS_PUSHLEVEL, LANG_HOOKS_POPLEVEL, LANG_HOOKS_SET_BLOCK,
+ and LANG_HOOKS_GETDECLS with do-nothing stubs.
+ * objc/objc-lang.c: Likewise.
+ * objc/objc-act.c: Adjust all calls to pushlevel, poplevel,
+ get_parm_info.
+ (OBJC_VOID_AT_END): Delete; replace all uses
+ with void_list_node.
+ (generate_forward_declaration_to_string_table): Delete.
+ * objc/objc-act.h (OCTI_STRG_DECL, UOBJC_STRINGS_decl): Delete.
+
+ * coverage.c (create_coverage): Don't pushdecl anything.
+ * langhooks.c (lhd_clear_binding_stack): Call
+ lang_hooks.decls.poplevel, not poplevel.
+ * tree.c (list_length): If ENABLE_TREE_CHECKING, abort on a
+ circular list rather than going into an infinite loop.
+
+2004-03-23 Olivier Hainque <hainque@act-europe.fr>
+
+ * optabs.c (expand_binop): When synthesizing double word rotates
+ from single word shifts, use a new register target if the provided
+ target is not a REG already.
+
+2004-03-23 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * alias.c (get_alias_set): Add support for TYPE_REF_CAN_ALIAS_ALL.
+ * c-common.c (handle_mode_attribute): Add extra arg to
+ build_pointer_type_for_mode and build_reference_type_for_mode.
+ * c-typeck.c (build_c_cast): Only look at TREE_CONSTANT_OVERFLOW
+ for INTEGER_CST.
+ * tree.c (build_pointer_type_for_mode): Add arg CAN_ALIAS_ALL.
+ Chain pointers via TYPE_NEXT_PTR_TO.
+ (build_reference_type_for_mode): Similarly.
+ (build_type_no_quals): Add extra arg to build_pointer_type_for_mode
+ and build_reference_type_for_mode.
+ (tree_check4_failed): New function.
+ * tree.h (TREE_CHECK4, PTR_OR_REF_CHECK): New macros.
+ (TYPE_REF_CAN_ALIAS_ALL, TYPE_NEXT_PTR_TO, TYPE_NEXT_REF_TO): Likewise.
+ (TREE_NO_UNSUED_WARNING, TREE_VIA_VIRTUAL, TREE_CONSTANT_OVERFLOW):
+ Add check.
+
+2004-03-23 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (tree_expr_nonnegative_p): A&B is nonnegative when
+ A is nonnegative or B is nonnegative. Similarly A|B is nonnegative
+ when both A and B are nonnegative.
+ (tree_expr_nonzero_p): A|B is nonzero when A is nonzero or B is
+ nonzero.
+
+2004-03-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Remove cases for INTEGER_CST, REAL_CST,
+ VECTOR_CST, STRING_CST, COMPLEX_CST, and CONSTRUCTOR.
+
+2004-03-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR optimization/14669
+ * fold-const.c (fold): Only unwiden integer comparisons for equality
+ and inequality operators, or when the signedness doesn't change.
+
+2004-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config.gcc (sparc-*-linux*): Add sparc/t-linux to tmake_file.
+ * config/sparc/t-linux64 (TARGET_LIBGCC2_CFLAGS): Set.
+ * config/sparc/t-linux: New file.
+
+2004-03-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcse.c (can_assign_to_reg_p): New function, split out from...
+ (want_to_gcse_p): ...here.
+ (compute_ld_motion_mems): Use can_assign_to_reg_p to validate
+ the rhs of a store.
+
+2004-03-22 Diego Novillo <dnovillo@redhat.com>
+
+ * c-typeck.c (same_translation_unit_p): Fix pasto.
+
+2004-03-22 David Edelsohn <edelsohn@gnu.org>
+
+ * params.def (PARAM_MAX_SCHED_REGION_BLOCKS): New.
+ (PARAM_MAX_SCHED_REGION_INSNS): New.
+ * sched-rgn.c: Include params.h
+ (MAX_RGN_BLOCKS): Delete.
+ (MAX_RGN_INSNS): Delete.
+ (too_large): Return bool. Convert to PARAM_VALUE.
+ * Makefile.in (sched-rgn.o): Depend on $(PARAMS_H).
+ * doc/invoke.texi (param): Document max-sched-region-blocks and
+ max-sched-region-insns.
+
+2004-03-22 Joel Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (is_subrange_type): Do not emit a subrange_type DIE
+ for base types.
+
+2004-03-22 Joel Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (is_subrange_type): Minor code rework. No behavior
+ change.
+
+2004-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/14069
+ * c-decl.c (finish_struct): Change type of incorrect flexible array
+ field into error_mark_node.
+
+2004-03-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/14580
+ * config/rs6000/rs6000.c (symbol_ref_operand): Reject symbols
+ who are not local for Darwin PIC.
+
+2004-03-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * regrename.c (regrename_optimize): Set regs_ever_live for all
+ registers introduced as replacement.
+
+2004-03-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/14470
+ * expr.c (mark_queue): New function.
+ (emit_insns_enqueued_after_mark): New function replacing
+ emit_queue. Clear the body of emitted queued insns.
+ (emit_queue): Call emit_insns_enqueued_after_mark.
+ (store_expr): Mark the increment queue on entry. Emit
+ only the incrementations queued when expanding the source.
+
+2004-03-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Allow --disable-coverage-flags (for the future benefit
+ of top level bootstrap, and consistency). Reindent.
+ * configure: Regenerate.
+
+2004-03-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bt-load.c, builtins.c, cfghooks.c, cfgrtl.c, gcse.c,
+ ggc-page.c, integrate.c, var-tracking.c, web.c: Remove
+ unnecessary casts.
+
+2004-03-22 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/14291
+ * gcov-io.h (gcov_truncate): Define ftruncate as _chsize for
+ __MINGW32__.
+
+2004-03-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*doloop_si"): Change predicate for operand 2
+ to nonimmediate_operand.
+ ("*doloop_di"): Likewise.
+
+2004-03-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * real.h (struct real_value): Use the same type for all
+ bitfields. Rename exp to uexp.
+ (REAL_EXP, SET_REAL_EXP): New accessor macros for uexp.
+ Adjust all uses of exp...
+ * builtins.c: ... here, ...
+ * emit-rtl.c: ... here, and ...
+ * real.c: ... and here.
+
+2004-03-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.c (pp_base_maybe_space): New function.
+ * pretty-print.h (pp_base_maybe_space): Declare.
+ (pp_maybe_space): New macro.
+
+2004-03-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("addti3", "subti3"): New insns and splitters.
+
+2004-03-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * expmed.c (choose_mult_variant): Pass MULT_COST as argument instead
+ of using register multiplication cost.
+ (expand_mult): Adapt choose_mult_variant call.
+ (expand_mult_highpart): Call choose_mult_variant with WIDER_MODE
+ of MODE; pass appropriate cost bound. Adjust result when
+ performing signed multiplication by a negative constant.
+ Don't use intermediate modes larger than word_mode.
+
+2004-03-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * alias.c (get_alias_set): Remove handling of PLACEHOLDER_EXPR.
+ * emit-rtl.c (component_ref_for_mem_expr): Likewise.
+ (set_mem_attributes_minus_bitpos): Call SUBSTITUTE_PLACEHOLDER_IN_EXPR.
+ * explow.c (expr_size): Likewise.
+ * expr.h (placeholder_list, find_placeholder): Deleted.
+ * expr.c (store_constructor): Likewise.
+ (get_inner_reference): Likewise. Also don't call find_placeholder.
+ (placeholder_list, find_placeholder): Deleted.
+ (is_aligning_offset): Don't handle WITH_RECORD_EXPR, PLACEHOLDER_EXPR.
+ (expand_expr_real, cases PLACEHOLDER_EXPR, WITH_RECORD_EXPR): Likewise.
+ (highest_pow2_factor, case WITH_RECORD_EXPR): Remove.
+ * dojump.c (do_jump, case WITH_RECORD_EXPR): Likewise.
+ * dwarf2out.c (loc_descriptor_from_tree, case WITH_RECORD_EXPR):
+ Likewise.
+ * fold-const.c (invert_truthvalue, case WITH_RECORD_EXPR): Likewise.
+ (extract_muldiv, case WITH_RECORD_EXPR): Likewise.
+ * tree.c (expr_align, case WITH_RECORD_EXPR): Likewise.
+ (contains_placeholder_p): Don't handle WITH_RECORD_EXPR.
+ Clean up by using first_rtl_op.
+ (substitute_in_expr): Use SUBSTITUTE_IN_EXPR for recursive call.
+ (substitute_placeholder_in_expr): New function.
+ * tree.def (WITH_RECORD_EXPR): Deleted.
+ * tree.h (SUBSTITUTE_IN_EXPR, SUBSTITUTE_PLACEHOLDER_IN_EXPR): New.
+ (substitute_placeholder_in_expr): New.
+
+2004-03-21 Andrew Pinski <pinskia@gcc.gnu.org>
+
+ * dojump.c (prefer_and_bit_test): Fix which part of
+ the and_test is replaced.
+
+2004-03-21 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * frontends.texi: Add missing line.
+
+2004-03-21 Zack Weinberg <zack@codesourcery.com>
+ Chris Devers <cdevers@pobox.com>
+ Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/frontends.texi: Rewrite.
+ * doc/gcc.texi: Update last modification date.
+
+2004-03-21 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Print the debug
+ message before redirecting the edge.
+
+2004-03-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Set MEM_POINTER
+ flag.
+ * explow.c (force_not_mem): Set REG_POINTER flag according to
+ MEM_POINTER one.
+ * rtl.h (MEM_POINTER): New macro.
+ (struct rtx_def): Use integrated for MEM_SCALAR_P and frame_related
+ for MEM_POINTER.
+
+2004-03-20 Roger Sayle <roger@eyesopen.com>
+
+ PR target/13889
+ * cse.c (fold_rtx): Avoid substituting constants into unary
+ conversion operations.
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Replace "expr" with "t".
+
+2004-03-20 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR c/12373
+ * c-typeck.c (tagged_types_tu_compatible_p): Don't use
+ DECL_ORIGINAL_TYPE if there isn't one.
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Replace "final_type" with "type".
+ Remove variable "final_type".
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Constify "type".
+ Replace "TREE_TYPE (t)" with "type".
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bb-reorder.c, bt-load.c, c-decl.c, cfgcleanup.c, coverage.c,
+ dwarf2asm.c, ifcvt.c, stor-layout.c, varasm.c: Replace calls
+ via (*targetm.foo) () with targetm.foo ().
+
+2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR other/14630
+ * doc/install.texi: Add info directory category and entry.
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Replace "t" with "tem" where it is used
+ as a temporary variable. Remove "orig_t" and all of its uses.
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Remove variable "invert".
+ Move the handling of relational expressions that can be folded
+ to a constant ...
+ (fold_relational_const): ... here.
+ (tree_expr_nonzero_p): New.
+
+2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/14635
+ * builtins.def (nan, nanf, nanl, nans, nansf, nansl): Change to
+ DEF_GCC_BUILTIN.
+
+2004-03-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (dojump.o): Depend on $(GGC_H) and dojump.h.
+ (GTFILES): Add $(srcdir)/dojump.h.
+ (gt-dojump.h): New dependency.
+ * dojump.c (and_reg, and_test, shift_test): New static variables.
+ (prefer_and_bit_test): New function.
+ (do_jump): Use it to choose between (X & (1 << C)) and (X >> C) & 1.
+
+2004-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.c, cfgcleanup.c, cgraphunit.c, c-pretty-print.c,
+ expmed.c, ggc-common.c, jump.c, passes.c, recog.c, regmove.c,
+ reorg.c, tree.h: Fix comment typos.
+
+2004-03-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c, attribs.c, bt-load.c, builtins.c, c-common.c,
+ c-decl.c, c-objc-common.c, c-typeck.c, calls.c, cfglayout.c,
+ cse.c, dbxout.c, dwarf2out.c, except.c, final.c,
+ haifa-sched.c, integrate.c, passes.c, rtlanal.c, sched-rgn.c,
+ sched-vis.c, simplify-rtx.c, stor-layout.c, tree.c, varasm.c,
+ vmsdbgout.c: Replace calls via (*targetm.foo) () with
+ targetm.foo ().
+
+2004-03-19 Ziemowit Laski <zlaski@apple.com>
+
+ * config/rs6000/altivec.h (vec_dst, vec_dstst, vec_dststt,
+ vec_dstt, vec_sld, vec_splat): Add prototypes, marked with
+ always_inline attribute.
+ * config/rs6000/rs6000.c (altivec_expand_dst_builtin):
+ Treat expansion as completed even if literal argument is
+ invalid (so that other expansions are not tried in vain).
+
+2004-03-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * loop-doloop.c (add_test): Replace GEN_INT (0) with
+ const0_rtx.
+
+2004-03-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold) <ABS_EXPR>: Move the handling of constants
+ ...
+ (fold_abs_const): ... here.
+
+2004-03-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree.h (TYPE_ARRAY_MAX_SIZE): Use type.maxval directly.
+
+2004-03-19 Denis Chertykov <denisc@overta.ru>
+
+ PR target/11520
+ * config/avr/avr.md ("call_insn"): Handle explicit integer
+ specially.
+ (call_value_insn): Likewise.
+
+2004-03-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree.c (substitute_in_expr): Rewrite to simplify and be more generic.
+
+2004-03-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (negate_expr): Move the handling of constants
+ ...
+ (fold_negate_const): ... here.
+
+2004-03-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * langhooks-def.h (LANG_HOOKS_HASH_TYPES): New macro and hook.
+ * langhooks.h (struct lang_hooks_for_types): New field hash_types.
+ * tree.c (debug_no_type_hash): Deleted.
+ (type_hash_canon): Abort if passed a variant.
+ Check lang_hooks.types.hash_types.
+ (build_type_no_quals): Copy mode of POINTER_TYPE and REFERENCE_TYPE.
+ (build_array_type): Remove unnecessary allocation of pointer type.
+ (build_complex_type): Properly qualify resulting type.
+
+2004-03-19 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_init_builtins): Fix typo.
+
+2004-03-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * expmed.c (choose_mult_variant, expand_mult_const): New, split from...
+ (expand_mult): ...here.
+ (extract_high_half): New, split out from expand_mult_highpart.
+ (expand_highpart_optab): Likewise. Don't clobber target prematurely.
+ (expand_highpart): Evaluate the cost of a shift/add sequence,
+ then see if any of the specialized optabs are cheaper.
+
+2004-03-18 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * mklibgcc.in: Remove obsolete MAYBE_USE_COLLECT2.
+
+2004-03-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * convert.c (convert_to_real): Add more math builtins.
+
+2004-03-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * convert.c (convert_to_real): Reformat using switch stmt.
+
+2004-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (pointer_int_sum): Do not complain about using
+ pointers to pointers-to-members.
+
+2004-03-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (MD_ASM_CLOBBERS): Move to "Old target macros that
+ have moved to the target hooks structure".
+
+2004-03-18 James E Wilson <wilson@specifixinc.com>
+
+ * config/mips/mips.md (type): Split move into arith and fmove. Split
+ hilo into mthilo and mfhilo. Add trap. Delete icmp. Fix all uses.
+ * config/mips/5400.md (ir_vr54_hilo, ir_vr54_arith, ir_vr54_fabs):
+ Likewise.
+ * config/mips/5500.md (ir_vr55_hilo, ir_vr55_arith, ir_vr55_fabs):
+ Likewise.
+ * config/mips/7000.md (rm7_int_other, rm7_mthilo, rm7_mfhilo,
+ rm7_fp_quick): Likewise.
+ * config/mips/9000.md (rm9k_int, rm9k_mfhilo, rm9k_mthilo,
+ rm9k_fquick): Likewise.
+ * config/mips/sr71k.md (ir_sr70_hilo, ir_sr70_arith, ir_sr70_fabs):
+ Likewise.
+ (ir_sr70_icmp): Delete.
+
+2004-03-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree.h (TREE_CHECK2, TREE_CHECK3, TREE_CHECK5): New macros.
+ (tree_check2_failed, tree_check3_failed, tree_check5_failed): New decl.
+ (FUNC_OR_METHOD_CHECK, SET_ARRAY_OR_VECTOR_CHECK): New macros.
+ (REC_OR_UNION_CHECK, NUMERICAL_TYPE_CHECK): Likewise.
+ (TYPE_VALUES, TYPE_DOMAIN, TYPE_FIELDS, TYPE_METHODS, TYPE_VFIELD):
+ Protect with proper check.
+ (TYPE_ARG_TYPES, TYPE_METHOD_BASETYPE, TYPE_OFFSET_BASETYPE): Likewise.
+ (TYPE_MIN_VALUE, TYPE_MAX_VALUE): Likewise.
+ * tree.c (type_hash_eq): Rewrite to access proper fields for each type.
+ (tree_check2_failed, tree_check3_failed, tree_check5_failed): New.
+ * c-typeck.c (build_array_ref): Use TYPE_DOMAIN, not TYPE_VALUES.
+ * dwarf2out.c (gen_enumeration_type_die): Use TYPE_VALUES,
+ not TYPE_FIELDS.
+ * stor-layout.c (set_sizetype): Use TYPE_ORIG_SIZE_TYPE.
+
+2004-03-18 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * gcse.c (eliminate_partially_redundant_loads): Reject change if
+ dest is set between beginning and current insn.
+
+2004-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * c-decl.c (grokdeclarator): Do not complain about redeclaring
+ visible "static" identifiers "extern" in a local scope.
+ * dwarf2out.c (loc_descriptor_from_tree): Handle pre- and
+ post-increments/decrements.
+
+2004-03-18 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (current_function_arg_words): Delete.
+ (xtensa_builtin_saveregs): Use current_function_args_info.arg_words.
+ (xtensa_va_start): Remove assignment to current_function_arg_words.
+
+2004-03-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * alias.c (record_set): Detect the case where a register is assigned
+ a new value that has the same base term as the old one.
+
+2004-03-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * doloop.c: Removed.
+ * loop-doloop.c: New file.
+ * Makefile.in (doloop.o): Remove.
+ (loop-doloop.o): New.
+ * cfgloop.h (get_loop_level, doloop_optimize_loops): Declare.
+ * cfgloopanal.c (get_loop_level): New function.
+ * loop-iv.c (iv_number_of_iterations): Handle case when loop
+ is leaved immediatelly.
+ * loop.c (strength_reduce): Do not call doloop optimization.
+ * loop.h (LOOP_BCT): Removed.
+ * passes.c (rest_of_handle_loop_optimize): Do not use LOOP_BCT.
+ (rest_of_handle_loop2): Call doloop_optimize_loops.
+ (rest_of_compilation): Test for optimizations moved to
+ rest_of_handle_loop2.
+
+2004-03-17 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_stack_info): correct reg_size
+ for mixed mode.
+ (rs6000_emit_prologue): Ditto.
+ (rs6000_emit_epilogue): Ditto.
+ * config/rs6000/rs6000.h: Definition of DWARF_CIE_DATA_ALIGNMENT
+ macro for mixed mode.
+
+2004-03-18 Jan Hubicka <jh@suse.cz>
+
+ * predict.c (propagate_freq): Compute correctly frequency of
+ EXIT_BLOCK.
+
+2004-03-17 Eric Christopher <echristo@redhat.com>
+
+ * builtins.c (apply_args_size): Use reg_raw_mode.
+ (apply_result_size): Ditto.
+
+2004-03-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR target/14620
+ * config/rtems.h: Add STD_LIB_SPEC and LIB_SPEC.
+
+2004-03-17 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/t-linux64 (bispecs): Don't add -mlong-double-128 for
+ 32-bit builds when defaulting to 32-bit.
+
+2004-03-17 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (rtl_create_basic_block): Pre-allocate basic_block_info
+ array.
+
+2004-03-17 James E Wilson <wilson@specifixinc.com>
+
+ * config/mips/mips.md (zero_extendsidi2): Add length attribute.
+ (hazard_nop): Change type to nop.
+ (type): Split arith into arith, shift, slt, clz. Delete darith.
+ Fix all uses. Change arith to multi if more than one insn emitted.
+ * config/mips/5400.md (ir_vr54_arith): Likewise.
+ * config/mips/5500.md (ir_vr55_arith): Likewise.
+ * config/mips/7000.md (rm7_int_other): Likewise.
+ * config/mips/9000.md (rm9k_int): Likewise.
+ * config/mips/sr71k.md (ir_sr70_arith): Likewise.
+
+2004-03-17 Joel Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (subrange_type_die): Define new variable "subtype"
+ to hold the subtype tree instead of recomputing it several times.
+
+2004-03-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300.c (notice_update_cc): Don't handle
+ CC_INVERT.
+ * config/mn10300/mn10300.md (cc): Remove "invert".
+
+2004-03-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (integer_valued_real_p): Add builtin rint.
+ (fold_builtin): Likewise.
+ * convert.c (convert_to_real): Likewise.
+
+ * convert.c (convert_to_real): Fix typos in `long double'
+ builtins.
+
+2004-03-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14481
+ * fold-const.c (fold): Set TREE_NO_UNUSED_WARNING on implicitly
+ generated COMPOUND_EXPRs.
+
+2004-03-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config/h8300/t-rtems (h8300-*-rtems*): New.
+
+2004-03-16 Eric Christopher <echristo@redhat.com>
+
+ * doc/cppopts.texi(fwide-exec-charset): Fix typo.
+
+2004-03-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-protos.h: Add a prototype for
+ ix86_reverse_condition.
+ * config/i386/i386.c (ix86_reverse_condition): New.
+ * config/i386/i386.h (REVERSE_CONDITION): Use
+ ix86_reverse_condition.
+ * config/i386/i386.md: Use ix86_reverse_condition instead of
+ REVERSE_CONDITION.
+
+2004-03-16 J. Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (loc_descriptor_from_tree): Add handling for MIN_EXPR.
+
+2004-03-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR bootstrap/12974
+ * Makefile.in: Pass $(INCLUDES) down to libgcc.mk explicitly.
+
+2004-03-16 Paolo Bonzini <bonzini@gnu.org>
+
+ * c-common.c (c_common_type_for_mode): Build vector types on
+ demand.
+ (handle_mode_attribute): Deprecate using the mode attribute
+ to create vector types. Fix indentation.
+ (vector_type_node_list): Remove.
+ (handle_vector_size_attribute): Create vector types on demand.
+ Strip a NON_LVALUE_EXPR from the attribute if there is one.
+ * c-typeck.c (comptypes): Make vector types compatible if they
+ have the same underlying mode.
+ (convert_for_assignment): Use comptypes to convert between
+ vector types.
+ * tree.c (build_common_tree_nodes_2): Do not create vector types.
+ * config/arm/arm.c (arm_init_iwmmxt_builtins): Create necessary
+ vector types.
+ * tree.h: Remove vector types.
+ * config/i386/i386.c (i386_init_mmx_sse_builtins): Likewise.
+ * config/rs6000/rs6000.c (rs6000_init_builtins): Likewise.
+ (V16QI_type_node, V2SI_type_node, V2SF_type_node, V4HI_type_node,
+ V4SI_type_node, V4SF_type_node, V8HI_type_node): New globals.
+ * doc/extend.texi (Vector Types): Document how to use the
+ vector_size attribute to create vectors, rather than mode.
+
+ * config/arm/mmintrin.h: Use vector_size attribute, not mode.
+ * config/i386/emmintrin.h: Likewise.
+ * config/i386/mmintrin.h: Likewise.
+ * config/i386/xmmintrin.h: Likewise.
+ * config/sh/ushmedia.h: Likewise.
+
+2004-03-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/freebsd-spec.h, config/arc/arc-protos.h,
+ config/arm/aout.h, config/arm/elf.h, config/arm/freebsd.h,
+ config/arm/linux-gas.h, config/arm/semi.h,
+ config/cris/cris-protos.h, config/i386/xm-djgpp.h,
+ config/ia64/freebsd.h, config/mips/7000.md,
+ config/mips/9000.md, config/ns32k/ns32k-protos.h,
+ config/sparc/pbd.h: Update copyright.
+
+2004-03-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR target/14577
+ * config.gcc: Switch sh-*-rtems* to ELF. Add sh-*-rtemscoff.
+
+2004-03-16 Paolo Bonzini <bonzini@gnu.org>
+
+ * combine.c (combine_simplify_rtx): Remove the "last"
+ parameter and its documentation. Adjust recursive calls.
+ (simplify_logical): Always perform the only simplification
+ controlled by "last", if the simplified expression is
+ actually different.
+ (try_combine): Do not pass the "last" parameter to
+ combine_simplify_rtx.
+
+2004-03-16 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/14599
+ * config/mips/mips.md (UNSPEC_GP): New constant.
+ * config/mips/mips.c (CONST_GP_P): Expect the CONST to contain
+ an UNSPEC instead of (reg $gp).
+ (mips16_gp_pseudo_reg): Change accordingly.
+ (print_operand): Print $gp directly when handling CONST_GP_P.
+
+2004-03-16 Richard Zidlicky <rz@linux-m68k.org>
+
+ * config.gcc, config/m68k/linux.h: Implement with-cpu for m68k-linux.
+ * longlong.h: Make code 68060 clean when compiling for m68060.
+
+2004-03-16 Richard Zidlicky <rz@linux-m68k.org>
+
+ * config/m68k/m68k.md: Fix constraints for bitfield instructions.
+ * doc/md.texi: Clarify description of "i" constraint.
+
+2004-03-15 James E Wilson <wilson@specifixinc.com>
+
+ * config/mips/mips.md (type): Split load into load, fpload, fpidxload.
+ Split store into store, fpstore, fpidxstore. Fix all uses.
+ * config/mips/5400.md (ir_vr54_load, ir_vr54_store, ir_vr54_fstore):
+ Likewise.
+ * config/mips/5500.md (ir_vr55_load, i5_vr55_store): Likewise.
+ * config/mips/7000.md (rm7_ld, rm7_st): Likewise.
+ * config/mips/9000.md (rm9k_load, rm9k_store): Likewise.
+ * config/mips/sr71k.md (ir_sr70_load, ir_sr70_store, ir_sr70_fload,
+ ir_sr70_fstore): Likewise.
+
+2004-03-15 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14535
+ * except.c (collect_one_action_chain): Record action for cleanup
+ outer of exception spec.
+
+2004-03-15 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address):
+ Fix the check for abort and only do the mmap if we can.
+
+2004-03-15 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * config/sparc/sparc.h: Rework comments about the code model
+ in 64-bit environment and the mode 'Pmode'.
+ * doc/invoke.texi (SPARC options): Rework description of the
+ different code models supported in 64-bit environment.
+
+2004-03-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * defaults.h (REVERSIBLE_CC_MODE): Define.
+ * jump.c (reversed_comparison_code_parts): Don't check if
+ REVERSIBLE_CC_MODE is defined.
+
+2004-03-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-incpath.c, c-incpath.h, c-pch.c, c.opt, cppexp.c,
+ et-forest.h, genattr.c, ggc-none.c, hosthooks-def.h,
+ hosthooks.h, params.h, ra-colorize.c, web.c,
+ config/darwin-c.c, config/alpha/freebsd.h, config/arm/pe.c,
+ config/avr/avr-protos.h, config/avr/avr.md,
+ config/fr30/fr30-protos.h, config/fr30/fr30.md,
+ config/h8300/fixunssfsi.c, config/i386/darwin.h,
+ config/i386/freebsd.h, config/i386/freebsd64.h,
+ config/ia64/hpux.h, config/ia64/unwind-ia64.c,
+ config/ip2k/libgcc.S, config/m32r/xm-m32r.h,
+ config/mmix/mmix-modes.def, config/ns32k/netbsd.h,
+ config/ns32k/ns32k.md, config/pa/pa64-hpux.h,
+ config/pa/pa64-regs.h, config/rs6000/aix41.h,
+ config/rs6000/aix43.h, config/rs6000/host-darwin.c,
+ config/sparc/aout.h, config/sparc/freebsd.h,
+ config/sparc/litecoff.h, config/vax/vax-protos.h,
+ doc/hostconfig.texi, doc/include/gcc-common.texi: Update
+ copyright.
+
+2004-03-15 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (thumb_expand_prologue): Tie prologue insns to fp.
+
+2004-03-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.c (pp_c_semicolon): Fix formatting.
+ (pp_c_cv_qualifier): Document.
+ (pp_c_space_for_pointer_operator): Likewise.
+ (pp_c_integer_constant): Likewise.
+ (pp_c_identifier): Likewise.
+ (pp_c_init_declarator): Don't print function body.
+
+2004-03-14 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/contrib.texi, doc/extend.texi, doc/gcov.texi,
+ doc/install.texi, doc/invoke.texi, doc/makefile.texi,
+ doc/sourcebuild.texi, doc/tm.texi, doc/trouble.texi: Capitalize
+ "gcc", "g++" and "g77" or mark up with appropriate markup. Adjust
+ wording and grammar.
+
+2004-03-14 Roger Sayle <roger@eyesopen.com>
+
+ * alias.c (get_alias_set): Replace calls via (*lang_hooks.foo) ()
+ with lang_hooks.foo ().
+ * builtins.c (expand_builtin_va_arg): Likewise.
+ * c-common.c (fname_as_string, c_common_truthvalue_conversion,
+ c_common_type_for_mode, c_common_nodes_and_builtins,
+ handle_mode_attribute, handle_vector_size_attribute): Likewise.
+ * c-convert.c (convert): Likewise.
+ * c-format.c (check_format_types): Likewise.
+ * c-objc-common.c (c_tree_printer): Likewise.
+ * c-typeck.c (build_unary_op, build_conditional_expr,
+ build_binary_op): Likewise.
+ * calls.c (try_to_integrate, expand_call,
+ emit_library_call_value_1): Likewise.
+ * cgraph.c (cgraph_node_name, cgraph_function_possibly_inlined_p):
+ Likewise.
+ * cgraphunit.c (record_call_1, cgraph_analyze_function,
+ cgraph_expand_function): Likewise.
+ * convert.c (convert_to_pointer, convert_to_integer): Likewise.
+ * coverage.c (build_fn_info_type, build_ctr_info_type,
+ build_gcov_info, create_coverage): Likewise.
+ * dbxout.c (dbxout_init): Likewise.
+ * diagnostic.c (diagnostic_report_current_function): Likewise.
+ * dojump.c (do_jump): Likewise.
+ * dwarf2out.c (dwarf2_name): Likewise.
+ * except.c (init_eh): Likewise.
+ * explow.c (expr_size, int_expr_size): Likewise.
+ * expmed.c (make_tree, const_mult_add_overflow_p, expand_mult_add):
+ Likewise.
+ * expr.c (store_expr, store_constructor, safe_from_p,
+ expand_expr_real, do_store_flag, try_casesi): Likewise.
+ * function.c (push_function_context_to, pop_function_context_from,
+ free_after_parsing, assign_stack_local_1, assign_stack_temp_for_type,
+ put_var_into_stack, allocate_struct_function, current_function_name):
+ Likewise.
+ * integrate.c (copy_decl_for_inlining, expand_inline_function):
+ Likewise.
+ * langhooks.c (lhd_clear_binding_stack, write_global_declarations,
+ lhd_print_error_function): Likewise.
+ * opts.c (handle_option, decode_options): Likewise.
+ * passes.c (open_dump_file): Likewise.
+ * print-tree.c (print_node): Likewise.
+ * stmt.c (expand_fixup, fixup_gotos, expand_asm_operands,
+ expand_decl_cleanup, emit_case_nodes): Likewise.
+ * stor-layout.c (variable_size): Likewise.
+ * toplev.c (announce_function, wrapup_global_declarations,
+ check_global_declarations, compile_file, default_tree_printer,
+ process_options, lang_dependent_init, finalize): Likewise.
+ * tree-dump.c (dequeue_and_dump): Likewise.
+ * tree-inline.c (remap_decl, remap_block, copy_body_r,
+ initialize_inlined_parameters, declare_return_variable,
+ inlinable_function_p, expand_call_inline, optimize_inline_calls,
+ walk_tree, copy_tree_r): Likewise.
+ * tree-optimize.c (tree_rest_of_compilation): Likewise.
+ * tree.c (decl_assembler_name, tree_size, size_in_bytes, staticp,
+ unsafe_for_reeval, get_unwidened, get_narrower, get_callee_fndecl,
+ variably_modified_type_p, dump_tree_statistics): Likewise.
+ * varasm.c (assemble_variable, compare_constant, copy_constant,
+ force_const_mem, compute_reloc_for_constant, output_constant,
+ output_addressed_constants, initializer_constant_valid_p): Likewise.
+
+2004-03-14 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/install.texi: Make autoconf 2.13 the exception, not the rule.
+
+2004-03-14 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * doc/install.texi: Reflect autoconf and automake version for
+ libffi. Update autoconf version to 2.59.
+
+2004-03-13 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_expr, operand_equal_for_comparison_p,
+ optimize_bit_field_compare, decode_field_reference, all_ones_mask_p,
+ make_range, build_range_check, fold_range_test, unextend,
+ constant_boolean_node, fold_binary_op_with_conditional_arg,
+ fold_truthop, fold_mathfn_compare, fold_inf_compare,
+ fold_single_bit_test, fold): Replace calls via (*lang_hooks.foo) ()
+ with lang_hooks.foo ().
+
+2004-03-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (EXTRA_CONSTRAINT_STR_ARM): Update comment.
+
+2004-03-13 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ * doc/install.texi: Note status of -fnew-ra.
+
+2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/14470
+ * expr.c (store_expr): Call emit_queue before generating the move
+ from the temporary to the original target. Protect the temporary
+ from emit_queue.
+
+2004-03-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/14533
+ * config/s390/s390.c (legitimize_pic_address): Don't abort on UNSPEC
+ other than UNSPEC_GOTOFF.
+
+2004-03-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_legitimate_address_p): New argument, OUTER. Pass through
+ to arm_legitimate_index_p. Update all callers with SET as default
+ value.
+ (arm_legitimate_index_p): New argument, OUTER. Restrict the index
+ range if OUTER is a sign-extend operation on QImode. Correctly
+ reject shift operations on sign-extended QImode addresses.
+ (bad_signed_byte_operand): Delete.
+ (arm_extendqisi_mem_op): New function.
+ * arm.h (EXTRA_CONSTRAINT_ARM): Delete. Replace with...
+ (EXTRA_CONSTRAINT_STR_ARM): ... this. Handle extended address
+ constraints.
+ (CONSTRAINT_LEN): New.
+ (EXTRA_CONSTRAINT): Delete. Replace with...
+ (EXTRA_CONSTRAINT_STR): ... this.
+ (PREDICATE_CODES): Remove bad_signed_byte_operand.
+ * arm.md (extendqihi_insn): Use new constraint Uq. Rework. Length
+ is now always default.
+ (define_splits for bad sign-extend loads): Delete.
+ (arm_extendqisi, arm_extendqisi_v5): Likewise.
+ * arm/vfp.md (arm_movsi_vfp, arm_movdi_vfp, movsf_vfp, movdf_vfp):
+ Rework 'U' constraint to 'Uv'.
+ * arm-protos.h: Remove bad_signed_byte_operand. Add
+ arm_extendqisi_mem_op.
+ * doc/md.texi (ARM constraints): Rename VFP constraint (now Uv).
+ Add Uq constraint.
+
+2004-03-13 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_va_arg): Replace SPLIT_COMPLEX_ARGS
+ with targetm version.
+
+ PR target/14567
+ * config/rs6000/rs6000.h (UNITS_PER_ARG, RS6000_ARG_SIZE): Delete.
+ (HARD_REGNO_MODE_OK): Disallow TFmode for fp31.
+ * config/rs6000/rs6000.c (rs6000_arg_size): New function.
+ Update all users of RS6000_ARG_SIZE.
+ (function_arg_advance): Count fregno using mode size.
+ (function_arg): Handle long double split over regs and memory.
+ (function_arg_partial_nregs): Likewise.
+ (rs6000_va_arg): Repackage complex args.
+
+2004-03-13 Dean Ferreyra <dferreyra@igc.org>
+
+ PR target/14047
+ * config/avr/avr.c (avr_progmem_p): Add "attributes" parameter.
+ (avr_insert_attributes): Pass "attributes" to avr_progmem_p.
+ * config/avr/avr-protos.h (avr_progmem_p): Change prototype.
+
+2004-03-12 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000-protos.h (rs6000_output_dwarf_dtprel): Add
+ prototype.
+ * config/rs6000/rs6000.c (rs6000_output_dwarf_dtprel): New.
+ * config/rs6000/rs6000.h (ASM_OUTPUT_DWARF_DTPREL): Define.
+
+2004-03-12 Andrew Pinski <apinski@apple.com>
+
+ * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address):
+ Use ret instead of result. Use addr instead of base.
+
+2004-03-12 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (*-ibm-aix*): Document assembler and achiver
+ fixes required by libstdc++ and update installation instructions
+ for libstdc++.a.
+
+2004-03-12 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (i386_pe_strip_name_encoding_full): Strip
+ leading '@' on fastcall symbols before stripping suffix.
+
+2004-03-12 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (unmentioned_reg_p): New function to check whether an
+ expression is a "specialization" of another, i.e. that there are
+ no registers or memory references mentioned in the first that don't
+ appear in the second.
+ (unmentioned_reg_p_1): New helper subroutine of unmentioned_reg_p.
+ (combine_instructions): Also try combining instructions using the
+ REG_EQUAL note from a preceding log-linked instruction.
+
+2004-03-12 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (ix86_split_ashrdi): Optimize shift by 63.
+
+2004-03-12 Matt Austern <austern@apple.com>
+
+ * target.h (struct gcc_target): New target hook, unwind_label.
+ * target-def.h (TARGET_ASM_EMIT_UNWIND_LABEL): New hook.
+ * output.h (default_emit_unwind_label): New function.
+ * default.h (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY): New macro.
+ (TARGET_USES_WEAK_UNWIND_INFO): New target macro.
+ (TARGET_SUPPORTS_HIDDEN): New target macro.
+ * dwarf2out.c (struct dw_fde_struct): Add field for function decl
+ that corresponds to this FDE.
+ (FRAME_BEGIN_LABEL): Allow target to override default label.
+ (output_call_frame_info): If FDEs are linknonce, then use extra
+ indirection for FDE encoding, output a label for each FDE, and
+ output an empty label for each function without an FDE.
+ (dwarf2out_begin_prologue): Set up decl field when creating an FDE.
+ * varasm.c (globalize_decl): Call ASM_MAKE_LABEL_LINKONCE for
+ decls with DECL_ONE_ONLY set, if that macro is defined.
+ (make_decl_one_only): Don't use DECL_COMMON if we're compiling
+ for a SUPPORTS_ONE_ONLY target.
+ * config/darwin-protos.h (darwin_unique_section): Declare.
+ (darwin_asm_named_section): Likewise.
+ (darwin_section_type_flags): Likewise.
+ (darwin_non_lazy_pcrel): Likewise.
+ (darwin_emit_unwind_label): Likewise.
+ (darwin_make_decl_one_only): Likewise.
+ * config/darwin.c (machopic_finish): Get rid of tweak that
+ eliminate stubs for symbols that are defined.
+ (darwin_encode_section_info): Don't treat weak functions as defined.
+ (darwin_make_decl_one_only): Define.
+ (darwin_asm_named_section): Likewise.
+ (darwin_section_type_flags): Likewise.
+ (darwin_unique_section): Likewise.
+ (darwin_emit_unwind_label): Likewise.
+ (darwin_non_lazy_pcrel): Likewise.
+ (darwin_asm_output_dwarf_delta): Difference between two labels is
+ local only if both labels are local.
+ * config/darwin.h (MAKE_DECL_ONE_ONLY): Define.
+ (ASM_MAKE_LABEL_LINKONCE): Likewise.
+ (TARGET_SUPPORTS_HIDDEN): Likewise.
+ (TARGET_USES_WEAK_UNWIND_INFO): Likewise.
+ (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY): Likewise.
+ (FRAME_BEGIN_LABEL): Likewise.
+ (ASM_DECLARE_OBJECT_NAME): Make references to weak symbols indirect.
+ (ASM_DECLARE_FUNCTION_NAME): Likewise.
+ (darwin_eh_frame_section): Give __eh_frame section the coalesced flag.
+ (TARGET_ASM_UNIQUE_SECTION): Define.
+ (EH_FRAME_SECTION_NAME): Define.
+ (EH_FRAME_SECTION_ATTR): Likewise.
+ (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): Likewise.
+ (TARGET_ASM_NAMED_SECTION): Likewise.
+ (TARGET_SECTION_TYPE_FLAGS): Likewise.
+ * doc/tm.texi: Document TARGET_USES_WEAK_UNWIND_INFO,
+ TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY, TARGET_SUPPORTS_HIDDEN,
+ TARGET_ASM_EMIT_UNWIND_LABEL.
+
+2004-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_mathfn): Add pow10* to the
+ existing exp10* case.
+ (expand_builtin): Likewise.
+
+2004-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/tm.texi (registers) <Values in Registers>: Add
+ entry for REGMODE_NATURAL_SIZE.
+
+2004-03-12 Richard Henderson <rth@redhat.com>
+
+ PR target/14547
+ * target.h (struct gcc_target): Move calls substructure before
+ booleans. Add split_complex_arg.
+ * function.c (assign_parms, split_complex_args): Use it.
+ * calls.c (expand_call): Likewise.
+ (split_complex_values): Likewise. Check for splittable types
+ before allocating memory.
+ (split_complex_types): Likewise.
+ * system.h (SPLIT_COMPLEX_ARGS): Poison.
+ * expr.h (SPLIT_COMPLEX_ARGS): Remove.
+ * target-def.h (TARGET_SPLIT_COMPLEX_ARG): New.
+ * config/alpha/alpha.c (alpha_split_complex_arg): New.
+ (TARGET_SPLIT_COMPLEX_ARG): New.
+ * config/alpha/alpha.h (SPLIT_COMPLEX_ARGS): Remove.
+ * config/rs6000/rs6000.c (TARGET_SPLIT_COMPLEX_ARG): New.
+ (rs6000_override_options): Zap it for non-AIX.
+ (rs6000_function_value): Use targetm.calls.split_complex_arg.
+ * config/rs6000/rs6000.h (SPLIT_COMPLEX_ARGS): Remove.
+ * config/xtensa/xtensa.c (TARGET_SPLIT_COMPLEX_ARG): New.
+ * config/xtensa/xtensa.h (SPLIT_COMPLEX_ARGS): Remove.
+ * doc/tm.texi (TARGET_SPLIT_COMPLEX_ARG): Modify from old
+ SPLIT_COMPLEX_ARGS entry.
+
+2004-03-11 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (xfloating_ops, vax_cvt_ops): New.
+ (alpha_lookup_xfloating_lib_func): Use them, return rtx.
+ (alpha_emit_xfloating_arith): Update to match.
+ (alpha_emit_xfloating_compare): Likewise.
+ (alpha_emit_xfloating_cvt): Likewise.
+ (alpha_emit_xfloating_libcall): Take already built symbol,
+ mark call const.
+ * config/alpha/alpha.md (extendsftf2, extenddftf2): Take
+ op1 in a register.
+
+2004-03-11 Richard Henderson <rth@redhat.com>
+
+ PR target/14539
+ * config/alpha/alpha.h (STACK_BOUNDARY): Set to 128.
+
+ * simplify-rtx.c (simplify_relational_operation): Fix typo.
+
+2004-03-11 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14477
+ * except.c (remove_unreachable_regions): Look thru CALL_PLACEHOLDER.
+
+2004-03-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR target/14262
+ * calls.c (load_register_parameters): If BLOCK_REG_PADDING is not
+ defined, pass small BLKmode values in registers in the low-order part.
+
+2004-03-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (if_then_else_cond): Check for NULL return value of
+ simplify_gen_subreg.
+
+2004-03-11 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/14496
+ * config/mips/mips.h (UNITS_PER_FPVALUE): Fix value for
+ TARGET_SINGLE_FLOAT.
+
+2004-03-11 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (TARGET_INIT_LIBFUNCS): Add undef.
+ * config/ia64/ia64.h (TARGET_INIT_LIBFUNCS): Add define.
+ * config/ia64/ia64.c (ia64_init_libfuncs): New.
+ (ia64_hpux_init_libfuncs): Add call to ia64_init_libfuncs.
+
+2004-03-11 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_expr_p) <RSHIFT_EXPR>: We can optimize
+ -((int)X>>C) where C is an integer constant one bit less than the
+ size of X into (unsigned)X>>C. Similarly for unsigned->signed.
+ (negate_expr) <RSHIFT_EXPR>: Implement the above transformations.
+
+ * simplify-rtx.c (simplify_unary_operation): Also implement the
+ above transformations at the RTL level.
+
+2004-03-11 Alan Modra <amodra@bigpond.net.au>
+
+ * real.c (encode_ibm_extended): Do round low word.
+
+2004-03-11 Ben Elliston <bje@wasabisystems.com>
+
+ * config/arm/arm.md (is_xscale): Comment this attribute and move
+ it a bit further up in the file, closer to related attributes.
+
+2004-03-11 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/host-solaris.c (sol_gt_pch_use_address): Add
+ missing terminating marker to comment.
+
+2004-03-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Use move_operand in splitters for 64-bit moves.
+ (movdi, movsi, movhi, movqi, movsf, movdf): Remove predicates.
+ (*movdi_32bit_mips16, *movsi_mips16, *movhi_mips16, *movqi_mips16)
+ (*movsf_mips16, *movdf_mips16): Name unnamed patterns. Use
+ move_operand as source predicate in all cases.
+ (*movdi_32bit): Renamed from movdi_internal. Remove 'F' constraint.
+ Test reg_or_0_operand. Use move_operand as source predicate.
+ (*movdi_64bit): Renamed from movdi_internal2. Test reg_or_0_operand.
+ (*movdi_64bit_mips16): Renamed from movdi_internal2_mips16.
+ (*movsi_internal): Renamed from movsi_internal. Test reg_or_0_operand.
+ (movhi, movqi, movsf, movdf): Use mips_legitimize_move.
+ (*movhi_internal): Renamed from movhi_internal. Test reg_or_0_operand.
+ Use move_operand as source predicate. Remove 'K' constraint.
+ (*movqi_internal): Likewise movqi_internal.
+ (*movsf_hardfloat): Renamed from movsf_internal1. Test
+ reg_or_0_operand. Use move_operand as source predicate.
+ (*movsf_softfloat): Likewise movsf_internal2.
+ (*movdf_hardfloat_64bit): Likewise movsf_internal1a.
+ (*movdf_hardfloat_32bit): Likewise movsf_internal1b.
+ (*movdf_softfloat): Likewise movdf_internal2.
+ * config/mips/mips.c (move_operand): Match arbitrary CONST_INTs
+ for DImode if !TARGET_64BIT.
+ (mips_legitimize_move): Simplify accordingly.
+
+2004-03-11 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/14362
+ * var-tracking.c (struct variable_def): Added field refcount.
+ (variable_htab_free): Decrease the refcount and delete variable
+ only if there are no more references.
+ (unshare_variable): New function.
+ (vars_copy_1): Increase refcount instead of copying the variable.
+ (variable_union): Share the variables where possible, unshare
+ the variables if needed.
+ (variable_different_p): Return false if var1 and var2 are
+ the same structure.
+ (variable_was_changed): Init the refcount of new variable.
+ (set_frame_base_location): Unshare variable if needed.
+ (set_variable_part): Init the refcount of new variable.
+ Unshare the variables if needed.
+ (delete_variable_part): Unshare the variables if needed.
+ (emit_notes_for_differences_1): Init the refcount of new variable.
+ (vt_add_function_parameters): Do not add function parameters to
+ IN set of ENTRY_BLOCK_PTR because it is unused anyway.
+ (vt_initialize): Do not add frame_base_decl to IN set of
+ ENTRY_BLOCK_PTR because it is unused anyway.
+
+2004-03-11 Josef Zlomek <zlomekj@suse.cz>
+
+ * var-tracking.c (vars_copy_1): Cleanup and speedup chain operations.
+ (vars_copy): Likewise.
+ (variable_union): Likewise.
+ (set_variable_part): Likewise.
+ (delete_variable_part): Likewise.
+
+2004-03-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-typeck.c, combine.c, cse.c, dominance.c, et-forest.h,
+ ggc-page.c, var-tracking.c, config/fp-bit.c, config/c4x/c4x.c,
+ config/cris/cris.c, config/i386/ppro.md, config/i860/i860.c,
+ config/i860/i860.h, config/m32r/m32r.h, config/m32r/xm-m32r.h,
+ config/m68hc11/m68hc11.h, config/m68hc11/m68hc11.md,
+ config/mips/mips.c, config/mmix/mmix.c, config/ns32k/ns32k.h,
+ config/pa/pa.c, config/pa/pa32-regs.h, config/pa/pa64-regs.h,
+ config/pdp11/pdp11.h, config/rs6000/rs6000.c,
+ config/stormy16/stormy16.c: Fix comment typos and formatting.
+
+2004-03-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure: Regenerate, since I forgot to while committing Paolo's
+ changes.
+
+2004-03-08 Paolo Bonzini <bonzini@gnu.org>
+
+ PR ada/14131
+ Move language detection to the top level.
+ * configure.ac: Remove code to detect languages,
+ it now lives exclusively in the top level.
+ * aclocal.m4 (gcc_AC_PROG_GNAT): Moved to the
+ top level, renamed to ACX_PROG_GNAT.
+
+2004-03-10 Richard Henderson <rth@redhat.com>
+
+ * c-pch.c (c_common_no_more_pch): Update for gt_pch_use_address
+ extra arguments.
+ * config.host (*-*-solaris2*, *-*-linux*): Add out_host_hook_obj
+ and host_xmake_file fragments.
+ * ggc-common.c (gt_pch_save): Update for gt_pch_get_address change.
+ (gt_pch_restore): Similarly for gt_pch_use_address.
+ (default_gt_pch_get_address): New.
+ (mmap_gt_pch_get_address): Split out of gt_pch_save.
+ (default_gt_pch_use_address): Split out of gt_pch_restore.
+ (mmap_gt_pch_use_address): Likewise.
+ * hooks.c (hook_voidp_size_t_null): Remove.
+ (hook_bool_voidp_size_t_false): Remove.
+ * hooks.h: Likewise.
+ * hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): Use one of the
+ default_ or mmap_ definitions.
+ (HOST_HOOKS_GT_PCH_USE_ADDRESS): Likewise.
+ * hosthooks.h (struct host_hooks): Update gt_pch_get_address
+ and gt_pch_use_address.
+ * config/host-linux.c, config/host-solaris.c: New files.
+ * config/x-linux, config/x-solaris: New files.
+ * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_get_address):
+ Update for changed definition.
+ (darwin_rs6000_gt_pch_use_address): Likewise.
+ * doc/hostconfig.texi: Update docs.
+
+2004-03-10 Richard Henderson <rth@redhat.com>
+
+ PR c/14517
+ * c-decl.c (grokdeclarator): Don't warn for duplicate qualifiers
+ except for pedantic c90 mode.
+
+2004-03-10 Kelley Cook <kcook@gcc.gnu.org>
+
+ * configure.ac: Bump AC_PREREQ to 2.59.
+ * configure: Regenerate.
+
+2004-03-10 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_exp10 and OTI_exp2.
+ (exp10_optab, exp2_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize exp10_optab and exp2_optab.
+ * genopinit.c (optabs): Implement exp10_optab and exp2_optab
+ using exp10?f2 and exp2?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXP10{,F,L}
+ using exp10_optab, and BUILT_IN_EXP2{,F,L} using exp2_optab.
+ (expand_builtin): Expand BUILT_IN_EXP10{,F,L} and BUILT_IN_EXP2{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (exp10sf2, exp10df2, exp10xf2, exp2sf2,
+ exp2df2, exp2xf2): New patterns to implement exp10, exp10f, exp10l,
+ exp2, exp2f and exp2l built-ins as inline x87 intrinsics.
+
+2004-03-10 Anthony Green <green@redhat.com>
+
+ * doc/invoke.texi (ARM Options): Fix -mpfu typo.
+
+2004-03-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix.h (TARGET_OS_CPP_BUILTINS): Rename to ...
+ (TARGET_OS_AIX_CPP_BUILTINS): this. Conditionally define
+ __LONGDOUBLE128.
+ * config/rs6000/aix41.h (TARGET_OS_CPP_BUILTINS): Use
+ TARGET_OS_AIX_CPP_BUILTINS.
+ * config/rs6000/aix43.h (TARGET_OS_CPP_BUILTINS): Same.
+ * config/rs6000/aix51.h (TARGET_OS_CPP_BUILTINS): Same.
+ * config/rs6000/aix52.h (TARGET_OS_CPP_BUILTINS): Same.
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Revert
+ previous change.
+
+2004-03-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fold-const.c (tree_expr_nonnegative_p): Add more builtin cases.
+
+2004-03-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define
+ __LONGDOUBLE128 on AIX.
+
+2004-03-10 Andrew Haley <aph@redhat.com>
+
+ PR optimization/14381
+ * function.c (expand_function_end): Emit a blockage insn before
+ the epilogue when -fnon-call-exceptions is used.
+
+ * except.c (expand_start_all_catch): Make comment more accurate.
+
+2004-03-08 Joel Sherrill <joel@oarcorp.com>
+
+ PR target/14480
+ * config/rs6000/t-rtems: Add missing file on branch.
+
+2004-03-10 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * dbxout.c (dbxout_symbol_location): Do not output references
+ to optimized-out constant pool symbols.
+
+2004-03-10 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/ia64.md (divsi3, udivsi3): Remove unused variable
+ twon34_r.
+
+2004-03-09 James E Wilson <wilson@specifixinc.com>
+
+ * alias.c (alias_sets_might_conflict_p): New.
+ * c-typeck.c (build_c_cast): Call it if warn_strict_aliasing > 1.
+ * common.opt (Wstrict-aliasing=): New.
+ * flags.h (warn_strict_aliasing): Change type to int.
+ * opts.c (warn_strict_aliasing): Change type to int.
+ (common_handle_option): Handle OPT_Wstrict_aliasing_.
+ * tree.h (alias_sets_might_conflict_p): Declare it.
+ * doc/invoke.tex (-Wstrict-aliasing=2): Document it.
+
+2004-03-10 Roman Zippel <zippel@linux-m68k.org>
+
+ PR bootstrap/12371
+ * config/m68k/m68k.h (FIXED_REGISTERS): Add arg pointer.
+ (CALL_USED_REGISTERS): Likewise.
+ (REG_CLASS_CONTENTS): Likewise.
+ (REG_ALLOC_ORDER): New.
+ (REGNO_REG_CLASS): Use regno_reg_class.
+ * config/m68k/m68k.c: Add regno_reg_class array.
+
+2004-03-09 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.md (divsi3): Fix algorithm.
+ (udivsi3): Ditto.
+ (setf_exp_xf): Remove '*' from name.
+ * testsuite/gcc.dg/20040309-1.c: New test.
+
+2004-03-09 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * system.h (SUNOS4_SHARED_LIBRARIES): Poison.
+ * collect2.c: Remove SUNOS4_SHARED_LIBRARIES code.
+ * config/sparc/aout.h (TARGET_ASM_SELECT_SECTION): Don't define.
+ * config/sparc/sparc.c (sparc_aout_select_section): Remove.
+ (sparc_aout_select_rtx_section): Don't check
+ SUNOS4_SHARED_LIBRARIES.
+ * config/sparc/sparc.h (SUNOS4_SHARED_LIBRARIES): Don't define.
+
+2004-03-10 Hans-Peter Nilsson <hp@axis.com>
+
+ PR other/14474
+ * doc/md.texi (Pattern Ordering, Dependent Patterns)
+ (Jump Patterns, Looping Patterns): Wrap in separate "@ifset
+ INTERNALS".
+
+2004-03-09 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/hpux.h (MULTILIB_DEFAULTS): Define.
+ (LIBGCC_SPEC): Update to match.
+
+2004-03-09 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (last_function_parms, last_function_parm_tags)
+ (last_function_parm_others, current_function_parms)
+ (current_function_parm_tags, current_function_parm_others):
+ Delete.
+ (ARG_INFO_PARMS, ARG_INFO_TAGS, ARG_INFO_TYPES, ARG_INFO_OTHERS):
+ New macros.
+ (grokdeclarator): For function definitions, save the arg-info
+ block from the declarator in DECL_ARGUMENTS.
+ (grokparms): Do not write to last_function_parm*. Use ARG_INFO_*
+ macros to operate on arg-info block. Can assume ARG_INFO_PARMS
+ contains only PARM_DECLs. Improve diagnostics.
+ (get_parm_info): Use ARG_INFO_* macros. Improve comments and
+ diagnostics. Disable some expensive checks if not ENABLE_CHECKING.
+ (store_parm_decls_newstyle): Take the function to operate on,
+ and an arg-info block, as arguments; don't get anything from
+ current_function_* globals.
+ (store_parm_decls_oldstyle): Likewise.
+ (store_parm_decls): Pass fndecl and its arg-info block down to
+ store_parm_decls_newstyle/oldstyle. Send functions with empty
+ argument lists through store_parm_decls_newstyle to reduce
+ overhead.
+ (pushdecl): Comment on the problems with the call to copy_node.
+ Clear DECL_ARGUMENTS of the old node after copying it, if it
+ is an arg-info block instead of a chain of decls.
+ (start_function): Do not manipulate current_function_parm* or
+ last_function_parm*.
+
+2004-03-09 Roger Sayle <roger@eyesopen.com>
+ Andrew Pinski <pinskia@physics.uc.edu>
+
+ * ifcvt.c (noce_try_sign_mask): New function to transform
+ "x = (y < 0) ? z : 0" into the equivalent "x = (y >> C) & z".
+ (noce_process_if_block): Call noce_try_sign_mask.
+
+2004-03-09 Andrew Pinski <apinski@apple.com>
+
+ * c-typeck.c (tagged_types_tu_compatible_p):
+ Fix typo.
+
+2004-03-09 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_const_relational_operation): New function
+ renamed from simplify_relational_operation.
+ (simplify_relational_operation): Change prototype to accept an
+ additional mode argument. Call simplify_const_relational_operation.
+ (simplify_gen_relational): Update simplify_relational_operation call.
+ (simplify_ternary_operation): Update simplify_relational_operation
+ subroutine call to use simplify_const_relational_operation instead.
+
+ * rtl.h (simplify_const_relational_operation): Prototype here.
+ (simplify_relational_operation): Add addtional mode argument.
+
+ * combine.c (combine_simplify_rtx): Update calls to
+ simplify_relational_operation.
+ (simplify_set): Likewise.
+ (gen_binary): Likewise.
+ * cse.c (fold_rtx): Likewise.
+ * dojump.c (compare_from_rtx): Likewise.
+ (do_compare_rtx_and_jump): Likewise.
+ * integrate.c (subst_constants): Likewise.
+ * unroll.c (simplify_cmp_and_jump_insns): Likewise.
+
+2004-03-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Remove all define_peephole's.
+
+2004-03-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: Remove trailing whitespace.
+
+2004-03-08 Eric Christopher <echristo@redhat.com>
+
+ * Makefile.in (site.exp): Add libiconv variable definition.
+
+2004-03-09 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure: Regenerate for config/accross.m4 correction.
+
+2004-03-08 Joel Sherrill <joel@oarcorp.com>
+
+ PR target/14480
+ * config/rs6000/t-rtems: Add missing file on branch.
+
+2004-03-08 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/14289
+ * c-typeck.c (c_mark_addressable): A register variable should
+ be considered global if its not automatic, i.e. TREE_PUBLIC,
+ TREE_STATIC or DECL_EXTERNAL.
+ * function.c (put_var_into_stack): Call abort when placing a
+ hard register into the stack, if x_parm_reg_stack_loc is NULL.
+
+2004-03-08 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*extendqidi2_short_displ"): Add CC clobber.
+ ("*extendqisi2_short_displ"): Likewise.
+
+2004-03-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/pdp11/pdp11.c (comparison_operator_index): Remove.
+ (comp_operator): Likewise.
+ * config/pdp11/pdp11-protos.h: Remove corresponding
+ prototypes.
+
+2004-03-08 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * expr.c (highest_pow2_factor_for_type): Rename into
+ highest_pow2_factor_for_target. Use DECL_ALIGN instead of
+ TYPE_ALIGN when the target is a COMPONENT_REF.
+ (expand_assignment): Ajust call to highest_pow2_factor_for_type.
+
+2004-03-08 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c: Formatting fix.
+ (legitimate_offset_address_p): Correct offset range check.
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Don't override
+ -msoft-float by -mcpu. Consolidate similar code for MASK_MULTIPLE
+ and MASK_STRING.
+
+2004-03-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md (ashrdi3): Do not call ashrdi3_no_power
+ for little endian.
+ ("ashrdi3_no_power"): Disable for little endian.
+ (ashrdi3): Same.
+
+2004-03-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fold-const.c (tree_expr_nonnegative_p): Reformat checks for
+ builtins.
+
+2004-03-08 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/14471
+ * configure.ac (Target-specific assembler checks) <cris-*-*>: New
+ case, checking for -no-mul-bug-abort option.
+ * configure, config.in: Regenerate.
+ * doc/invoke.texi (CRIS Options): Document -mmul-bug-workaround
+ and -mno-mul-bug-workaround.
+ * config/cris/cris.md ("smulsi3_highpart", "umulsi3_highpart")
+ ("mulsidi3", "umulsidi3"): Prefix output template with "%!".
+ ("umulhisi3", "umulqihi3", "mulsi3", "mulqihi3", "mulhisi3"):
+ Ditto. Make attribute "slottable" dependent on TARGET_MUL_BUG.
+ * config/cris/mulsi3.asm (__Mul) [__CRIS_arch_version >= 10]: Make
+ sure mulu.d is not last on cache-line.
+ * config/cris/cris.h (ASM_SPEC): Translate -mno-mul-bug-workaround
+ into -no-mul-bug-abort depending on HAVE_AS_MUL_BUG_ABORT_OPTION.
+ (TARGET_MASK_MUL_BUG, TARGET_MUL_BUG): New macros.
+ (TARGET_SWITCHES): New options -mmul-bug-workaround and
+ -mno-mul-bug-workaround.
+ (TARGET_DEFAULT): Include TARGET_MASK_MUL_BUG.
+ (PRINT_OPERAND_PUNCT_VALID_P): Include '!'.
+ * config/cris/cris.c (cris_operand_extend_operator): Clarify
+ relation to MULT in head comment.
+ (cris_op_str): Abort for MULT.
+ (cris_print_operand) <case '!'>: New case.
+
+2004-03-08 Alan Modra <amodra@bigpond.net.au>
+
+ PR debug/11983
+ * dwarf2out.c (enum dw_val_class): Rename dw_val_class_float to
+ dw_val_class_vec. Replace use throughout file.
+ (dw_float_const): Delete.
+ (dw_vec_const): New.
+ (dw_val_struct_union): Rename val_float to val_vec. Replace use
+ throughout file.
+ (add_AT_vec): Rename from add_AT_float. Add elt_size param.
+ (same_dw_val_p): Adjust vec comparison. Use memcmp.
+ (size_of_die): Adjust dw_val_class_vec sizing.
+ (output_die): Output dw_val_class_vec.
+ (insert_int, extract_int, insert_float): New functions.
+ (add_const_value_attribute): Use insert_float for CONST_DOUBLE.
+ Handle CONST_VECTOR.
+ (add_location_or_const_value_attribute): Handle CONST_VECTOR.
+
+2004-03-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_parse_abi_options): SPE and
+ AltiVec abi cannot co-exist.
+
+ * config/rs6000/eabispe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Same.
+
+2004-03-07 Jan Hubicka <jh@suse.cz>
+
+ * except.c (emit_to_new_bb_before): Break fallthru edges.
+
+2004-03-07 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*lshrsi3_const"): Disable for 68HC12.
+ ("*lshrsi3"): Also accept an immediate for 68HC12.
+ ("*ashrsi3_const"): Likewise.
+ ("*ashrsi3"): Likewise.
+ ("*ashlsi3_const"): Likewise.
+ ("*ashlsi3"): Likewise.
+ ("cmphi_1_hc12"): Compare two hard register by pushing them and
+ comparing with a pop; don't use a split for that.
+ ("cmphi split"): Disable compare split for 68HC12.
+
+ * config/m68hc11/m68hc11.c (m68hc11_notice_update_cc): Invalidate
+ the status operands if they have side effects.
+
+2004-03-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * defaults.h (LEGITIMIZE_ADDRESS): Provide a default
+ definition.
+ * config/arc/arc.h, config/fr30/fr30.h, config/frv/frv.h,
+ config/h8300/h8300.h, config/ia64/ia64.h,
+ config/mcore/mcore.h, config/mmix/mmix.h,
+ config/ns32k/ns32k.h, config/pdp11/pdp11.h,
+ config/stormy16/stormy16.h, config/v850/v850.h,
+ config/vax/vax.h (LEGITIMIZE_ADDRESS): Remove.
+ * doc/tm.texi (LEGITIMIZE_ADDRESS): Mention the default
+ definition.
+
+2004-03-07 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <IOR_EXPR>: Fold x | x as x.
+ <XOR_EXPR>: Fold x ^ x as zero.
+ <AND_EXPR>: Fold x & x as x.
+
+2004-03-07 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <EQ_EXPR>: Rewrite optimization to transform
+ "foo++ == const" into "++foo == const+incr".
+
+2004-03-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_in_small_data_p): Return false if
+ TARGET_ABICALLS.
+
+2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Use 2,-sp to push
+ the stack register.
+ (expand_prologue): Don't make an interrupt or a trap handler a far
+ symbol.
+ (m68hc11_initial_elimination_offset): Likewise.
+
+2004-03-06 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_in_small_data_p): False for functions.
+
+2004-03-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ns32k/ns32k-protos.h: Add a prototype for
+ ns32k_notice_update_cc.
+ * config/ns32k/ns32k.c (ns32k_notice_update_cc): New.
+ * config/ns32k/ns32k.h (NOTICE_UPDATE_CC): Call
+ ns32k_notice_update_cc.
+
+2004-03-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("load_multiple", "*load_multiple_di",
+ "*load_multiple_si"): Allow only if reload_completed.
+ ("store_multiple", "*store_multiple_di", "*store_multiple_si"):
+ Likewise.
+
+2004-03-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/vax/vax-protos.h: Add a prototype for
+ vax_notice_update_cc.
+ * config/vax/vax.c (vax_notice_update_cc): New.
+ * config/vax/vax.h (NOTICE_UPDATE_CC): Call
+ vax_notice_update_cc.
+
+2004-03-06 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (main): Only export initfunc and finifunc if
+ LD_INIT_SWITCH not defined.
+ (scan_prog_file): Only export constructors and destructors if
+ LD_INIT_SWITCH not defined. Only export symbols not found in
+ shared objects.
+
+2004-03-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md (icacheflush): Reorder operands to make match_scratch operand
+ last.
+ * pa.h (INITIALIZE_TRAMPOLINE): Remove unnecessary scratch argument
+ from calls to gen_icacheflush.
+
+2004-03-06 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.h (MASK_LONG_DOUBLE_128): New.
+ (TARGET_LONG_DOUBLE_128): New.
+ (TARGET_SWITCHES): Add long-double-{128,64}.
+ (TARGET_HAS_XFLOATING_LIBS): Default to TARGET_LONG_DOUBLE_128.
+ (LONG_DOUBLE_TYPE_SIZE): Honor TARGET_LONG_DOUBLE_128.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New.
+ (WIDEST_HARDWARE_FP_SIZE): New.
+ (TARGET_CPU_CPP_BUILTINS): Define __LONG_DOUBLE_128__.
+ * config/alpha/alpha.c (override_options): Clear MASK_LONG_DOUBLE_128
+ if TARGET_VAX_FLOAT.
+ * config/alpha/osf5.h (LONG_DOUBLE_TYPE_SIZE): Remove.
+ (TARGET_DEFAULT): Set MASK_LONG_DOUBLE_128.
+
+2004-03-06 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_swapped_comparison_operator): Fix
+ botched rtx class conversion.
+
+2004-03-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * tree.h (BUILTIN_EXP10_P, BUILTIN_EXPONENT_P, BUILTIN_SQRT_P,
+ BUILTIN_CBRT_P, BUILTIN_ROOT_P): New macros.
+
+ * builtins.c (fold_builtin_logarithm, fold_builtin): Use new
+ macros.
+ * fold-const.c (fold_mathfn_compare, fold): Likewise.
+
+2004-03-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/14343
+ * config/i386/i386.md (movv2di_internal): Conditionalize on
+ TARGET_SSE, not TARGET_SSE2.
+
+2004-03-05 Chris Demetriou <cgd@broadcom.com>
+
+ * config.gcc (mips64orion-*-elf*, mips64orionel-*-elf*): Delete
+ duplicated line.
+
+2004-03-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c: Consistently use logN not log* in comments.
+
+2004-03-05 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * rtl.h (mem_expr_equal_p): Function prototype added.
+ * cfgcleanup.c (merge_memattrs): New function.
+ (flow_find_cross_jump): Call merge_memattrs for matching insns.
+ * emit-rtl.c (mem_expr_equal_p): New function.
+
+2004-03-05 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (synth_module_prologue): Const-qualify
+ objc_selector type if using the GNU runtime; fix generated
+ signatures for objc_msg_lookup and objc_msg_lookup_super
+ to match what GNU ObjC headers provide; reformat and clean up.
+ (synth_self_and_ucmd_args): Use previously constructed (and
+ hence possibly const-qualified) objc_selector type.
+
+2004-03-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi (HARD_REGNO_RENAME_OK): Document.
+
+2004-03-05 Jason Merrill <jason@redhat.com>
+
+ * tree.h (TYPE_HASH): Use TYPE_UID.
+ (TREE_HASH): New macro with old definition of TYPE_HASH.
+ * tree.c (build_type_attribute_variant): Use iterative_hash_object.
+ (build_array_type, build_function_type): Likewise.
+ (build_method_type_directly): Likewise.
+ (build_offset_type, build_complex_type): Likewise.
+ (type_hash_list, attribute_hash_list): Likewise. Now static.
+ * except.c: s/TYPE_HASH/TREE_HASH/.
+
+2004-03-05 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (function_arg): Handle 16-byte aligned args.
+ (xtensa_va_start): Initialize __va_stk to ($arg_ptr - 32). Adjust
+ __va_ndx by 2 words when referencing an argument on the stack.
+ (xtensa_va_arg): Handle 16-byte aligned args. Adjust __va_ndx by 2
+ words when an arg on the stack is first seen.
+
+2004-03-05 Paul Brook <paul@codesourcery.com>
+
+ * arm.h (ARM_FLAG_VFP): Remove.
+ (ARM_FLAG_ATPCS, CIRRUS_FIX_INVALID_INSNS): Renumber.
+ * netbsd-elf.h (ARM_FLAG_VFP): Remove.
+
+2004-03-05 Paul Brook <paul@codesourcery.com>
+
+ * function.c (assign_parms): Include pretend alignment offset.
+
+2004-03-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (layout_type, case FUNCTION_TYPE): Make size
+ FUNCTION_BOUNDARY, not POINTER_SIZE * 2.
+
+2004-03-05 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * configure.ac: When passing --enable-languages to subdir
+ configure when host != build, make sure we don't pass an empty
+ value.
+ * configure: Regenerate.
+
+2004-03-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR 13577
+ * gcc.c (cc1_options): Robustify -auxbase-strip from multiple -o
+ options.
+
+2004-03-05 Paolo Bonzini <bonzini@gnu.org>
+
+ * simplify-rtx.c (simplify_relational_operation): If
+ flag_wrapv is set, do not move terms between the two
+ side of a relational operator.
+
+2004-03-05 Paolo Bonzini <bonzini@gnu.org>
+
+ * rtlanal.c: Include target.h and output.h
+ (rtx_cost, address_cost, default_address_cost): Move from...
+ * cse.c (rtx_cost, address_cost, default_address_cost):
+ ... this file.
+ * rtl.h (rtx_cost, address_cost): Move under rtlanal.c.
+ * Makefile.in: Adjust dependencies.
+
+2004-03-05 Paolo Bonzini <bonzini@gnu.org>
+
+ * cse.c (cse_end_of_basic_block): Make static.
+ * local-alloc.c (function_invariant_p): Move to
+ reload1.c.
+ * loop.c (libcall_other_reg, record_excess_regs):
+ Make static.
+ * reload1.c (function_invariant_p): Moved here
+ from local-alloc.c, made static.
+ * rtl.h (cse_end_of_basic_block, function_invariant_p,
+ libcall_other_reg, record_excess_regs): Remove
+ declarations.
+
+2004-03-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c (signed_comparison_operator): Add a
+ missing parenthesis.
+
+2004-03-04 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * ggc-common.c (gt_pch_restore): Don't unmap addr unless we are
+ going to call mmap again. Read the file into the right place.
+ Give a fatal error if we have to relocate.
+
+2004-03-04 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_return_in_msb): New function.
+ (TARGET_RETURN_IN_MSB): Define to xtensa_return_in_msb.
+
+2004-03-05 Hans-Peter Nilsson <hp@axis.com>
+
+ PR other/14354
+ * config/fp-bit.c (_fpdiv_parts): Do not round when pack_d would
+ round the same. When rounding, clear bits that would cause a
+ second rounding in pack_d.
+ (_fpmul_parts): Ditto. Remove #if 0:d code.
+
+2004-03-04 Ziemowit Laski <zlaski@apple.com>
+
+ PR c++/14425, c++/14426
+ * config/rs6000/altivec.h (vec_splat_s8, vec_splat_s16,
+ vec_splat_s32, vec_splat_u8, vec_splat_u16, vec_splat_u32):
+ Change C++ definitions to accept a 'const int' argument;
+ the prototypes already do.
+ * config/rs6000/rs6000.c (rs6000_common_init_builtins):
+ Rename v4si_ftype_char, v8hi_ftype_char, v16qi_ftype_char,
+ v4sf_ftype_v4si_char, v4si_ftype_v4sf_char, v4si_ftype_v4si_char,
+ v8hi_ftype_v8hi_char, v16qi_ftype_v16qi_char,
+ v16qi_ftype_v16qi_v16qi_char, v8hi_ftype_v8hi_v8hi_char,
+ v4si_ftype_v4si_v4si_char and v4sf_ftype_v4sf_v4sf_char to
+ end in ..._int; change them to accept an int instead of a char
+ as the last parameter.
+
+2004-03-04 Phil Edwards <phil@codesourcery.com>
+
+ * genmultilib: Change '=' to '-' when translating option names
+ to directory names.
+
+2004-03-04 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr_real, case COMPONENT_REF): Get proper type of
+ stack slot for temp used for result of BLKmode but in integral mode.
+
+2004-03-04 Jan Hubicka <jh@suse.cz>
+
+ * reload.c (find_reloads): Reorganize if seqeunce to switch.
+
+ * cfgrtl.c (rtl_redirect_edge_and_branch): Set the source BB as dirty.
+ (cfglayout_redirect_edge_and_branch): Set the source BB as dirty.
+
+2004-03-04 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.md (divdf3_internal_thr): Fix algorithm.
+ * testsuite/gcc.dg/20040303-1.c: New test.
+
+2004-03-04 Steven Bosscher <stevenb@suse.de>
+
+ * ppro.md: Rewrite as a DFA pipeline description.
+ * i386.md: Remove all uses of the ppro_uops attribute.
+ * i386.c: (ix86_safe_ppro_uops, ix86_dump_ppro_packet,
+ ix86_reorder_insn, ix86_sched_reorder_ppro, ix86_sched_init,
+ ix86_sched_reorder, ix86_variable_issue,
+ struct ix86_sched_data, TARGET_SCHED_VARIABLE_ISSUE,
+ TARGET_SCHED_INIT, TARGET_SCHED_REORDER): Remove.
+ (ia32_use_dfa_pipeline_interface): Add TARGET_PENTIUMPRO.
+ (ia32_multipass_dfa_lookahead): Add TARGET_PENTIUMPRO.
+ * athlon.md (athlon_ssecmp_load): Fix comment
+
+2004-03-04 Stuart Hastings <stuart@apple.com>
+
+ * gcc/doc/invoke.texi: Document -mlongcall for Darwin/PPC.
+
+2004-03-04 Stuart Hastings <stuart@apple.com>
+
+ * gcc/config/i386/darwin.h: Darwin/x86 doesn't support CPUs before
+ 686, tell Darwin assembler to allow prefetch insns, non-empty def
+ of SUBTARGET_OPTION_TRANSLATE_TABLE.
+
+2004-03-04 DJ Delorie <dj@redhat.com>
+
+ PR optimization/14282
+ * sched-deps.c (sched_analyze_insn): Allow a stack adjustment
+ between a call and the assignment of its return value.
+
+2004-03-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Put a comment for every function.
+
+2004-03-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Add comments about peephole2's.
+
+2004-03-04 Steven Bosscher <stevenb@suse.de>
+
+ * i386.h (TARGET_CPU_DEFAULT_nocona): Fix value.
+
+2004-03-04 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (thread_jump): Update call of cselib_init.
+ * cselib.c (cselib_record_memory): New static variable.
+ (cselib_lookup_mem, cselib_record_set, cselib_record_sets):
+ Give up on memories when asked for.
+ (cselib_init): Accept new argument.
+ * cselib.h (cselib_init): Update prototype.
+ * gcse.c (local_cprop_pass): Update call of cselib_init.
+ * loop.c (load_mems): Update call of cselib_init.
+ * postreload.c (reload_cse_regs_1): Update call of cselib_init.
+ * sched-deps.c (sched_analyze): Update call of cselib_init.
+
+2004-03-04 David Edelsohn <edelsohn@gnu.org>
+ GP <gp@qnx.com>
+
+ * config/rs6000/rs6000.c (output_function_profiler): Append @plt
+ when compiling PIC.
+
+2004-03-04 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/14362
+ * var-tracking.c (track_expr_p): Do not track variables which
+ should be ignored for debugging purposes.
+
+2004-03-04 Alan Modra <amodra@bigpond.net.au>
+
+ * real.c (encode_ibm_extended): Don't bother rounding low double.
+ * c-cppbuiltin.c (builtin_define_float_constants): Tweak MAX
+ when fmt->pnan < fmt->p.
+
+2004-03-04 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.h (FUNCTION_ARG_REGNO_P): Fix to check
+ only range of valid arg registers and fixed_regs.
+
+2004-03-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14406
+ * config/rs6000/rs6000.md (abstf2, abstf2+1): Delete define_insn.
+ (abstf2, abstf2_internal): New define_expand.
+
+2004-03-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/14235
+ * expr.c (convert_move): Copy the source to a new pseudo
+ when converting from a sub-word source to a larger-than-word
+ register which conflicts with the source.
+
+2004-03-03 Zack Weinberg <zack@codesourcery.com>
+
+ PR 13728
+ * c-decl.c (diagnose_mismatched_decls): Issue an error for two
+ parameters with the same name, unless one is a forward decl.
+ Do not issue a redundant-redeclaration warning for forward
+ decls of parameters.
+
+2004-03-04 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (*-ibm-aix*): Document use of Bash to speed up
+ configuration.
+
+2004-03-03 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * ggc-zone.c (ggc_pch_write_object): Don't align file pointer.
+
+2004-03-04 Alan Modra <amodra@bigpond.net.au>
+
+ * target-def.h (TARGET_OPTF): Delete.
+ * c-opts.c (TARGET_OPTF): Define.
+
+2004-03-04 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (cselib_finish): Fix another miss-application of my previous
+ patch.
+
+2004-03-03 Mike Stump <mrs@apple.com>
+
+ Add framework support for darwin.
+
+ * c-incpath.c: Include target.h and machmode.h.
+ (add_path): Use a consistent style for cpp_dir. Initialize
+ p->construct to 0.
+ (add_cpp_dir_path): New.
+ (register_include_chains): Add use of extra_includes callback.
+ (hook_void_int): Add.
+ (target_c_incpath): Add.
+ * c-incpath.h (add_cpp_dir_path): New.
+ (target_c_incpath_s): Add.
+ (target_c_incpath): Add.
+ (C_INCPATH_INIT): Add.
+ * c-opts.c (c_common_missing_argument,
+ c_common_handle_option): Add -F argument processing.
+ * c.opt: Add -F argument processing.
+ * gcc.c (trad_capable_cpp): Add -F argument processing.
+ * cppfiles.c (find_file_in_dir): Update to use construct
+ callback.
+ (search_path_exhausted, cpp_get_path, cpp_get_buffer,
+ cpp_get_prev): New.
+ (_cpp_find_file): Use search_path_exhausted.
+ (make_cpp_dir): Initialize construct to 0.
+ * cpplib.h (missing_header_cb
+ cpp_get_path, cpp_get_buffer, cpp_get_file, cpp_get_prev): New.
+ (cpp_callbacks): Add missing_header
+ (cpp_dir): Add construct.
+ * target-def.h: (TARGET_OPTF): New.
+ * hooks.c (hook_void_int, hook_void_charptr): Add.
+ * hooks.h (hook_void_int, hook_void_charptr): Add.
+ * Makefile.in (c-incpath.o) : Add $(TARGET_H) and
+ $(MACHMODE_H) dependencies.
+ * doc/invoke.texi (Darwin Options): Document -F.
+ * doc/tm.texi (TARGET_EXTRA_INCLUDES): Add.
+ (TARGET_OPTF): Add.
+ * fix-header.c (target_c_incpath): Add.
+
+ * config/darwin-c.c: Add c-incpath.h include.
+ (using_frameworks, find_subframework_file,
+ find_subframework_header, add_system_framework_path,
+ frameworks_in_use, num_frameworks, max_frameworks,
+ add_framework, find_framework, struct framework_header,
+ framework_header_dirs, framework_construct_pathname,
+ find_subframework_file, add_system_framework_path,
+ add_framework_path, framework_defaults,
+ darwin_register_frameworks, find_subframework_header): Add.
+ * config/darwin.h (TARGET_EXTRA_INCLUDES, TARGET_OPTF): New.
+ (TARGET_OPTION_TRANSLATE_TABLE): Add -framework support.
+ (CPP_SPEC): Add __APPLE_CC__ support.
+ * t-darwin (darwin-c.o): Add c-incpath.h dependency.
+
+2004-03-04 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (cselib_finish): Fix miss-application of my previous
+ patch.
+
+2004-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * hooks.c (hook_tree_tree_identity): New.
+ * hooks.h: Add a prototype for hook_tree_tree_identity.
+ * stmt.c (expand_asm_operands): Use targetm.md_asm_clobbers
+ instead of MD_ASM_CLOBBERS.
+ * system.h (MD_ASM_CLOBBERS): Poison.
+ * target-def.h (TARGET_MD_ASM_CLOBBERS): New.
+ (TARGET_INITIALIZER): Add TARGET_MD_ASM_CLOBBERS.
+ * target.h (gcc_target): Add md_asm_clobbers.
+ * config/i386/i386.c (TARGET_MD_ASM_CLOBBERS): New.
+ (ix86_md_asm_clobbers): New.
+ * config/i386/i386.h (MD_ASM_CLOBBERS): Remove.
+ * doc/tm.texi (MD_ASM_CLOBBERS): Change to
+ TARGET_MD_ASM_CLOBBERS.
+
+2004-03-03 Stuart Hastings <stuart@apple.com>
+
+ * gcc/config.gcc: Arrange for Darwin/x86 to build libgcc_eh.a.
+
+2004-03-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (noov_compare64_op): Fix typo.
+
+ * config/sparc/sparc.h (ASM_FLOAT): Delete.
+ (ASM_DOUBLE): Likewise.
+ (ASM_LONGDOUBLE): Likewise.
+ * config/sparc/pbd.h (ASM_INT_OP): Delete.
+
+2004-03-03 Richard Henderson <rth@redhat.com>
+
+ PR opt/13862
+ * cselib.c (cselib_record_sets): Don't record multiple sets in
+ asm insns.
+
+2004-03-03 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * common.opt: Add description of the new -fgcse-after-reload flag.
+
+ * flags.h (flag_gcse_after_reload): Declaration of global variable.
+
+ * gcse.c (reg_used_on_edge ,reg_set_between_after_reload_p,
+ reg_used_between_after_reload_p, rtx get_avail_load_store_reg,
+ is_jump_table_basic_block, bb_has_well_behaved_predecessors,
+ get_bb_avail_insn, hash_scan_set_after_reload,
+ compute_hash_table_after_reload, eliminate_partially_redundant_loads,
+ gcse_after_reload, get_bb_avail_insn): New functions to implement
+ gcse-after-reload.
+ (gcse_after_reload_main): New function, the main entry point to
+ gcse-after-reload.
+
+ * rtl.h (gcse_after_reload_main): Declaration of the new function.
+
+ * opts.c (common_handle_option): Handle the -fgcse-after-reload flag.
+
+ * toplev.c (flag_gcse_after_reload): Initialization.
+
+ * passes.c (rest_of_handl_gcse2): Call gcse_after_reload_main.
+
+ * params.def (PARAM_GCSE_AFTER_RELOAD_PARTIAL_FRACTION,
+ PARAM_GCSE_AFTER_RELOAD_CRITICAL_FRACTION): New parameters for tuning
+ the gcse after reload optimization.
+
+ * params.h (GCSE_AFTER_RELOAD_PARTIAL_FRACTION,
+ GCSE_AFTER_RELOAD_CRITICAL_FRACTION): Two macros to access the tuning
+ parameters.
+
+ * doc/invoke.texi: Documentation for the new flag gcse-after-reload.
+
+2004-03-03 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/ieee754-df.S (muldf3, divdf3): Fix denormalization of
+ small negative values.
+
+2004-03-03 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (hash_table): Remove GTY marker.
+ (reg_values): Turn into array.
+ (used_regs): Likewise.
+ (n_used_regs): New static variable.
+ (reg_values_old): Kill.
+ (clear_table): Update uses of arrays.
+ (cselib_lookup): Likewise.
+ (cselib_record_set): Likewise.
+ (cselib_init): Likewise.
+ (cselib_finish): Likewise.
+ (cselib_udpate_varray_sizes): Kill.
+ * cselib.h (cselib_update_varray_sizes): Kill.
+
+2004-03-03 Paul Brook <paul@codesourcery.com>
+
+ * flow.c (ior_reg_cond, and_reg_cond): Remove stray ")".
+
+2004-03-03 Jan Hubicka <jh@suse.cz>
+
+ * ggc-common.c (ggc_alloc_cleared_stat, ggc_realloc_stat):
+ Rename from ...; make statistics transparent.
+ (ggc_alloc_cleared, ggc_realloc_stat): ... these.
+ (loc_descriptor): New structure.
+ (hash_descriptor, eq_descriptor, loc_descriptor, cmp_statistics,
+ add_statistics):
+ New static function.
+ (ggc_record_overhead, dump_statistics): New global function.
+ * ggc-none.c (ggc_alloc_types_stat, ggc_alloc_stat, ggc_alloc_zone_stat,
+ ggc_alloc_cleared_stat, ggc_realloc_stat, ggc_alloc_typed_stat): Rename
+ from ...; accept locations
+ (ggc_alloc_types, ggc_alloc, ggc_alloc_zone, ggc_alloc_cleared,
+ ggc_realloc, ggc_alloc_typed): ... this one.
+ from ...; accept locations
+ * ggc-page.c (ggc_alloc_typed_stat, ggc_alloc_zone_stat,
+ ggc_alloc_stat): Rename from ... ; pass locations
+ * ggc-page.c (ggc_alloc_typed, ggc_alloc_zone, ggc_alloc):
+ ... this one.
+ (ggc_alloc_stat): Record overehead.
+ * ggc.h (ggc_alloc_types, ggc_alloc, ggc_alloc_zone, ggc_alloc_cleared,
+ ggc_realloc, ggc_alloc_typed): Turn to macros
+ (ggc_alloc_types_stat, ggc_alloc_stat, ggc_alloc_zone_stat,
+ ggc_alloc_cleared_stat, ggc_realloc_stat, ggc_alloc_typed_stat): Declare.
+ (dump_ggc_loc_satistics, ggc_record_overehead): Declare.
+ * langhooks.h (lhd_make_node): Declare.
+ (LANG_HOOKS_MAKE_TYPE): Default to new function,
+ * langhooks.c (lhd_make_node): New.
+ * rtl.c (rtx_alloc_stat, swallow_copy_rtx_stat): Rename from ... ; pass
+ locations.
+ (rtx_alloc, swallow_copy_rtx): ... this one.
+ * rtl.h (rtx_alloc, swallow_copy_rtx): Turn to macros.
+ * rtl.c (rtx_alloc_stat, swallow_copy_rtx_stat): Declare.
+ * toplpev.c (finalize): Dump stats.
+ * tree.c (make_node_stat, copy_node_stat, make_tree_vec_stat,
+ build_tree_list_stat, tree_cons_stat, build?_stat, build_decl_stat):
+ Rename from ... ; pass locators.
+ (make_node, copy_node, make_tree_vec, build_tree_list, tree_cons,
+ build?, build_decl): Declare.
+ * tree.h (make_node_stat, copy_node_stat, make_tree_vec_stat,
+ build_tree_list_stat, tree_cons_stat, build?_stat, build_decl_stat):
+ Declare.
+ (make_node, copy_node, make_tree_vec, build_tree_list, tree_cons,
+ build?, build_decl): New macros.
+ * Makefile.in (RTL_H, TREE_H): Add statistics.h dependency.
+ * statistics.h: New file.
+
+2004-03-03 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MASK_FIX_SB1): Bump.
+ (MASK_FIX_R4400, TARGET_FIX_R4400): New macros.
+ (TARGET_SWITCHES): Add -mfix-r4400 and -mno-fix-r4400.
+ * config/mips/mips.c (mips_output_division): Fill the branch delay
+ slot with a nop if TARGET_FIX_R4000. Extend R4000 workarounds to
+ TARGET_FIX_R4400.
+ (mips_output_division): Adjust accordingly.
+ (override_options): Make -march=r4400 imply -mfix-r4400 by default.
+ * doc/invoke.texi: Document -mfix-r4400 and new errata workarounds.
+
+2004-03-03 Paolo Bonzini <bonzini@gnu.org>
+
+ * alias.c (rtx_equal_for_memref_p): Use predicates
+ to test rtx classes and new rtx class codes, possibly
+ splitting conditionals that tested against '<' and 'o'.
+ * caller-save.c (save_call_clobbered_regs): Likewise.
+ * combine.c (contains_muldiv, find_split_point, subst,
+ combine_simplify_rtx, simplify_if_then_else,
+ simplify_set, simplify_logical, expand_compound_operation,
+ make_compound_operation, if_then_else_cond, known_cond,
+ apply_distributive_law, cached_nonzero_bits,
+ cached_num_sign_bit_copies, simplify_shift_const,
+ gen_binary, simplify_comparison, update_table_tick,
+ record_value_for_reg, get_lsat_value_validate): Likewise.
+ * cse.c (mention_regs, find_best_addr, find_comparison_args,
+ fold_rtx, cse_insn, invalidate_memory, cse_basic_block):
+ Likewise.
+ * emit-rtl.c (copy_insn_1): Likewise.
+ * expr.c (force_operand): Likewise.
+ * final.c (final_scan_insn, get_mem_expr_from_op): Likewise.
+ * flow.c (notice_stack_pointer_modification_1,
+ invalidate_mems_from_autoinc, ior_reg_cond, not_reg_cond,
+ and_reg_cond, elim_reg_cond): Likewise.
+ * function.c (update_epilogue_consts): Likewise.
+ * genattrtab.c (attr_rtx_1): Likewise.
+ * genopinit.c (gen_insn): Likewise.
+ * integrate.c (subst_constants): Likewise.
+ * jump.c (reversed_comparison_code_parts,
+ reversed_comparison_code, delete_related_insns,
+ rtx_renumbered_equal_p): Likewise.
+ * local-alloc.c (block_alloc): Likewise.
+ * loop.c (rtx_equal_for_prefetch_p, maybe_eliminate_biv,
+ canonicalize_condition): Likewise.
+ * loop-iv.c (simplify_using_conditions, iv_number_of_iterations):
+ Likewise.
+ * optabs.c (add_equal_node, expand_binop): Likewise.
+ * predict.c (estimate_probability): Likewise.
+ * ra-debug.c (ra_print_rtx_2op, ra_print_rtx): Likewise.
+ * recog.c (validate_replace_rtx_1, comparison_operator,
+ offsettable_address_p, constrain_operands): Likewise.
+ * reg-stack.c (swap_rtx_condition_1, subst_stack_regs_pat):
+ Likewise.
+ * regclass.c (scan_one_insn): Likewise.
+ * regmove.c (stable_and_no_regs_but_for_p): Likewise.
+ * regrename.c (kill_autoinc_value): Likewise.
+ * reload.c (find_reusable_reload, find_reloads,
+ reg_overlap_mentioned_for_reload_p): Likewise.
+ * reload1.c (gen_reload, delete_address_reloads_1): Likewise.
+ * rtl.c (copy_rtx): Likewise.
+ * rtl.h (CONSTANT_P, INSN_P): Likewise.
+ * rtlanal.c (commutative_operand_precedence): Likewise.
+ * sched-deps.c (conditions_mutex_p): Likewise.
+ * sched-rgn.c (is_cfg_nonregular): Likewise.
+ * simplify-rtx.c (simplify_gen_binary,
+ simplify_gen_relational, simplify_replace_rtx,
+ simplify_unary_operation, simplify_binary_operation,
+ simplify_ternary_operation, simplify_rtx): Likewise.
+ * unroll.c (reg_dead_after_loop): Likewise.
+ * config/alpha/alpha.c (alpha_swapped_comparison_operator,
+ print_operand): Likewise.
+ * config/arc/arc.c (proper_comparison_operator): Likewise.
+ * config/arm/arm.c (arm_arm_address_cost, arm_select_cc_mode):
+ Likewise.
+ * config/avr/avr.c (_reg_unused_after): Likewise.
+ * config/frv/frv.c (frv_ifcvt_modify_tests,
+ frv_ifcvt_modify_insn, frv_pack_insn): Likewise.
+ * config/i386/i386.c (ix86_comparison_operator,
+ ix86_carry_flag_operator, fcmov_comparison_operator,
+ arith_or_logical_operator, print_operand,
+ ix86_expand_binary_operator, ix86_binary_operator_ok):
+ Likewise.
+ * config/i386/i386.md: Likewise.
+ * config/ia64/ia64.c (not_postinc_memory_operand,
+ ia64_print_operand, update_set_flags, errata_emit_nops):
+ Likewise.
+ * config/ia64/ia64.h (PREFERRED_RELOAD_CLASS,
+ CONSTRAINT_OK_FOR_S): Likewise.
+ * config/ip2k/ip2k.c (mdr_resequence_xy_yx,
+ mdr_try_move_dp_reload, ip2k_check_can_adjust_stack_ref,
+ ip2k_xexp_not_uses_reg_for_mem, ip2k_xexp_not_uses_reg_p,
+ ip2k_composite_xexp_not_uses_reg_p, ip2k_unary_operator):
+ Likewise.
+ * config/iq2000/iq2000.c (cmp_op, symbolic_expression_p,
+ eqne_comparison_operator, signed_comparison_operator):
+ Likewise.
+ * config/mips/mips.c (cmp_op, symbolic_expression_p):
+ Likewise.
+ * config/mmix/mmix (mmix_foldable_comparison_operator,
+ mmix_comparison_operator): Likewise.
+ * config/pa/pa.c (hppa_legitimize_address): Likewise.
+ * config/rs6000/rs6000.c (stmw_operation,
+ branch_comparison_operator, trap_comparison_operator,
+ ccr_bit): Likewise.
+ * config/rs6000/rs6000.h (SELECT_CC_MODE): Likewise.
+ * config/s390/s390.c (s390_alc_comparison,
+ s390_slb_comparison):L Likewise.
+ * config/sh/sh.c (gen_block_redirect, reg_unused_after):
+ Likewise.
+ * config/sparc/sparc.c (eq_or_neq, normal_comp_operator,
+ noov_compare_op, noov_compare64_op, v9_regcmp_op,
+ emit_hard_tfmode_operation, reg_unused_after)
+ * doc/md.texi, doc/rtl.texi: Likewise.
+
+ * ra-debug.c: Add 2004 to list of copyright years.
+ * unroll.c: Likewise.
+
+ * combine.c (simplify_logical): Remove dummy test,
+ (apply_distributive_law): Fix typo in comment.
+ GET_CODE (x) == AND so x is a commutative binary op.
+ * jump.c (delete_related_insns): simplify loop
+ condition, move testing of RTX codes inside the loop.
+ (rtx_renumbered_equal_p): do not use RTX_CODE.
+ * rtl.c (rtx_class): Declare as enum rtx_class.
+ * rtl.def (EQ, NE, UNEQ, LTGT, UNORDERED, ORDERED):
+ Move to RTX_COMM_COMPARE class.
+ (HIGH, SYMBOL_REF, LABEL_REF, CONST, CONST_INT, CONST_DOUBLE):
+ Move to RTX_CONST_OBJ class.
+ * rtl.h (enum rtx_class): New declaration,
+ (RTX_OBJ_MASK, RTX_OBJ_RESULT, RTX_COMPARE_MASK,
+ RTX_COMPARE_RESULT, RTX_ARITHMETIC_MASK, RTX_ARITHMETIC_RESULT,
+ RTX_BINARY_MASK, RTX_BINARY_RESULT, RTX_COMMUTATIVE_MASK,
+ RTX_COMMUTATIVE_RESULT, RTX_NON_COMMUTATIVE_RESULT,
+ RTX_EXPR_FIRST, RTX_EXPR_LAST, UNARY_P, BINARY_P,
+ ARITHMETIC_P, COMMUTATIVE_ARITHMETIC_P, COMPARISON_P,
+ SWAPPABLE_OPERANDS_P, NON_COMMUTATIVE_P, COMMUTATIVE_P,
+ OBJECT_P): New macros.
+ * config/sparc/sparc.c (noov_compare_op): Remove register
+ from parameter.
+
+2004-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * target.h: Remove texi jargons in comments.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___fixunssfsi): Change the
+ threshold to 0x4f.
+
+ Revert:
+ 2004-02-27 Kazu Hirata <kazu@cs.umass.edu>
+ * config/h8300/fixunssfsi.c (__fixunssfsi): Enable on H8/300
+ as well.
+ * config/h8300/lib1funcs.asm (___fixunssfsi): Remove.
+ * config/h8300/t-h8300 (LIB1ASMFUNCS): Remove _fixunssfsi_asm.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/md.texi (cbranchmode4): New.
+
+2004-03-02 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips16.S: Change fixsfsi and fixdfsi to
+ fix_trunc.
+ * config/mips/mips.c (mips_init_libfuncs): Change accordingly.
+ * config/mips/t-elf (LIB1ASMFUNCS): Ditto.
+ * config/mips/t-isa3264 (LIB1ASMFUNCS): Ditto.
+ * config/mips/t-r3900 (LIB1ASMFUNCS): Ditto.
+
+2004-03-02 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/11767
+ * coverage.c (coverage_counter_ref): Set MEM_NOTRAP_P.
+ * optabs.c (prepare_cmp_insn): Force trapping memories to registers
+ before the compare, if flag_non_call_exceptions.
+
+2004-03-02 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14327
+ * stmt.c (expand_computed_goto): Do do_pending_stack_adjust before
+ emitting the label, not after.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_addr_mode): New variable.
+ (m68hc11_mov_addr_mode): Likewise.
+ (m68hc11_override_options): Initialize them based on target.
+ (register_indirect_p): Allow a MEM for indirect addressing modes and
+ use flags to control what is allowed.
+ (m68hc11_small_indexed_indirect_p): Use m68hc11_mov_addr_mode for
+ supported addressing modes.
+ (m68hc11_register_indirect_p): Use m68hc11_addr_mode.
+ (go_if_legitimate_address_internal): Likewise.
+ (m68hc11_indirect_p): Likewise and check the mode.
+ (print_operand): Allow a (MEM (MEM)) and generate indirect addressing.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c (BUILTIN_SETJMP_FRAME_VALUE): Remove.
+ (expand_builtin_setjmp_setup): Use
+ targetm.builtin_setjmp_frame_value instead of
+ BUILTIN_SETJMP_FRAME_VALUE.
+ * system.h (BUILTIN_SETJMP_FRAME_VALUE): Poison.
+ * target-def.h (TARGET_BUILTIN_SETJMP_FRAME_VALUE): New.
+ (TARGET_INITIALIZER): Add TARGET_BUILTIN_SETJMP_FRAME_VALUE.
+ * target.h (gcc_target): Add builtin_setjmp_frame_value.
+ * targhooks.c (default_builtin_setjmp_frame_value): New.
+ * targhooks.h: Add a prototype for
+ default_builtin_setjmp_frame_value.
+ * doc/tm.texi (BUILTIN_SETJMP_FRAME_VALUE): Change to
+ TARGET_BUILTIN_SETJMP_FRAME_VALUE.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md (move peephole2): New peepholes to optimize
+ sequences of moves.
+ (add peepholes): New peepholes to optimize sequences adding small
+ constants.
+ (bset peepholes): New peepholes to transform an OR in a bset form
+ (bclr peepholes): Likewise for bclr form.
+ (cmp peepholes): New peepholes to avoid register copies when comparing.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*pushdi_internal"): New insn and split
+ to separate push from moves.
+ ("*pushdf_internal"): Likewise.
+ ("*pushsf_internal"): Likewise.
+ ("*pushsi_internal"): Likewise.
+ ("movdi_internal"): Use define_insn_and_split; non push operand.
+ ("movdf_internal"): Likewise.
+ ("movsf_internal"): Likewise.
+ ("movsi_internal"): Likewise.
+ ("*movhi_68hc12", "*addhi3_68hc12"): Fix and tune constraints
+ ("*addhi3", "*subhi3", "*andhi3_mem", "*iorhi3_mem"): Likewise.
+ ("*ashlsi3_const1", "*lshrsi3_const1"): Likewise.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("tstqi_z_used"): Use define_insn_and_split.
+ ("cmphi_z_used", "cmpqi_z_used"): Likewise.
+ ("movstrictsi", "movstricthi", "movstrictqi"): Likewise.
+ ("anddi3", "andsi3", "iordi3", "iorsi3"): Likewise.
+ ("xordi3", "xorsi3", "*logicalsi3_zexthi"): Likewise.
+ ("*logicalsi3_zextqi", "*logicalhi3_zexthi_ashift8"): Likewise.
+ ("logicalhi3_zexthi", "*logicalsi3_silshr16"): Likewise.
+ ("*logicalsi3_silshl16", "*logicalsi3_silshl16_zext"): Likewise.
+ ("*ashldi3_const32", "*ashldi3_const1", "addsi_silshr16"): Likewise.
+ ("addsi_andshr16", "*ashlsi3_const16_zexthi"): Likewise.
+ ("*lshrdi3_const32", "*lshrdi_const1"): Likewise.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md (SOFT_TMP_REGNUM): Define.
+ (SOFT_XY_REGNUM): Define.
+ (cmp split): Use the above instead of hard coded numbers.
+ (8-bit op split): No need to check the mode; allow Q_REG.
+ (ashift split): Adjust the first operand if it uses the SP and we
+ are pushing the shifted value.
+ (plus shift split): Fix when a source is in register D+X.
+ ("doloop_end"): Pass dummy arguments to gen_rtx_NE.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_check_z_replacement): Fix when
+ comparing with Z register.
+
+2004-03-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloop.h (struct loop_desc): Removed.
+ (struct loop): Fields simple, desc and has_desc removed.
+ (simple_loop_p, count_loop_iterations): Declaration removed.
+ * cfgloopanal.c (struct unmark_altered_insn_data): Removed.
+ (unmark_altered, blocks_invariant_registers, unmark_altered_insn
+ blocks_single_set_registers, invariant_rtx_wrto_regs_p_helper,
+ invariant_rtx_wrto_regs_p, test_for_iteration, constant_iterations,
+ simple_loop_exit_p, variable_initial_value, variable_initial_values,
+ simple_condition_p, simple_increment, count_strange_loop_iterations,
+ inverse, fits_in_mode_p, simple_loop_p, count_loop_iterations):
+ Removed.
+ * loop-iv.c (check_simple_exit, find_simple_exit): Update comments.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genattrtab.c: Don't handle MATCH_INSN.
+ * genrecog.c: Likewise.
+ * gensupport.c: Likewise.
+ * rtl.def (match_insn): Remove.
+ * doc/md.texi (match_insn, match_insn2): Remove.
+
+2004-03-02 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/c-tree.texi (DECL_ASSEMBLER_NAME): Mention that using this
+ macro results in memory allocation.
+
+2004-03-02 David O'Brien <obrien@FreeBSD.org>
+
+ * config/freebsd-spec.h (FBSD_DYNAMIC_LINKER): Add.
+ * config/alpha/freebsd.h (SUBTARGET_EXTRA_SPECS): Define
+ %(fbsd_dynamic_linker),
+ (LINK_SPEC): Use %(fbsd_dynamic_linker), and sync style with
+ config/i386/freebsd.h
+ * config/arm/freebsd.h: Ditto.
+ * config/i386/freebsd.h: Ditto.
+ * config/i386/freebsd64.h: Ditto.
+ * config/ia64/freebsd.h: Ditto.
+ * config/rs6000/sysv4.h: Ditto.
+ * config/sparc/freebsd.h: Ditto.
+
+2004-03-02 Loren James Rittle <ljrittle@acm.org>
+
+ * gcc/doc/install.texi (*-*-freebsd*): Update target information.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * rtl.def (define_combine): Remove.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Tweak formatting.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*cmphi_h8300): Rename to
+ *cmphi_h8300_znvc.
+ (*cmphi_h8300hs): Rename to *cmphi_h8300hs_znvc.
+
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR bootstrap/14356
+ * gcc.c (process_command): Remove const-qualification from argv.
+ (main): Likewise.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (pushqi1_h8300hs): Rename to
+ pushqi1_h8300hs_advanced. Adjust its caller.
+ (pushhi1_h8300hs): Rename to pushhi1_h8300hs_advanced.
+ Adjust its caller.
+
+2004-03-02 Nicolas Roche <roche@act-europe.fr>
+
+ * Makefile.in (install-libgcc, install-multilib): Pass
+ mkinstalldirs var to libgcc.mk.
+
+2004-03-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (DBX_OUTPUT_STANDARD_TYPES): Poison.
+ * doc/tm.texi (DBX_OUTPUT_STANDARD_TYPES): Remove.
+
+2004-03-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (gtle_operator): Accept GT and LE.
+ * config/h8300/h8300.md: Split several peephole2's, each into
+ two.
+
+2004-03-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * dominance.c (recount_dominator): Handle postdominators.
+
+2004-03-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (enum mips_symbol_type): Move from mips.h.
+ (NUM_SYMBOL_TYPES): Likewise.
+ (SYMBOL_64_HIGH, SYMBOL_64_MID, SYMBOL_64_LOW): New symbol types.
+ (mips_unspec_address): Declare.
+ (mips_gotoff_page, mips_gotoff_global): Delete.
+ * config/mips/mips.h (PREDICATE_CODES): Add general_symbolic_operand.
+ * config/mips/mips.c (enum mips_symbol_type, NUM_SYMBOL_TYPES): Delete.
+ (mips_symbolic_constant_p, mips_symbolic_address_p)
+ (mips_symbol_insns): Handle new symbol types.
+ (general_symbolic_operand): New predicate.
+ (mips_unspec_address): Make extern.
+ (mips_gotoff_page, mips_gotoff_global): Delete.
+ (override_options): Allow -mabi=64 -mno-abicalls -mexplicit-relocs.
+ Handle new symbol types.
+ * config/mips/mips.md (*lea_high64, *lea64): New patterns.
+ (*xgot_hi[sd]i, *xgot_lo[sd]i, *got_disp[sd]i, *got_disp[sd]i): Call
+ mips_unspec_address directly.
+ * doc/invoke.texi: Remove the -mabi=64 -mno-abicalls exception from
+ the documentation of -mexplicit-relocs.
+
+2004-03-01 Jeff Law <law@redhat.com>
+
+ * fold-const.c (fold): An equality comparison of a non-weak object
+ against zero has a known result. Similarly an equality comparison
+ of the address of two non-weak, unaliased symbols has a known result.
+
+ * 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.
+
+2004-03-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_output_division): Use the division
+ instruction to fill the delay slot of a zero check.
+ (mips_idiv_insns): Adjust accordingly.
+
+2004-03-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Create a default tmake_file for linux, and use
+ it in all but two linux clauses. Comment those two.
+
+2004-03-01 Paolo Bonzini <bonzini@gnu.org>
+
+ * combine.c (try_combine): Do not refer to is_replaced.
+ (gen_lowpart_for_combine): Perverse subregs now have a
+ more politically correct name.
+ * cse.c (cse_insn): Likewise.
+ * jump.c: Fix bogus reference to delete_insn.
+
+2004-02-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/14328
+ * dwarf2out.c (gen_enumeration_type_die): Output all enumeration
+ constants as signed values.
+
+ PR middle-end/13448
+ * c-tree.h (readonly_warning): Rename to ...
+ (readonly_error): ... this.
+ * c-typeck.c (build_unary_op): Adjust accordingly.
+ (readonly_warning): Rename to ...
+ (readonly_error): ... this and issue errors, not warnings.
+ (build_modify_expr): Call readonly_error, not readonly_warning.
+ (c_expand_asm_operands): Likewise.
+ * tree-inline.c (optimize_inline_calls): Do not inline functions
+ after errors have occurred.
+
+2004-02-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Rearrange some threading code for clarity;
+ add section comment.
+ * configure: Regenerate.
+
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * passes.c, config/frv/frv.c, config/sh/sh.c: Fix comment
+ typos.
+ * doc/cppopts.texi: Fix a typo.
+
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.md: Fix formatting.
+
+2004-02-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Add some comments delineating sections of code.
+
+ * doc/install.texi: Note that libada uses autoconf 2.57 also.
+
+ * doc/install.texi: Fix idiot typo in previous commit.
+
+ * doc/install.texi: Update for conversion of intl to autoconf 2.57.
+
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Add comments about peephole2's.
+
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Tweak operand numbers of some
+ peephole2's.
+
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Tweak comments about peephole2's.
+
+2004-02-29 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ PR middle-end/14203
+ * function.c (uninitialized_vars_warning): Use DECL_RTL_SET_P
+ instead of testing whether DECL_RTL is not NULL.
+
+2004-02-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/sh.c: Fix formatting.
+
+2004-02-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/sh.c: Convert to ISO-C.
+
+2004-02-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-typeck.c (tagged_types_tu_compatible_p): Fix pasto in
+ my previous patch.
+
+ * config/darwin.h (machopic_finish): Output stub even if the
+ symbol is already defined.
+
+2004-02-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa64-hpux.h (LIB_SPEC): Fix linking under HP-UX 11.00 with -p and -pg.
+
+2004-02-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genattr.c (main): Don't define
+ TRADITIONAL_PIPELINE_INTERFACE or DFA_PIPELINE_INTERFACE.
+ * system.h (TRADITIONAL_PIPELINE_INTERFACE): Poison.
+ (DFA_PIPELINE_INTERFACE): Likewise.
+ * doc/tm.texi (TRADITIONAL_PIPELINE_INTERFACE): Remove.
+ (DFA_PIPELINE_INTERFACE): Likewise.
+
+2004-02-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (tstsi, tstdi): Delete.
+
+2004-02-28 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/mips/mips.c (override_options): Remove an obsolete
+ duplicate definition of the "e" constraint.
+ * config/mips/mips.h: Update a comment accordingly.
+
+2004-02-28 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/mips/mips.md: Complete the unfinished R4000
+ multiply/shift errata workaround. Improve documentation.
+ (hazard): Use TARGET_FIX_R4000 to decide whether an "imul" instruction
+ has a hilo hazard.
+ (mulsi3, mulsi3_internal, mulsi3_r4000): Use TARGET_FIX_R4000.
+ (muldi3, muldi3_internal): Likewise.
+ (muldi3_internal2): Remove, replacing with...
+ (muldi3_mult3, muldi3_r4000): ...these new patterns.
+ (mulsidi3): Take the errata into account.
+ (mulsidi3_32bit): Remove, replacing with...
+ (mulsidi3_32bit_internal, mulsidi3_32bit_r4000): ...these new patterns.
+ (mulsidi3_64bit, mulsidi3_64bit_parts): Disable if TARGET_FIX_R4000.
+ (umulsidi3): Take the errata into account.
+ (umulsidi3_32bit): Remove, replacing with..
+ (umulsidi3_32bit_internal, umulsidi3_32bit_r4000): ...these patterns.
+ (umulsi3_highpart, umulsi3_highpart_internal): Disable if
+ TARGET_FIX_R4000.
+ (smulsi3_highpart, smulsi3_highpart_internal): Likewise.
+ (smuldi3_highpart, umuldi3_highpart): Likewise.
+ * doc/invoke.texi: Document the errata workaround.
+
+2004-02-28 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/mips/mips-protos.h (mips_idiv_insns): Declare.
+ * config/mips/mips.h (MASK_FIX_SB1): Bump.
+ (MASK_FIX_R4000, TARGET_FIX_R4000): New macros.
+ (TARGET_SWITCHES): Add -mfix-r4000 and -mno-fix-r4000.
+ * config/mips/mips.c (mips_idiv_insns): New function.
+ (override_options): Make -march=r4000 imply -mfix-r4000 by default.
+ (mips_output_division): Add a workaround for the R4000 divide/shift
+ errata.
+ * config/mips/mips.md (length): Use mips_idiv_insns() to calculate
+ the length of an "idiv" instruction.
+ * doc/invoke.texi: Document the new switches.
+
+2004-02-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi (IS_COSTLY_DEPENDENCE): Change to
+ TARGET_SCHED_IS_COSTLY_DEPENDENCE.
+
+2004-02-28 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/14229
+ * cfgrtl.c (rtl_tidy_fallthru_edge): Do not fail for !onlyjump jump.
+
+2004-02-28 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * fold-const.c (fold): Strip NOPs that change the signedness
+ for RSHIFT too. Expand comment.
+
+2004-02-27 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR optimization/7871
+ * flow.c (mark_set_1): Don't add LOG_LINKS for global registers
+ from or to call insns.
+
+2004-02-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/7871
+ * flow.c (propagate_one_insn): Interpret calls as setting global
+ registers, not merely clobbering them.
+
+2004-02-27 Dale Johannesen <dalej@apple.com>
+
+ * config/darwin.c (machopic_output_possible_stub_label): Remove.
+ config/darwin-protos.h: Ditto.
+ config/darwin.h: Remove call to it.
+ * combine.c (distribute_notes): Do not place a REG_DEAD note
+ when value is both set and used.
+
+2004-02-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/fixunssfsi.c (__fixunssfsi): Enable on H8/300
+ as well.
+ * config/h8300/lib1funcs.asm (___fixunssfsi): Remove.
+ * config/h8300/t-h8300 (LIB1ASMFUNCS): Remove _fixunssfsi_asm.
+
+2004-02-27 Andrew Pinski <apinski@apple.com>
+
+ * c-typeck.c (tagged_types_tu_compatible_p) <ENUMERAL_TYPE>:
+ Speedup common case of the type values being in the same order.
+
+2004-02-27 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.h (no-inline-float-divide): New option.
+ * config/ia64/ia64.h (no-inline-int-divide): New option.
+ * config/ia64/ia64.h (no-inline-sqrt): New option.
+ (TARGET_DEFAULT): Add MASK_INLINE_FLOAT_DIV_THR to define.
+ * config/ia64/hpux.h (TARGET_DEFAULT): Ditto.
+ * config/ia64/ia64.c (ia64_override_options): Modify error
+ checking for inlined division/sqrt.
+
+2004-02-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bb-reorder.c, cfgbuild.c, diagnostic.c, explow.c, profile.c,
+ ra-build.c, read-rtl.c, tracer.c, unwind-dw2-fde-glibc.c,
+ value-prof.c, config/darwin-protos.h, config/frv/frv-abi.h,
+ config/i386/pmmintrin.h, config/pa/pa-hpux.h: Update
+ copyright.
+
+2004-02-27 Paul Brook <paul@codesourcery.com>
+
+ * function.c (assign_parms): Don't count pretend args for alignment.
+
+2004-02-27 Richard Henderson <rth@redhat.com>
+
+ * passes.c: New file.
+ * Makefile.in (OBJS-common): Add it.
+ * diagnostic.c (rtl_dump_and_exit): Move decl ...
+ * flags.h (rtl_dump_and_exit): ... here.
+ * output.h (size_directive_output, last_assemble_variable_decl):
+ Move from toplev.c.
+ * rtl.h (reg_alloc): Move from toplev.c.
+ * toplev.c (HAVE_conditional_execution, DUMPFILE_FORMAT,
+ struct dump_file_info, enum dump_file_index, dump_file_tbl,
+ open_dump_file, close_dump_file, rest_of_decl_compilation,
+ rest_of_type_compilation, rest_of_handle_final,
+ rest_of_handle_delay_slots, rest_of_handle_stack_regs,
+ rest_of_handle_variable_tracking, rest_of_handle_machine_reorg,
+ rest_of_handle_new_regalloc, rest_of_handle_old_regalloc,
+ rest_of_handle_regrename, rest_of_handle_reorder_blocks,
+ rest_of_handle_sched, rest_of_handle_sched2, rest_of_handle_regmove,
+ rest_of_handle_tracer, rest_of_handle_if_conversion,
+ rest_of_handle_if_after_combine, rest_of_handle_web,
+ rest_of_handle_branch_prob,
+ rest_of_handle_value_profile_transformations, rest_of_handle_cfg,
+ rest_of_handle_addressof, rest_of_handle_sibling_calls,
+ rest_of_handle_jump_bypass, rest_of_handle_inlining,
+ rest_of_handle_null_pointer, rest_of_handle_combine,
+ rest_of_handle_life, rest_of_handle_cse, rest_of_handle_cse2,
+ rest_of_handle_gcse, rest_of_handle_loop_optimize,
+ rest_of_handle_loop2, rest_of_compilation): Move to passes.c.
+ (decode_d_option): Use enable_rtl_dump_file.
+ (compile_file, finalize, do_compile): Move profile+combine+graph
+ cleanup to finish_optimization_passes.
+ * toplev.h (init_optimization_passes, finish_optimization_passes,
+ enable_rtl_dump_file): Declare.
+
+2004-02-27 Eric Botcazou <ebotcazou@act-europe.fr>
+ Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold): Revert 2004-02-25 change. Use the original
+ operands to build a tree with swapped operands.
+ * expr.c (expand_expr_real) <MAX_EXPR>: Consistently use the
+ 'unsignedp' predicate to specify the signedness.
+
+2004-02-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c, c-ppoutput.c, combine.c, cppfiles.c, dwarf2out.c,
+ expr.c, fold-const.c, gcc.c, haifa-sched.c, loop-iv.c,
+ params.def, read-rtl.c, rtl.c, rtlanal.c, toplev.c: Fix
+ comment typos and formatting. Follow spelling conventions.
+
+2004-02-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md: Add fixuns_truncsfsi2 and
+ fix_truncsfsi2.
+
+ * config/rs6000/spe.md: Delete spe_efsctuiz.
+ Add spe_fixuns_truncsfsi2.
+ Add spe_fix_truncsfsi2.
+
+2004-02-26 Eric Christopher <echristo@redhat.com>
+
+ * c-lex.c (c_lex_string_translate): New variable.
+ (lex_string): Use to determine string translation.
+ * c-pragma.h: Prototype.
+ * c-parse.in (start_string_translation): New. Set above.
+ (stop_string_translation): Ditto.
+ (attribute, attribute_list, asm_def, asm_stmt,
+ asm_operand): Use above functions.
+ * cp/parser.c (cp_parser_declaration): Translate strings
+ unless token is RID_EXTERN. Set c_lex_string_translate
+ for recursive use.
+ (cp_parser_asm_definition): Only translate argument strings
+ to asms.
+ (cp_parser_asm_operand_list): Ditto.
+ (cp_parser_attribute_list): Do not translate attribute strings.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * stmt.c (expand_start_case_dummy): Remove.
+ * tree.h: Remove the corresponding prototype.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c (apply_args_register_offset): Remove.
+ * tree.h: Remove the corresponding prototype.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * stor-layout.c (is_pending_size): Remove.
+ * tree.h: Remove the corresponding prototype.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * recog.c (validate_replace_src): Remove.
+ * recog.h: Remove the corresponding prototype.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c: Don't reference FINAL_REG_PARM_STACK_SPACE or
+ MAYBE_REG_PARM_STACK_SPACE.
+ * function.c: Likewise.
+ * system.h (FINAL_REG_PARM_STACK_SPACE): Poison.
+ (MAYBE_REG_PARM_STACK_SPACE): Likewise.
+ * doc/tm.texi (FINAL_REG_PARM_STACK_SPACE): Remove.
+ (MAYBE_REG_PARM_STACK_SPACE): Likewise.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c (c_expand_deferred_function): Remove.
+ * c-tree.h: Remove the corresponding prototype.
+
+2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * postreload.c (reload_cse_move2add): Generate just a PLUS
+ instead of an entire SET.
+
+2004-02-26 Jan Hubicka <jh@suse.cz>
+
+ * config.gcc: Add support for nocoma/prescott/pentium-m/pentium3m
+ /pentium4m.
+ * i386.c (override_options): Add support for new CPUs.
+ * i386.h (TARGET_CPU_DEFAULT_NAMES): New names.
+ (TARGET_CPU_DEFAULT_pentium_m, TARGET_CPU_DEFAULT_pentium4e): New
+ constants.
+ * invoke.texi: Extend documentation of -mtune/-march for new CPUs.
+
+2004-02-26 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (TARGET_CPU_CPP_BUILTINS): Define __xtensa__.
+
+2004-02-26 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * config/sparc/sparc-protos.h (sparc_emit_floatunsdi): Add 'mode'.
+ (sparc_emit_fixunsdi): New prototype.
+ * config/sparc/sparc.c (sparc_emit_floatunsdi): Use 'mode' argument.
+ (sparc_emit_fixunsdi): New function.
+ * config/sparc/sparc.md (floatunsdisf2): Use 'general_operand' for
+ operand 1. Pass SFmode to sparc_emit_floatunsdi.
+ (floatunsdidf2): Use 'general_operand' for operand 1. Pass DFmode
+ to sparc_emit_floatunsdi.
+ (fixuns_truncsfdi2): New expander.
+ (fixuns_truncdfdi2): Likewise.
+
+2004-02-26 Alan Modra <amodra@bigpond.net.au>
+
+ * gcse.c (delete_null_pointer_checks_1): Do not delete CC setter
+ unless HAVE_cc0.
+
+2004-02-25 Richard Henderson <rth@redhat.com>
+
+ * explow.c (force_reg): Call mark_reg_pointer as appropriate.
+ * config/alpha/alpha.c (alpha_emit_conditional_branch): Don't
+ use (op0-op1) == 0 if op0 is a pointer.
+ * config/alpha/alpha.md (cmpdi): Use some_operand.
+ (three comparison combine splits): Remove.
+
+2004-02-25 Richard Henderson <rth@redhat.com>
+
+ PR c/12794
+ * c-common.c (handle_alias_attribute): Reject the attribute if
+ current_function_decl is set.
+
+2004-02-25 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config.gcc: Add comment describing extra_gcc_objs.
+ i[34567]86-*-cygwin*): Replace host_extra_gcc_objs with extra_gcc_objs.
+ * configure.ac (extra_gcc_objs): New substitution variable.
+ (host_extra_gcc_objs): Don't substitute.
+ * configure: Regenerate.
+ * Makefile.in: Use extra_gcc_objs.
+
+2004-02-25 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/contrib.texi: Add an entry for myself.
+
+2004-02-25 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (make_eh_edge, break_superblocks): Declare.
+ * cfgbuild.c (make_eh_edge): Make global.
+ * cfglayout.c (break_superblocks): Likewise; fix memory leak.
+ * except.c (build_post_landing_pads, connect_post_landing_pads,
+ dw2_build_landing_pads, sjlj_emit_function_enter,
+ sjlj_emit_function_exit, sjlj_emit_dispatch_table,
+ sjlj_build_landing_pads): Update CFG.
+ (emit_to_new_bb_before): New function.
+ (finish_eh_generation): Do not rebuild the CFG.
+
+2004-02-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * config.gcc (hppa*-*-*, parisc*-*-*): Add MASK_BIG_SWITCH to all
+ target_cpu_default defines.
+ * pa-hpux.h (TARGET_DEFAULT): Add MASK_BIG_SWITCH to define.
+ * pa.h (TARGET_DEFAULT): Likewise.
+
+2004-02-25 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * fold-const.c (fold): Treat MAX_EXPR and MIN_EXPR like
+ comparisons with regard to signedness.
+
+2004-02-25 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_legitimize_address): New function.
+ * arm-protos.h: Prototype it.
+ * arm.h (THUMB_LEGITIMIZE_ADDRESS): Define.
+ (LEGITIMIZE_ADDRESS): Use it.
+
+2004-02-25 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * reload1.c (reload): Only spill eliminable register with multiple
+ adjacent elimination alternatives if all alternatives fail.
+
+2004-02-25 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_legitimate_index_p): For QImode the range of an offset
+ is -4095...+4095 inclusive.
+
+2004-02-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi (sparc-sun-solaris2* specific notes): Document
+ the bootstrap failure with Sun CC 5.4 and 5.5.
+
+2004-02-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cse.c (cse_change_cc_mode_insns): Stop at any instruction
+ which modifies NEWREG.
+ (cse_condition_code_reg): Update the mode of CC_REG in
+ CC_SRC_INSN on our own.
+
+2004-02-24 Michael Matz <matz@suse.de>
+
+ * config/i386/i386.c (ix86_comp_type_attributes): Check for
+ regparm attributes.
+
+2004-02-24 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (dump_file_tbl): Rename from dump_file.
+ * bb-reorder.c, bt-load.c, cfgcleanup.c, cfglayout.c, cfgloopanal.c,
+ cfgloopmanip.c, cfgrtl.c, config/arm/arm.c, config/frv/frv.c,
+ config/i386/i386.c, config/ia64/ia64.c, config/mips/mips.c,
+ config/sh/sh.c, cse.c, flow.c, ifcvt.c, loop-iv.c, loop-unroll.c,
+ loop-unswitch.c, output.h, predict.c, profile.c, ra-build.c,
+ ra-colorize.c, ra-debug.c, ra-rewrite.c, ra.c, regrename.c, reload1.c,
+ toplev.c, tracer.c, value-prof.c, var-tracking.c, web.c:
+ s/rtl_dump_file/dump_file/g.
+
+2004-02-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md (spe_fix_truncsfsi2): Delete.
+ (spe_fixuns_truncsfsi2): Delete.
+
+ * config/rs6000/rs6000.md (fix_truncsfsi2): Delete.
+ (fixuns_truncsfsi2): Delete.
+
+2004-02-24 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/14240
+ * rtlanal.c (replace_label): Fix replacing labels in constant pool.
+
+2004-02-24 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.h (TARGET_HAS_F_SETLKW): Define.
+
+2004-02-24 Jason Merrill <jason@redhat.com>
+
+ * tree.c (check_qualified_type): New fn.
+ (get_qualified_type): Use it. If type already has the desired
+ quals, just return it.
+ * tree.h: Declare it.
+
+2004-02-24 Sanjiv Kumar Gupta <sanjivg@noida.hcltech.com>
+
+ * target-def.h (TARGET_SCHED_INIT_GLOBAL,
+ TARGET_SCHED_FINISH_GLOBAL): New macros.
+
+ * target.h (md_init_global, md_finish_global): Function
+ declarations corresponding to new target macros.
+
+ * haifa-sched.c (sched_init, sched_finish): Allow target to
+ call the new schedular hooks.
+
+ * flow.c (recompute_reg_usage): Add PROP_DEATH_NOTES flag in
+ call to update_life_info.
+
+ * config/sh/sh.h (OVERRIDE_OPTIONS): Re-enable
+ flag_schedule_insns for SH4.
+
+ * config/sh/sh.c (sh_md_init_global, sh_md_finish_global,
+ find_set_regmode_weight, find_insn_regmode_weight,
+ find_regmode_weight), sh_md_init, sh_dfa_new_cycle,
+ sh_variable_issue, high_pressure, ready_reorder,
+ rank_for_reorder, swap_reorder, sh_reorder, sh_reorder2): New
+ functions used to throttle the insn movement in first
+ scheduling pass for SH.
+
+ * gcc/doc/tm.texi: Document TARGET_SCHED_INIT_GLOBAL and
+ TARGET_SCHED_FINISH_GLOBAL.
+
+2004-02-24 Alexandre Oliva <aoliva@redhat.com>
+
+ Implement FR-V FDPIC ABI support for frv-uclinux and frv-linux.
+ 2004-02-05 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_emit_movsi): Use GOT relocations for
+ symbols in sections named by the user.
+ 2004-01-30 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/linux.h (TARGET_OS_CPP_BUILTINS): New.
+ 2004-01-27 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc (frv-*-*linux*): Handle like *-*-linux*.
+ * config/frv/t-linux (EXTRA_MULTILIB_PARTS): Remove, obviated by
+ the above.
+ 2004-01-20 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.md (symGOT2reg_hilo, symGOTOFF2reg_hilo): Add
+ one more pseudo to further improve code generation.
+ 2004-01-19 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.md (movdi_ldd): Introduce explicit indirection
+ inside UNSPEC.
+ 2004-01-16 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_legitimate_address_p): Added
+ allow_double_reg_p argument. Adjust all callers. Use it to
+ decide whether to enable double-register indirect addressing.
+ (frv_funcdesc_alias_set): Remove.
+ (frv_expand_fdpic_call): Force non-SYMBOL_REF operand into
+ register. Emit movdi_ldd.
+ (ldd_address_operand): New.
+ * config/frv/frv-protos.h (frv_legitimate_address_p): Adjust.
+ * config/frv/frv.h (GO_IF_LEGITIMATE_ADDRESS): Likewise.
+ (PREDICATE_CODES): Add ldd_address_operand.
+ * config/frv/frv.md (movdi_ldd): New.
+ (symGOT2reg_hilo, symGOTOFF2reg_hilo): Use separate pseudo for
+ intermediate computations if possible.
+ (symGOTOFF2reg_i): Fix harmless typo.
+ 2003-12-18 Alexandre Oliva <aoliva@redhat.com>
+ * unwind-dw2-fde-glibc.c (_Unwind_IteratePhdrCallback): Cast
+ relocated p_vaddr to vaddr type.
+ * config/frv/frv-protos.h (frv_expand_fdpic_call): Return void.
+ * config/frv/frv.c (frv_get_funcdesc_alias_set): New.
+ (frv_expand_fdpic_call): Propagate incoming MEM's expr to funcdesc
+ MEM, or use a funcdesc alias set. Use regular move instead of
+ ldd.
+ (dbl_memory_one_insn_operand): Recognize function descriptors by
+ type or by alias set, and don't split them.
+ * config/frv/frv.md (call, call_value): Never use call_internal
+ for fdpic.
+ (call_internal, call_value_internal): Never match for FDPIC.
+ (call_fdpicdi, call_fdpicsi, call_value_fdpicdi,
+ call_value_fdpicsi): Require FDPIC.
+ (ldd): Removed.
+ 2003-12-17 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.h (CRT_GET_RFIB_DATA): Define for __FRV_FDPIC__.
+ * unwind-dw2-fde-glibc.c: Don't include elf-fdpic.h any more.
+ (_Unwind_IteratePhdrCallback): Adjust type of load_base for FRV
+ FDPIC. Compute data base address.
+ * config/frv/linux.h (SUBTARGET_DRIVER_SELF_SPECS): Enable -mfdpic
+ before the other self-specs are processed.
+ * config/frv/t-linux (CRTSTUFF_T_CFLAGS, TARGET_LIBGCC2_CFLAGS):
+ Build with -fPIC.
+ 2003-12-15 Alexandre Oliva <aoliva@redhat.com>
+ * unwind-dw2-fde-glibc.c: Don't include bits/elf-fdpic.h if
+ inhibit_libc is defined.
+ 2003-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * unwind-dw2-fde-glibc.c: Include bits/elf-fdpic.h for
+ __FRV_FDPIC__.
+ (__RELOC_POINTER): Define.
+ (_Unwind_IteratePhdrCallback): Use it.
+ * config/frv/frv.h (Twrite): Define.
+ (TRANSFER_FROM_TRAMPOLINE): Use it.
+ * config/frv/linux.h (INVOKE__main): Undefine.
+ (Twrite): Override.
+ 2003-12-05 Richard Sandiford <rsandifo@redhat.com>
+ * doc/invoke.texi (-mlong-calls, -mlinked-fp): Document FRV options.
+ (-mlibrary-pic): Emphasize that this option generates EABI code.
+ (-mcpu): Add fr550.
+ (-mpack): Remove.
+ 2003-11-30 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (int_2word_operand): Reject LABELs, SYMBOL_REFs
+ and CONSTs in FDPIC mode.
+ * gcc/config.gcc (with_cpu): Default to fr400 on frv-*-*linux*.
+ 2003-11-29 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv.c (move_source_operand): Don't accept symbolic
+ constants.
+ * config/frv/frv.md (*movhi_internal, *movsi_internal): Use an 'n'
+ rather than 'i' constraint for the 2-instruction alternative.
+ (*movsi_2word): New, incorporating existing int_2word_operand splitter.
+ 2003-11-29 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv.h (EXTRA_CONSTRAINT_FOR_Q): Renamed from
+ EXTRA_CONSTRAINT_FOR_Y.
+ (EXTRA_CONSTRAINT): Remove handling of 'Y'.
+ * config/frv/frv.md (*movsi_internal): Remove 'Q' constraint.
+ (addsi3): Change 'Y' constraint to 'Q'.
+ 2003-11-27 Richard Sandiford <rsandifo@redhat.com>
+ * reload.c (CONST_POOL_OK_P): New macro.
+ (find_reloads): Use it to decide whether a constant can be forced
+ into memory.
+ * config/frv/frv.h (LEGITIMATE_PIC_OPERAND_P): Return true if the
+ constant satisfies got12_operand.
+ (frv_cannot_force_const_mem): Always return true for TARGET_FDPIC.
+ (frv_legitimate_address_p): Check for valid unspec offsets using
+ got12_operand rather than frv_legitimate_fdpic_operand_p.
+ (frv_legitimate_fdpic_operand_p): Delete.
+ (frv_emit_movsi): Abort if we try to use the FDPIC register during
+ or after reload.
+ (frv_legitimate_constant_p): Return LEGITIMATE_PIC_OPERAND_P if
+ TARGET_FDPIC.
+ * config/frv/frv.md (*movdf_double): Add alternatives for CONST_DOUBLE.
+ 2003-11-19 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv-protos.h (fdpic_operand, fdpic_got12_operand)
+ (frv_fdpic_fptr_operand): Don't declare here.
+ * config/frv/frv.h (EXTRA_CONSTRAINT_FOR_Y): Call got12_operand
+ rather than fdpic_got12_operand.
+ (PREDICATE_CODES): Remove symbolic_operand entry. Add entries for
+ got12_operand and const_unspec_operand.
+ * config/frv/frv.c (got12_operand): Renamed from fdpic_got12_operand.
+ (gpr_or_int12_operand, dbl_memory_one_insn_operand): Update calls.
+ (symbolic_operand): Remove.
+ (const_unspec_operand): New predicate.
+ * config/frv/frv.md (*movsi_got): Use got12_operand.
+ (*movsi_high_got, *movsi_lo_sum_got): Use const_unspec_operand.
+ 2003-11-18 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv-protos.h (frv_output_addr_const_extra): Remove.
+ * config/frv/frv.h (OUTPUT_ADDR_CONST_EXTRA): Remove definition.
+ * config/frv/frv.c (frv_unspec): New structure.
+ (frv_small_data_reloc_p, frv_const_unspec_p): New functions.
+ (frv_print_operand_memory_reference): Use frv_const_unspec_p to
+ validate CONST indices. Use frv_output_const_unspec to print them.
+ (frv_print_operand): Update call to unspec_got_name. Use
+ frv_output_const_unspec to print constant unspecs.
+ (frv_legitimate_fdpic_operand_p): Return true if frv_const_unspec_p.
+ Reject UNSPECs otherwise.
+ (unspec_got_name): Take the relocation number as argument, not an
+ rtx containing it.
+ (frv_output_addr_const_extra): Remove, replacing with...
+ (frv_output_const_unspec): ...this new function.
+ (frv_find_base_term): Use frv_const_unspec_p & frv_small_data_reloc_p.
+ (gpr_or_int12_operand): Use fdpic_got12_operand.
+ (dbl_memory_one_insn_operand): Likewise.
+ (fdpic_got12_operand): Use frv_const_unspec_p.
+ (frv_emit_movsi): Use frv_const_unspec_p to check for CONSTs that
+ are already legitimate. Use frv_small_data_reloc_p when deciding
+ whether to use HIGH/LO_SUM for R_FRV_GOTOFF12 and R_FRV_GPREL12.
+ 2003-11-18 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/t-linux (SHLIB_MAPFILES): Override so as to export...
+ * config/frv/libgcc-frv.ver: ... frv-specific symbols. New file.
+ * config/frv/frv-abi.h (CREATE_DOUBLE_SHIFT): Use branch to local
+ label, for real this time.
+ * config/frv/frv.c (frv_local_funcdesc_p): Update to new
+ representation of visibility.
+ (fdpic_got12_operand, symbolic_operand): Mark unused arguments as
+ such.
+ 2003-11-17 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv.h (MASK_LINKED_FP, TARGET_LINKED_FP): New macros.
+ (TARGET_SWITCHES): Add -mlinked-fp and -mno-linked-fp.
+ * config/frv/frv.c (frv_override_options): Set MASK_LINKED_FP unless
+ it was explicitly disabled.
+ (frv_stack_info): There is no need to save the link register in every
+ frame unless TARGET_LINKED_FP is true.
+ (frv_frame_pointer_required): If !TARGET_LINKED_FP, only require a
+ frame pointer if the stack pointer might change value.
+ (frv_return_addr_rtx): Check and process "count" argument.
+ 2003-11-14 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv-protos.h (frv_legitimize_address): Remove.
+ (frv_find_base_term): Declare.
+ * config/frv/frv.h (LEGITIMIZE_ADDRESS): Do nothing.
+ (FIND_BASE_TERM): Define.
+ (PREDICATE_CODES): Remove pic_register_operand, pic_symbolic_operand,
+ small_data_register_operand, small_data_symbolic_operand. Add
+ symbolic_operand.
+ * config/frv/frv.c (const_small_data_p, plus_small_data_p): Delete.
+ (frv_print_operand_memory_reference, output_move_single): Remove
+ special handling for unlegitimized sdata addresses.
+ (frv_legitimate_address_p): Don't allow sums of SDA_BASE_REG
+ and symbolic addresses.
+ (frv_legitimize_address, frv_legitimize_fdpic_address): Delete.
+ (frv_find_base_term): New function.
+ (int_2word_operand): Check specifically for symbolic address constants.
+ (pic_register_operand, pic_symbolic_operand): Delete.
+ (small_data_register_operand, small_data_symbolic_operand): Delete.
+ (dbl_memory_one_insn_operand): Don't call plus_small_data_p.
+ Allow UNSPEC_GOT constants if !TARGET_FDPIC.
+ (move_source_operand): Only accept CONSTs if they're a two-insn
+ symbolic constant.
+ (fdpic_got12_operand): Don't require TARGET_FDPIC.
+ (frv_emit_movsi): Legitimize sdata and -mlibrary-pic addresses
+ using gen_symGOTOFF2reg*.
+ (frv_ifcvt_rewrite_mem): Remove (plus gr16 ...) special cases.
+ (frv_rtx_costs): Give all MEM addresses a cost of 0. Give MEMs
+ themselves a cost of 3 insns.
+ * config/mips/mips.md (*movsi_got): Allow for !TARGET_FDPIC too.
+ Change predicate to symbolic_operand.
+ (*movsi_high_got, *movsi_lo_sum_got): Likewise.
+ (*movsi_lda_sdata): Delete.
+ (*movsi_pic, movsi_high_pic, movsi_lo_sum_pic): Delete.
+ 2003-11-05 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc: Add t-slibgcc-elf-ver and support --with-cpu for
+ frv-*-*linux*.
+ * config/frv/frv-abi.h (CREATE_DOUBLE_SHIFT): Use branch to local
+ label.
+ * config/frv/frv.h (DRIVER_SELF_SPECS): Add blank before
+ -multilib-library-pic.
+ (LINK_SPEC): Add -z text for -mfdpic.
+ * config/frv/frvbegin.c (__ROFIXUP_LIST__): Don't define on FDPIC.
+ * config/frv/frvend.c (__ROFIXUP_END__): Likewise.
+ * config/frv/linux.h (STARTFILE_SPEC, ENDFILE_SPEC, LINK_SPEC):
+ Override.
+ (OPTION_DEFAULT_SPECS, HAS_INIT_SECTION, INIT_SECTION_ASM_OP,
+ FINI_SECTION_ASM_OP, CRT_CALL_STATIC_FUNCTION): Define.
+ * config/frv/t-linux (EXTRA_MULTILIB_PARTS): Use
+ crtstuff-generated files.
+ 2003-10-31 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc: Add frv-*-*linux*.
+ * config/frv/linux.h, config/frv/t-linux: New.
+ 2003-10-06 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.h (LINK_SPEC): Pass -melf32frvfd to the linker
+ when -mfdpic even if a linker script is explicitly listed.
+ 2003-10-02 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_override_options): Clear asm_out
+ unaligned_op for SImode on FDPIC.
+ (frv_emit_movsi): Use compute_reloc_for_constant to compute the
+ argument passed to decl_readonly_section.
+ (frv_assemble_integer): Revert 2003-09-30's change, but make the
+ whole block run with FDPIC even with -fno-PIC.
+ 2003-10-02 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_cannot_force_const_mem): Don't force
+ symbol or label plus offset to memory.
+ (frv_emit_movsi): Emit GPREL only if -mgprel-ro. Emit 32-bit
+ GOTOFF and GPREL for LABEL_REF.
+ * config/frv/frv.h (DRIVER_SELF_SPECS): Add -mgprel-ro with
+ -mfdpic unless -mno-gprel-ro, -fpic or -fpie.
+ (MASK_GPREL_RO, TARGET_GPREL_RO): New.
+ (TARGET_SWITCHES): Added gprel-ro and no-gprel-ro.
+ * doc/invoke.texi: Document them.
+ 2003-09-30 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv-protos.h (frv_gen_GPsym2reg): Declare.
+ (frv_splittable_got_operand): Removed.
+ * config/frv/frv.c (frv_cannot_force_const_mem): Reject HIGH and
+ LO_SUM. Add comments.
+ (frv_override_options): Moved enabling of FDPIC to
+ DRIVER_SELF_SPECS. Don't enable MASK_DWORD.
+ (frv_local_funcdesc_p): Remove unnecessary heck for flag_pie.
+ (frv_legitimize_fdpic_address): Don't duplicate logic in
+ frv_emit_movsi.
+ (frv_gen_GPsym2reg): New.
+ (unspec_got_name): Added gprel.
+ (frv_expand_fdpic_call): Add support for inlining PLTs.
+ (fdpic_fptr_operand): Renamed from frv_fdpic_fptr_operand.
+ (gpr_or_int12_operand): Added GPREL12.
+ (pic_symbolic_operand): Match even if !flag_pic for FDPIC.
+ (small_data_symbolic_operand): Fail if FDPIC.
+ (fdpic_splittable_got_operand): Removed.
+ (fdpic_got12_operand): Added GPREL12.
+ (frv_emit_movsi): Reorganize to avoid duplication. Emit GPREL
+ when appropriate. Fix sdata GOTOFF.
+ (frv_legitimate_constant_p): Require legitimate PIC operand for
+ FDPIC with pic, but only a legitimate fdpic operand for non-pic.
+ (frv_assemble_integer): Move FDPIC funcdesc handling out of
+ flag_pic case.
+ (frv_asm_out_constructor, frv_asm_out_destructor): Abort if
+ frv_assemble_integer fails.
+ * config/frv/frv.h (DRIVER_SELF_SPECS): New.
+ (SUBTARGET_DRIVER_SELF_SPECS): New.
+ (ASM_SPEC): Don't pass -mno-fdpic.
+ (LINK_SPEC): Pass -melf32frvfd for FDPIC.
+ (MASK_INLINE_PLT, TARGET_INLINE_PLT): New.
+ (TARGET_SWITCHES): Add -minline-plt, -mno-inline-plt and
+ -multilib-library-pic.
+ (PREDICATE_CODES): Added fdpic_operand, fdpic_fptr_operand,
+ condexec_si_media_operator, condexec_sf_add_operator and
+ condexec_sf_conv_operator. Removed condexec_sf_binary_operator
+ and condexec_sf_unary_operator.
+ * config/frv/frv.md (R_FRV_GPREL12, R_FRV_GPRELHI, R_FRV_GPRELLO):
+ New.
+ (movsi_got, movsi_high_got, movsi_lo_sum_got): Move before
+ movsi_internal. Give them internal names. movsi_got has type
+ int.
+ (fdpic got splitters): Remove.
+ (symGPREL2reg, symGPREL2reg_hilo): New.
+ * config/frv/t-frv (MULTILIB_MATCHES): Don't map -fpic and -fPIC
+ to -mlibrary-pic. Map -multilib-library-pic to it.
+ * doc/invoke.texi: -mfdpic, -minline-plt, -multilib-library-pic:
+ Document.
+ 2003-09-28 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_function_symbol_referenced_p): Declare.
+ (TARGET_CANNOT_FORCE_CONST_MEM): Define to...
+ (frv_cannot_force_const_mem): New function.
+ (const_small_data_p, plus_small_data_p): Update comments on sdata
+ on FDPIC.
+ (frv_override_options): Set flag_pie for FDPIC too.
+ (frv_conditional_register_usage): Mark gr16 and gr17 as non-fixed,
+ call-saved registers on FDPIC.
+ (frv_stack_info): Don't preserve the PIC register on FDPIC, and
+ don't force LR to be preserved.
+ (frv_expand_prologue): Likewise.
+ (frv_asm_output_mi_thunk): Use 12-bit funcdesc gotoff for -fpic.
+ (frv_frame_pointer_required): Don't force it just because the
+ FDPIC register is used.
+ (frv_legitimate_address_p) <CONST>: Accept a legitimate FDPIC
+ operand only if !condexec_p.
+ (frv_legitimize_address): Return the FDPIC-legitimized address.
+ Don't match small data here on FDPIC.
+ (frv_legitimate_fdpic_operand_p): Don't accept unadorned function
+ symbols. Use TRUE/FALSE instead of 1/0.
+ (frv_local_funcdesc_p): New.
+ (frv_legitimize_fdpic_address): Rewrite to use GOTOFF and 12-bit
+ immediates when possible.
+ (pic_symbolic_operand): Accept SYMBOL_REFs and CONSTs in FDPIC.
+ (dbl_memory_one_insn_operand): Accept addresses that add a REG and
+ an UNSPEC_GOT.
+ (frv_emit_movsi): Handle FDPIC before small data. Use GOTOFF and
+ 12-bit immediates when possible.
+ (frv_legitimate_constant_p): In FDPIC, reject SImode operands that
+ are not legitimate pic operands.
+ (frv_in_small_data_p): Re-enable for FDPIC.
+ * config/frv/frv.h (SDA_BASE_REG): Remove comment about FDPIC.
+ (FRV_GLOBAL_P): Removed.
+ * config/frv/frv.md: Add modes to CONSTs.
+ (movsi_got): New.
+ (movsi_lo_sum_got): Use separate matches instead of match_dup.
+ (movsi_high_pic, movsi_lo_sum_pic): Match on non-FDPIC only.
+ (fdpic splittable operations): Match on flag_pic != 1.
+ 2003-09-22 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_asm_out_constructor,
+ frv_asm_out_destructor): Pass to frv_assemble_integer the size in
+ bytes, not bits.
+ 2003-09-19 Alexandre Oliva <aoliva@redhat.com>
+ * config/frv/frv.c (frv_assemble_integer): Reject complex
+ expressions referencing function SYMBOL_REFs.
+ * config/frv/frv.c (frv_function_symbol_referenced_p): New.
+ (move_source_operand): Reject CONSTs that reference function
+ SYMBOL_REFs on FDPIC.
+ (frv_emit_movsi): If we get such a CONST, break it up.
+ * config/frv/frv.h (CPP_SPEC): Define __FRV_FDPIC__ for -mfdpic.
+ (TRANSFER_FROM_TRAMPOLINE): Use different definitions for FDPIC.
+ * config/frv/frv.c (frv_print_operand) <I>: Recognize PLUS without
+ MEM.
+ (frv_assemble_integer): Don't use funcdesc for LABEL_REFs.
+ (frv_trampoline_size): Increase for FDPIC.
+ * config/frv/frv.h (TRAMPOLINE_ALIGNMENT): Bump to 64 for FDPIC.
+ (TRANSFER_FROM_TRAMPOLINE): Handle FDPIC trampolines.
+ * config/frv/frv.c (frv_legitimize_fdpic_address, frv_emit_movsi):
+ Disable use of GOTOFF for now.
+ (const_small_data_p, plus_small_data_p, frv_in_small_data_p):
+ Disable use of small data in FDPIC for now.
+ (frv_asm_output_mi_thunk): Implement for FDPIC.
+ * config/frv/frv.h (SDA_BASE_REG): Set to -1 with FDPIC.
+ * config/frv/frv.c (frv_asm_out_constructor): Use
+ frv_assemble_integer for FDPIC pointers.
+ (frv_asm_out_destructor): Likewise.
+ * config/frv/frv.md (ldd): Fix order of operands. Use
+ address_operand for input.
+ 2003-09-18 DJ Delorie <dj@redhat.com>
+ * config/frv/frv.c (frv_legitimate_fdpic_operand_p): Remove UNSPEC_PIC.
+ (unspec_got_name): Correct typo.
+ (frv_emit_movsi): Pre-expand splittable GOTs.
+ (frv_expand_fdpic_call): Rename gen_lddi to gen_ldd.
+ * config/frv/frv.md (lddi): Fix syntax error, rename to ldd.
+ (symGOT2reg_hilo, symGOTOFF2reg_hilo): New.
+ * config/frv/t-frv: Add -mfdpic multilibs.
+ * config/frv/frv.h (ASM_SPEC): Pass -mfdpic/-mno-fdpic.
+ (TARGET_SWITCHES): Add -mno-fdpic, fix documentation.
+ * config/frv/frv.c (frv_override_options): -mfdpic assumes
+ flag_pic, default to 32-bit pics, require DWORD ops.
+ (frv_override_options): Add W and Z constraints.
+ (frv_expand_prologue): No pic prologue for -mfdpic.
+ (frv_asm_output_mi_thunk): Support -mfdpic (soon).
+ (frv_print_operand_memory_reference): Handle GOT constants.
+ (frv_legitimate_address_p): Allow GOT constants.
+ (frv_legitimize_address): Handle GOT addresses too.
+ (frv_legitimate_fdpic_operand_p): New.
+ (frv_legitimize_fdpic_address): New.
+ (unspec_got_name): New.
+ (frv_output_addr_const_extra): New.
+ (frv_expand_fdpic_call): New.
+ (frv_fdpic_fptr_operand): New.
+ (gpr_or_int12_operand): Handle GOT operands.
+ (int_2word_operand): Handle GOT operands.
+ (fdpic_operand): New.
+ (fdpic_splittable_got_operand): New.
+ (fdpic_got12_operand): New.
+ (frv_emit_movsi): Handle GOT operands.
+ (frv_assemble_integer): -mfdpic doesn't use rofixups.
+ (frv_print_operand): Support 'g' code for GOT operands.
+ * config/frv/frv-protos.h: Add prototypes as needed.
+ * config/frv/frv.md (R_FRV_GOT12, R_FRV_GOTHI, R_FRV_GOTLO,
+ R_FRV_FUNCDESC, R_FRV_FUNCDESC_GOT12, R_FRV_FUNCDESC_GOTHI,
+ R_FRV_FUNCDESC_GOTLO, R_FRV_FUNCDESC_VALUE,
+ R_FRV_FUNCDESC_GOTOFF12, R_FRV_FUNCDESC_GOTOFFHI,
+ R_FRV_FUNCDESC_GOTOFFLO, R_FRV_GOTOFF12, R_FRV_GOTOFFHI,
+ R_FRV_GOTOFFLO): New.
+ (movsi_high_got, movsi_lo_sum_got): New.
+ (*movsi_pic): Don't use this splitter for -mfdpic.
+ (addsi3): Allow GOT references also.
+ (call, call_value): Handle -mfdpic separately.
+ (call_fdpicdi, call_fdpicsi, lddi, call_value_fdpicdi,
+ call_value_fdpicsi): New.
+ (symGOT2reg, symGOT2reg_i, got splitters, symGOTOFF2reg,
+ symGOTOFF2reg_i): New.
+ * config/frv/frv.h (MASK_FDPIC): New.
+ (TARGET_FDPIC): New.
+ (TARGET_SWITCHES): Add -mfdpic.
+ (FDPIC_FPTR_REGNO): New.
+ (FDPIC_REGNO): New.
+ (OUR_FDPIC_REG): New.
+ (enum reg_class): Add FDPIC_REGS, FDPIC_FPTR_REGS, and
+ FDPIC_CALL_REGS.
+ (REG_CLASS_NAMES): Likewise.
+ (REG_CLASS_CONTENTS): Likewise.
+ (EXTRA_CONSTRAINT_FOR_Y): New, for 12-bit GOTs.
+ (EXTRA_CONSTRAINT): Add it here.
+ (FRV_GLOBAL_P): New.
+ (OUTPUT_ADDR_CONST_EXTRA): New.
+
+2004-02-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sparc/sparc.h: Remove commented-out definitions of
+ TARGET_EDOM and GEN_ERRNO_RTX.
+
+2004-02-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * df.c, df.h, ra-build.c, ra-rewrite.c, ra.c, web.c: Replace
+ df_analyse with df_analyze.
+
+2004-02-24 Alan Modra <amodra@bigpond.net.au>
+
+ * gcse.c (delete_null_pointer_checks_1): Set stop_insn to end, not
+ beginning of block.
+
+2004-02-23 James E Wilson <wilson@specifixinc.com>
+
+ * calls.c (precompute_arguments): Update comment.
+
+2004-02-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * et-forest.c: Replace et_occurences with et_occurrences.
+
+2004-02-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cfgloop.h, loop-iv.c, loop-unswitch.c: Replace iv_analyse
+ with iv_analyze.
+
+2004-02-23 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/i386/i386.c: Rename pni to sse3.
+ * config/i386/i386.h: Likewise.
+ * config/i386/i386.md: Likewise.
+ * config/i386/pmmintrin.h: Likewise.
+ * doc/extend.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2004-02-23 Zack Weinberg <zack@codesourcery.com>
+ Kazu Hirata <kazu@cs.umass.edu>
+
+ Remove -fwritable-strings.
+ * c-common.c (fix_string_type): Don't check
+ flag_writable_strings.
+ (fix_string_type): Likewise.
+ * c-opts.c (set_std_c89): Don't initialize
+ flag_writable_strings.
+ (set_std_c99): Likewise.
+ * common.opt (fwritable-strings): Remove.
+ * flags.h: Remove the external declaration of
+ flag_writable_strings.
+ * opts.c (common_handle_option) <OPT_fwritable_strings>:
+ Remove.
+ * toplev.c (flag_writable_strings): Remove.
+ (f_options): Remove an entry for writable-strings.
+ * varasm.c (const_hash_1) <STRING_CST>: Don't check
+ flag_writable_strings.
+ (compare_constant) <STRING_CST>: Likewise.
+ (build_constant_desc): Likewise.
+ * config/darwin.c (machopic_select_section): Likewise.
+ * config/arm/arm.c (AOF_ASSEMBLER): Likewise.
+ * config/arm/pe.c (arm_pe_encode_section_info): Likewise.
+ * config/iq2000/iq2000.c (iq2000_select_section): Likewise.
+ * config/mips/mips.c (mips_select_section): Likewise.
+ (mips_encode_section_info): Likewise.
+ * config/pa/pa.c (pa_select_section): Likewise.
+ * config/pa/pa.h (TEXT_SPACE_P): Likewise.
+ * config/v850/v850.c (v850_select_section): Likewise.
+ * doc/invoke.texi (-fwritable-strings): Remove.
+ (-fno-const-strings): Don't mention -fwritable-strings.
+ * doc/trouble.texi: Don't mention -fwritable-strings.
+
+2004-02-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Update for switch of boehm-gc to autoconf 2.57.
+
+2004-02-23 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000.md (movsf_hardfloat): Add POWER form of nop.
+ (movdf_hardfloat64): Ditto.
+ (movdf_softfloat64): Ditto.
+
+2004-02-23 Fariborz Jahanian <fjahanian@apple.com>
+ * config/rs6000/rs6000.c (function_arg): call to
+ rs6000_mixed_function_arg for DFmode moved to allow
+ normal DFmode incoming register assignment.
+
+2004-02-23 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000.md (movsf_hardfloat): Accept CTR-to-CTR copy.
+ (movdf_hardfloat64): Ditto.
+
+2004-02-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * convert.c, gcov-io.c, libgcov.c, sched-int.h, sibcall.c,
+ config/rs6000/linux.h, config/rs6000/rs6000-c.c: Update
+ copyright.
+
+2004-02-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/14156
+ * c-typeck.c (c_expand_return): Change check for VAR_DECL
+ to use DECL_P instead.
+
+ * config/rs6000/linux.h (OS_MISSING_POWERPC64): Define.
+ * config/rs6000/linux64.h (OS_MISSING_POWERPC64): Define.
+
+2004-02-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * Makefile.in (opts.o): Depend on target.h.
+ * opts.c (decode_options): Use targetm.default_short_enums
+ instead of DEFAULT_SHORT_ENUMS.
+ * system.h (DEFAULT_SHORT_ENUMS): Poison.
+ * target-def.h (TARGET_DEFAULT_SHORT_ENUMS): New.
+ (TARGET_INITIALIZER): Add TARGET_DEFAULT_SHORT_ENUMS.
+ * target.h (gcc_target): Add default_short_enums.
+ * config/cris/cris.h: Remove a comment about
+ DEFAULT_SHORT_ENUMS.
+ * config/ip2k/ip2k.h: Likewise.
+ * doc/tm.texi (DEFAULT_SHORT_ENUMS): Change to
+ TARGET_DEFAULT_SHORT_ENUMS. Update the description.
+
+2004-02-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Falk Hueffner <falk@debian.org>
+
+ PR c/14188
+ * builtins.c (expand_builtin_va_arg): Emit an informative message
+ if a trap is generated.
+ * c-typeck.c (build_function_call): Likewise.
+
+2004-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ * gcov-io.c (gcov_open) [GCOV_LOCKED]: Use open + fdopen instead of
+ fopen.
+ * libgcov.c: Include sys/stat.h.
+ * config/rs6000/linux.h (TARGET_HAS_F_SETLKW): Define.
+ * config/rs6000/linux64.h (TARGET_HAS_F_SETLKW): Define.
+ * config/sparc/linux.h (TARGET_HAS_F_SETLKW): Define.
+ * config/sparc/linux64.h (TARGET_HAS_F_SETLKW): Define.
+
+2004-02-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reorg.c: Remove comments about dead ports.
+
+2004-02-22 Christopher Faylor <cgf@redhat.com>
+
+ * config.gcc (i[34567]86-*-pe|i[34567]86-*-cygwin*): *Really* specify
+ extra host object file when targetting cygwin rather than generic
+ object files.
+
+2004-02-22 Josef Zlomek <zlomekj@suse.cz>
+
+ Merge from tree-ssa:
+ 2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * 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): Use it.
+
+ * function.c (copy_body_r): Add mapping from id->ret_label to
+ id->ret_label. Revert test for ret_label.
+
+2004-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ * genoutput.c (process_template): Strip trailing whitespace in @
+ templates and issue a warning if there was any.
+
+2004-02-21 Christopher Faylor <cgf@redhat.com>
+
+ * config.gcc (i[34567]86-*-pe|i[34567]86-*-cygwin*): Specify extra host
+ object file when targetting cygwin.
+ * config/i386/t-cygwin (EXTRA_GCC_OBJS): Remove definition since it is
+ overridden by top-level Makefile.
+
+2004-02-21 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (standard_80387_constant_p): Also prefer
+ the x87's load constant instructions when optimizing for size.
+
+2004-02-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (SHIFT_COUNT_TRUNCATED): Remove.
+ * defaults.h (SHIFT_COUNT_TRUNCATED): Provide the default.
+ * expmed.c: Assume SHIFT_COUNT_TRUNCATED is always defined.
+ * fold-const.c: Likewise.
+ * simplify-rtx.c: Likewise.
+
+2004-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * combine.c (can_combine_p): Don't ignore SETs marked with
+ REG_EH_REGION notes.
+ (try_combine): When attemting to fix unrecognized insns, don't
+ split a PARALLEL that contains the original i2.
+
+2004-02-21 Ziemowit Laski <zlaski@apple.com>
+
+ * config/darwin.h (TARGET_OPTION_TRANSLATE_TABLE): Refer to
+ SUBTARGET_OPTION_TRANSLATE_TABLE for architecture-specific options.
+ * config/i386/darwin.h (SUBTARGET_OPTION_TRANSLATE_TABLE): Define it.
+ * config/rs6000/altivec.h: #error out if '-maltivec' not specified.
+ (vector, pixel, bool): #define to __vector, __pixel and __bool.
+ (__un_args_eq, __bin_args_eq, __tern_args_eq): Move to C-specific
+ portion of header.
+ (__altivec_link_error_invalid_argument): Remove prototype; will use
+ __builtin_altivec_compiletime_error("vec_*") instead.
+ (vec_*): Fix/complete set of available operation overloads given the
+ existence of distinct 'vector bool ...' and 'vector pixel' types; tighten
+ cv-correctness of pointer arguments; in C, always check for correct
+ argument types before macro expansion.
+ * config/rs6000/darwin.h (SUBTARGET_OPTION_TRANSLATE_TABLE): New macro
+ defining Darwin/PowerPC-specific '-f[no-]altivec' and
+ '-W[no-]altivec-long-deprecated' switches.
+ * config/rs6000/rs6000-c (rs6000_cpu_cpp_builtins): Pre-define
+ '__vector', '__pixel' and '__bool' macros using
+ '__attribute__((altivec(...)))' types.
+ * config/rs6000/rs6000.c (bool_char_type_node, bool_short_type_node,
+ bool_int_type_node, pixel_type_node, bool_V16QI_type_node,
+ bool_V8HI_type_node, bool_V4SI_type_node, pixel_V8HI_type_node):
+ New type nodes.
+ (rs6000_warn_altivec_long, rs6000_warn_altivec_long_switch): New, for
+ handling '-W[no-]altivec-long-deprecated'.
+ (rs6000_override_options): Handle '-W[no-]altivec-long-deprecated'.
+ (rs6000_expand_binop_builtin, rs6000_expand_ternop_builtin,
+ altivec_expand_dst_builtin): Remove casts from integer literals.
+ (altivec_expand_builtin): Likewise; handle expansion of new
+ '__builtin_altivec_compiletime_error' function.
+ (rs6000_init_builtins): Initialize 'vector bool ...' and 'vector pixel'
+ types, and make them distinct from other vector types; register
+ '__builtin_altivec_compiletime_error' function.
+ (print_operand): For 'P', print a full target register name instead of
+ merely its number.
+ (rs6000_attribute_table): Add "altivec" attribute.
+ (rs6000_handle_altivec_attribute): New function.
+ * config/rs6000/rs6000.h (TARGET_OPTIONS): Describe
+ '-m[no-]-warn-altivec-long' (which '-W[no-]altivec-long-deprecated'
+ maps to).
+ (rs6000_warn_altivec_long, rs6000_warn_altivec_long_switch): Forward
+ declare.
+ (ALTIVEC_BUILTIN_COMPILETIME_ERROR): New built-in enumeration.
+
+2004-02-20 James E Wilson <wilson@specifixinc.com>
+
+ * config/ia64/ia64.md (shift_mix4left+1): Delete reload_completed
+ check.
+ (shift_mix4left+2): Delete redundant pattern.
+
+2004-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c (OUTGOING_REGNO): Don't define the default.
+ * builtins.c (OUTGOING_REGNO): Likewise.
+ (INCOMING_REGNO): Likewise.
+ (apply_args_register_offset): Always use OUTGOING_REGNO.
+ * combine.c (OUTGOING_REGNO): Likewise.
+ * sibcall.c (OUTGOING_REGNO): Likewise.
+ * defaults.h (INCOMING_REGNO): Provide the default.
+ (OUTGOING_REGNO): Likewise.
+
+2004-02-21 Jan Hubicka <jh@suse.cz>
+
+ * params.def (max-peeled-insns, max-completely-peeled-insns,
+ max-once-peeled-insns): Set to 400.
+
+2004-02-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR c++/12007
+ * dbxout.c (dbxout_parms): Check that DECL_RTL and DECL_INCOMING_RTL
+ are set for parameters before outputing debugging information.
+
+2004-02-20 Falk Hueffner <falk@debian.org>
+
+ PR target/14201
+ * config/alpha/alpha.md (*fix_truncsfsi_ieee): Fix typoed operand
+ numbers.
+
+2004-02-20 Per Bothner <per@bothner.com>
+
+ * input.h: Don't #include line-map.h. It may cause link problems
+ with undefined linemap_line_start when line-map.h is included but
+ line-map.o is not linked, as currently happens with gengtype on
+ compilers that don't support inline.
+ * toplev.c: So we do have to explicitly #include line-map.h here.
+
+2004-02-20 Richard Henderson <rth@redhat.com>
+
+ * doc/invoke.texi: Add -Wvariadic-macros.
+
+2004-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * haifa-sched.c (sched_emit_insn): Remove.
+ * sched-int.h: Remove the corresponding prototype.
+
+2004-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ Revert:
+ 2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+ * opts.c (decode_options): Don't use DEFAULT_SHORT_ENUMS.
+ * system.h (DEFAULT_SHORT_ENUMS): Poison.
+ * config/cris/cris.h: Remove a comment about
+ DEFAULT_SHORT_ENUMS.
+ * config/ip2k/ip2k.h: Likewise.
+ * doc/tm.texi (DEFAULT_SHORT_ENUMS): Remove.
+
+2004-02-20 Mohan Embar <gnustuff@thisiscool.com>
+ Tom Tromey <tromey@redhat.com>
+
+ * doc/install.texi: Moved --disable-libgcj and
+ --with-system-zlib documentation to new section for
+ Java-specific options.
+ Added explicit Cross-Compiler-Specific Options subheading.
+ Added section for Java-specific options.
+
+2004-02-20 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/install.texi (Building the Ada compiler): Remove
+ example.
+
+2004-02-20 James E Wilson <wilson@specifixinc.com>
+
+ * toplev.c (dump_file_index, dump_file): Put ce3 before rnreg.
+
+2004-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcc.c (process_command): Allow translation of the copyright
+ symbol but not the rest of the copyright message.
+ * gcov.c (print_version): Likewise. Allow translation of the
+ message about warranty.
+
+2004-02-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/cris.md ("*andsi_movu"): Correct parentheses in
+ predicate.
+ ("*andsi_clear"): Tweak constraints to not match postincrement.
+ Adjust the predicate to exclude a volatile memory reference.
+ ("*andhi_clear"): Ditto. Rename from "*andhi_clear_signed".
+ ("*andhi_clear_unsigned"): Remove, non-matching pattern.
+
+2004-02-19 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * move-if-change: Remove.
+ * Makefile.in (s-mlib, c-parse.y, s-check, s-gencheck)
+ (s-specs, s-options, s-config, s-conditions, s-flags, s-codes)
+ (s-constants, s-emit, s-recog, s-opinit, s-extract, s-peep)
+ (s-attr, s-attrtab, s-output, s-genrtl, s-modes, s-preds)
+ (s-gtyp-gen, s-iov): Use the top level move-if-change.
+ * objc/Make-lang.in (objc/objc-parse.y): Likewise.
+
+2004-02-19 James E Wilson <wilson@specifixinc.com>
+
+ * config/i386/i386.md (doloop_end_internal): Use nonimmediate_operand
+ for operand2. Add condition that requires register_operand operand2
+ before reload.
+
+2004-02-19 Richard Sandiford <rsandifo@redhat.com>
+ Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/mips/mips.c (mips_address_insns): Treat BLKmode specially.
+ * config/mips/mips.md: Expand comment above unaligned loads and stores.
+
+2004-02-19 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (STRICT2_WARN): Add -Wno-variadic-macros.
+ * tree.c (build0, build1, build2, build3, build4): Split out from...
+ (build): ... here. Call them.
+ * tree.h (build, _buildN1, _buildN2, _buildC1, _buildC2): New.
+
+ * convert.c (convert_to_integer): Remove extra build argument.
+ * tree-inline.c (expand_call_inline): Likewise.
+
+2004-02-19 Richard Henderson <rth@redhat.com>
+
+ * c-opts.c (warn_variadic_macros): New.
+ (c_common_handle_option): Set it.
+ (sanitize_cpp_opts): Copy it to cpp_opts.
+ * c.opt (Wvariadic-macros): New.
+ * cpplib.h (struct cpp_options): Add warn_variadic_macros.
+ * cppinit.c (cpp_create_reader): Initialize it.
+ * cppmacro.c (parse_params): Check it.
+
+2004-02-19 David Daney <ddaney@avtrex.com>
+
+ PR preprocessor/14198
+ * config/mips/linux.h (TARGET_OS_CPP_BUILTINS): Add
+ builtin_assert ("machine=mips")
+
+2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * opts.c (decode_options): Don't use DEFAULT_SHORT_ENUMS.
+ * system.h (DEFAULT_SHORT_ENUMS): Poison.
+ * config/cris/cris.h: Remove a comment about
+ DEFAULT_SHORT_ENUMS.
+ * config/ip2k/ip2k.h: Likewise.
+ * doc/tm.texi (DEFAULT_SHORT_ENUMS): Remove.
+
+2004-02-19 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.c (ia64_function_arg): In big-endian mode,
+ when passing single SFmode quantities in general registers,
+ put them in the high half.
+
+2004-02-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/md.texi (Standard Names): Document additional dependency on
+ fix pattern.
+
+ * optabs.c (ftruncify): Remove.
+ (expand_fix): Manually inline ftruncify above.
+ (can_fix_p): Add FIXME note.
+
+2004-02-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md (spe_fixunssfsi2): Rename to
+ spe_fixuns_truncsfsi2.
+
+ * config/rs6000/rs6000.md (fixunssfsi2): Rename to
+ fixuns_truncsfsi2.
+
+2004-02-19 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): New macro.
+ * testsuite/gcc.dg/20040219-1.c: New test.
+
+2004-02-19 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*subdf3_cc", "*subdf3_cconly", "*subsf3_cc",
+ "*subsf3_cconly"): Subtraction is not commutative.
+
+2004-02-19 Zack Weinberg <zack@codesourcery.com>
+
+ * sdbout.c (preinit_symbols, sdbout_initialized): New statics.
+ (sdbout_symbol): If called before sdbout_init, queue DECL for
+ later and return.
+ (sdbout_init): Set sdbout_initialized true, process decls
+ queued earlier by sdbout_symbol.
+ (sdbout_finish): Use size_t for index variable.
+
+2004-02-19 Jeff Law <law@redhat.com>
+
+ * fold-const.c (invert_truthvalue): Do not call invert_tree_comparison
+ for unordered comparison codes.
+
+2004-02-19 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * reload1.c (reload): Correct comment.
+ (scan_paradoxical_subregs): Remove #if 0 and old comment.
+ * doc/extend.texi (Local Reg Vars): Remove obsolete comment that
+ register variables are not used by reload.
+
+2004-02-19 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/14209
+ * config/cris/cris.md ("*andsi_movu", "*andhi_movu"): Tweak
+ constraints to not match postincrement. Adjust the predicate to
+ exclude a volatile memory reference.
+
+2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mcore/mcore.h (ASM_OUTPUT_EXTERNAL): Remove.
+
+2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * hooks.c (hook_void_tree_int): Remove.
+ (hook_void_constcharptr): Likewise.
+ (hook_int_void_0): Likewise.
+ * hooks.h: Remove the prototypes for the above three
+ functions.
+ * targhooks.c (hook_bool_machine_mode_true): Remove.
+ * targhooks.h: Remove the prototype for
+ hook_bool_machine_mode_true.
+
+2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * emit-rtl.c (subreg_realpart_p): Remove.
+ (reorder_insns_with_line_notes): Likewise.
+ (end_full_sequence): Likewise.
+ * rtl.h: Remove the prototype for the above functions.
+
+2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arc/arc.h, config/arm/arm.h, config/frv/frv.h,
+ config/h8300/h8300.h, config/i386/i386.h, config/i860/i860.h,
+ config/iq2000/iq2000.h, config/m32r/m32r.h,
+ config/pdp11/pdp11.h, config/sparc/sparc.h,
+ config/xtensa/xtensa.h: Remove commented-out or useless
+ definitions of CASE_VECTOR_PC_RELATIVE.
+
+2004-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * loop.c (all_sets_invariant_p): Remove.
+
+2004-02-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12916
+ * config/sparc/sparc.h (NPARM_REGS): Delete.
+ (BASE_RETURN_VALUE_REG): Likewise.
+ (BASE_OUTGOING_VALUE_REG): Likewise.
+ (BASE_PASSING_ARG_REG): Likewise.
+ (BASE_INCOMING_ARG_REG): Likewise.
+ * config/sparc/sparc.c (sparc_strict_argument_naming): Test
+ TARGET_ARCH64, not TARGET_V9.
+ (function_arg_slotno): Dispatch based on the mode class.
+ Handle vector modes like floating-point modes.
+ (function_arg_record_value_1): Handle vector types like
+ floating-point types.
+ (function_arg_record_value_2): Likewise.
+ Calculate regno after mode transformation.
+ (function_arg): Handle vector modes like floating-point modes.
+ (function_arg_partial_nregs): Replace NPARM_REGS by SPARC_INT_ARG_MAX.
+ If ARCH64, do not recheck alignment.
+ (function_arg_pass_by_reference): Reorder the conditions.
+ (sparc_return_in_memory): Move after function_arg_padding.
+ Implement calling conventions for vector modes.
+ (sparc_struct_value_rtx): Move after sparc_return_in_memory.
+ (function_value): Move scope of 'regbase'.
+ Implement calling conventions for vector modes.
+ (sparc_builtin_saveregs): Replace NPARM_REGS by SPARC_INT_ARG_MAX
+ and BASE_INCOMING_ARG_REG by SPARC_INCOMING_INT_ARG_FIRST.
+ (sparc_va_arg): Use function_arg_pass_by_reference to test whether
+ the argument is passed by reference.
+ (sparc_type_code): Handle vector types.
+
+2004-02-19 Alan Modra <amodra@bigpond.net.au>
+
+ * function.c (assign_parms): When building decl_rtl for
+ SPLIT_COMPLEX_ARGS, ensure inner modes of concat match outer.
+
+2004-02-19 Olivier Hainque <hainque@act-europe.fr>
+
+ * expr.c (is_aligning_offset): Check if we are aligning the
+ expressions's address over BIGGEST_ALIGNMENT in bytes, not
+ in bits.
+
+2004-02-18 Matt Austern <austern@apple.com>
+
+ * gcc.c (LIBGCC_SPEC): If REAL_LIBGCC_SPEC is defined, and
+ LIBGCC_SPEC isn't, set LIBGCC_SPEC to REAL_LIBGCC_SPEC.
+ (init_gcc_spec): Don't define or call if REAL_LIBGCC_SPEC is
+ defined. Instead use REAL_LIBGCC_SPEC, unmodifed, as the libgcc
+ spec string.
+ * doc/tm.texi (REAL_LIBGCC_SPEC): Document.
+
+2004-02-18 Zack Weinberg <zack@codesourcery.com>
+
+ * dwarf2out.c (loclabel_num): Move outside #ifdef
+ DWARF2_DEBUGGING_INFO and mark with GTY(()).
+ * config/ia64/ia64.c (struct extern_func_list,extern_func_head):
+ Mark with GTY(()).
+ (ia64_hpux_add_extern_decl): Save the decl, not the name string.
+ Allocate memory with ggc_alloc. No need to copy anything.
+ (ia64_hpux_file_end): Update to match.
+
+2004-02-18 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (override_options): Don't imply 3DNow! for -m64
+ by default.
+
+2004-02-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("divmodtidi3"): Use canonical RTL.
+ ("divmodtisi3"): Likewise.
+ ("udivmoddi4", "udivmodtidi3"): Likewise.
+ ("divmodsi4", "divmoddisi3"): Likewise.
+ ("udivmodsi4", "udivmoddisi3"): Likewise.
+ ("udivsi3", "umodsi3"): Likewise.
+
+2004-02-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_mainpool_start): Delete the main pool
+ placeholder insn when chunkifying the pool.
+
+2004-02-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (PIC_OFFSET_TABLE_REGNUM): Define to INVALID_REGNUM when not
+ generating PIC code.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ h8300_expand_branch.
+ * config/h8300/h8300.c (h8300_expand_branch): New.
+ * config/h8300/h8300.md (ble, bleu, bge, bgeu, blt, bltu, bgt,
+ bgtu, beq, bne): Call h8300_expand_branch().
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add prototypes for
+ h8300_hard_regno_nregs and h8300_hard_regno_mode_ok.
+ * config/h8300/h8300.c (h8300_hard_regno_nregs): New.
+ (h8300_hard_regno_mode_ok): Likewise.
+ * config/h8300/h8300.h (HARD_REGNO_NREGS): Call
+ h8300_hard_regno_nregs().
+ (HARD_REGNO_MODE_OK): Call h8300_hard_regno_mode_ok().
+
+2004-02-18 Per Bothner <per@bothner.com>
+
+ * cpphash.h (struct cpp_buffer): Restore return_at_eof field. This
+ partly reverts my 2003-10-01 change, because we're back to logically
+ including <command line> inside the main line.
+ * cpplex.c (_cpp_get_fresh_line): Check return_at_eof field.
+ * cppmacro.c (cpp_scan_nooutput): Set return_at_eof of current buffer.
+ Fixes PR preprocessor/14103.
+
+ * cppfiles.c (_cpp_stack_include): When appropriate decrement
+ line_table's highest_location, fixing LAST_SOURCE_LINE_LOCATION.
+ (cpp_push_include): Don't need to increment pfile's line field.
+ * line-map.h (LAST_SOURCE_LINE_LOCATION): Only decrement by 1.
+
+ * c-ppoutput.c (print struct): New first_time field.
+ (init_pp_output): Set print.first_time.
+ (pp_file_change): Use print.first_time, rather than MAIN_FILE_P,
+ which is set also for (say) <command line>. Clear print.first_time.
+
+ * cppfiles.c (struct _cpp_file): Comment and type for pch field
+ does not match the code, so fix both.
+ (should_stack_file): Inline include_pch_p function.
+ (include_pch_p): Remove pointless function.
+
+ * cpphash.h (struct cpp_buffer): Remove unused search_cached field.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (four define_peephole2's): Use
+ h8300_regs_ok_for_stm().
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototype for
+ expand_a_rotate().
+ * config/h8300/h8300.c (expand_a_rotate): Remove the first
+ argument.
+ * config/h8300/h8300.md: Update all callers.
+
+2004-02-18 Jan Hubicka <jh@suse.cz>
+
+ * simplify-rtx.c (simplify_unary_operation): Deal with logicals on
+ floats.
+ (simplify_binary_operation): Deal with logicals on floats.
+
+ * i386.md (SSE fabs splitters): Emit new patterns.
+ (SSE cmov splitters): Likewise.
+ (sse_andv4sf3, sse_nandv4sf3, sse_iorv4sf3, sse_xorv4sf3
+ (sse_andv2df3, sse_nandv2df3, sse_iorv2df3, sse_xorv2df3): Do not use
+ subregs.
+ (sse_andsf3, sse_nandsf3, sse_xorsf3): Kill.
+ (sse_anddf3, sse_nanddf3, sse_xordf3): Kill.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (expand_a_rotate): Don't generate insns
+ by hand.
+ (output_a_rotate): Tweak a comment.
+ * config/h8300/h8300.md (*rotlqi3_1): Change to rotlqi3_1.
+ (*rotlhi3_1): Change to rotlhi3_1.
+ (*rotlsi3_1): Change to rotlsi3_1.
+
+2004-02-18 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/13866
+ * arm.c (load_multiple_operation): Don't insist that the source reg
+ of a post-increment component is the same as the destination.
+ (store_multiple_operation): Likewise.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Move movsf patterns into one section
+ of the file.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cfgloop.h, cfgloopanal.c, cpplex.c, except.h, loop-init.c,
+ loop-unroll.c, scan-decls.c, scan.h, stor-layout.c,
+ xcoffout.c, xcoffout.h, config/arm/mmintrin.h,
+ config/mips/linux64.h, config/pa/pa-64.h,
+ config/rs6000/aix51.h, config/rs6000/aix52.h,
+ config/rs6000/spe.md, config/sparc/linux.h,
+ config/sparc/linux64.h: Update copyright.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Move push patterns into one
+ section of the file.
+
+2004-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11326
+ * config/ia64/ia64.c (ia64_struct_value_rtx): Cope with NULL
+ fntype.
+
+2004-02-18 Paul Brook <paul@codesourcery.com>
+
+ * rtlanal.c (rtx_varies_p): Return 0 for NULL_RTX
+
+2004-02-18 Paul Brook <paul@codesourcery.com>
+
+ PR debug/12934
+ * dwarf2out.c (loc_descriptor_from_tree): Handle
+ EXPR_WITH_FILE_LOCATION.
+
+2004-02-18 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (zero_extendqidi2, zero_extendqidi2,
+ testdi_1_rex64, anddi_2, xordi_1_rex64, xordi_2_rex64): Remove
+ trailing whitespace from instructions.
+
+2004-02-17 Geoffrey Keating <geoffk@apple.com>
+
+ * configure.ac: When generating auto-build.h, pass
+ --enable-languages to the sub-configure.
+ Put quotes around ${program_transform_name} when generating
+ name of as, ld, nm, objdump.
+ * configure: Regenerate.
+
+2004-02-17 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in (s-check, s-config, s-conditions, s-flags)
+ (s-codes, s-constants, s-emit, s-recog, s-opinit, s-extract)
+ (s-peep, s-attr, s-attrtab, s-output, s-genrtl, s-modes)
+ (s-preds, s-iov): Do not depend on move-if-change.
+
+2004-02-17 James E Wilson <wilson@specifixinc.com>
+
+ * caller-save.c (insert_restore): Pass mem through copy_rtx.
+ (insert_save): Likewise.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_emit_stack_adjustment): Fix a
+ warning.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*one_complsi2_h8300): Change to
+ *one_cmplsi2_h8300.
+ (*one_complsi2_h8300hs): Change to *one_cmplsi2_h8300hs.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototype of
+ fix_bit_operand().
+ * config/h8300/h8300.c (fix_bit_operand): Remove the second
+ argument "what".
+ * config/h8300/h8300.md: Update all callers.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (fix_bit_operand): Change the name of
+ the last argument to "code" from "type".
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Remove an extern declaration of
+ rtx_equal_function_value_matters.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (fix_bit_operand): Don't generate insns
+ by hand.
+ * config/h8300/h8300.md (*andqi3_1): Change to andqi3_1.
+ (*iorqi3_1): Change to iorqi3_1.
+ (*xorqi3_1): Change to xorqi3_1.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.c, cfghooks.c, rtlanal.c, varasm.c: Fix comment
+ typos.
+
+2004-02-17 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_prologue_using_move, x86_epilogue_using_move): Disable for P4.
+
+2004-02-18 Alan Modra <amodra@bigpond.net.au>
+
+ PR optimization/14119
+ * combine.c (try_combine): When attemting to fix unrecognized insns,
+ don't delete SETs marked with REG_EH_REGION notes.
+
+2004-02-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (simplify_if_then_else): Do not replace
+ (if_then_else (ne reg 0) (0) (const_int)) by (reg) if the
+ modes differ.
+
+2004-02017 Steven Bosscher <stevenb@suse.de>
+
+ * (c-decl.c, c-semantics.c, calls.c, cgraph.c, cgraphunit.c,
+ function.c, integrate.c, print-tree.c, toplev.c, tree-optimize.c,
+ tree.h): Replace DECL_SAVED_INSNS with DECL_STRUCT_FUNCTION.
+ * ada/utils.c: Likewise.
+ * cp/decl.c: Likewise.
+ * f/com.c: Likewise.
+ * java/class.c: Likewise.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix comment typos.
+
+2004-02-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/t-iris6gld: Renamed to ...
+ * config/mips/t-irix-gld: ... this.
+ * config.gcc (mips-sgi-irix6*): Reflect this
+ (mips-sgi-irix5*): Use it with GNU ld.
+
+ * config/mips/irix6-crti.asm, config/mips/irix6-crtn.asm: Renamed
+ to ...
+ * config/mips/irix-crti.asm, config/mips/irix-crtn.asm: ... this.
+ * config/mips/t-irix-gld: Reflect this.
+ * config/mips/iris6gld.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+
+ * config/mips/iris5gld.h: New file.
+ * config.gcc (mips-sgi-irix5*): Use it with GNU ld.
+ Only use collect2 without gas.
+
+ * config/mips/iris6.h (IRIX6_STARTFILE_SPEC, IRIX6_ENDFILE_SPEC):
+ Renamed to IRIX_STARTFILE_SPEC, IRIX_ENDFILE_SPEC.
+ (STARTFILE_SPEC, ENDFILE_SPEC, SUBTARGET_EXTRA_SPECS): Reflect this.
+ * config/mips/iris6gld.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+
+ * config/mips/iris6.h (SUBTARGET_EXTRA_SPECS): Moved ...
+ * config/mips/iris5.h: ... here.
+
+ * config/mips/iris5.h (STARTFILE_SPEC, ENDFILE_SPEC): Renamed to
+ IRIX_STARTFILE_SPEC, IRIX_ENDFILE_SPEC.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Define.
+
+ * config/mips/iris5gas.h (STARTFILE_SPEC, ENDFILE_SPEC): Simplify
+ using irix_startfile_spec, irix_endfile_spec.
+
+2004-02-16 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c: Remove obsolete support for HPUX_ASM.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_expand_prologue): Don't generate
+ insns by hand.
+
+2004-02-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfghooks.c (split_edge): Speed up updating of dominators.
+
+2004-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11326
+ * c-common.c (flag_abi_version): Remove.
+ * c-common.h (flag_abi_version): Likewise.
+ * c-opts.c (c_common_handle_option): Remove OPT_fabi_version case.
+ * c.opt (fabi-version): Remove.
+ * calls.c (expand_call): Always pass a function type to
+ struct_value_rtx. Use convert_memory_address.
+ * common.opt (fabi-version): Add it.
+ * flags.h (flag_abi_version): Likewise.
+ (abi_version_at_least): New macro.
+ * opts.c (common_handle_option): Add OPT_fabi_version.
+ * toplev.c (flag_abi_version): Define it.
+ * config/ia64/ia64.c (ia64_struct_retval_addr_is_first_parm_p):
+ New function.
+ (ia64_output_mi_thunk): Use it.
+ (ia64_struct_value_rtx): Likewise.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_emit_stack_adjustment):
+ Don't generate insns by hand.
+
+2004-02-17 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/14178
+ * doc/invoke.texi (fabi-version): The default is 2 now.
+
+2004-02-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * loop-iv.c: New file.
+ * Makefile.in (loop-iv.o): New.
+ * basic_block.h (FOR_BB_INSNS, FOR_BB_INSNS_REVERSE): New macros.
+ * cfgloop.c (fill_sons_in_loop, get_loop_body_in_dom_order,
+ num_loop_branches): New functions.
+ * cfgloop.h (get_loop_body_in_dom_order, num_loop_branches,
+ iv_analysis_loop_init, iv_get_reaching_def, iv_analyse, get_iv_value,
+ find_simple_exit, iv_number_of_iterations, iv_analysis_done,
+ get_simple_loop_desc, free_simple_loop_desc): Declare.
+ (simple_loop_desc): New inline function.
+ (struct rtx_iv, struct niter_desc): New.
+ * cfgloopmanip.c (loopify): Specify semantics more precisely.
+ * expr.c (force_operand): Handle subregs of expressions created by
+ loop unroller.
+ * loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Move
+ parts of the initialization to toplev.c
+ * loop-unroll.c (loop_exit_at_end_p): New.
+ (unroll_and_peel_loops): Call iv_analysis_done.
+ (decide_peel_once_rolling, decide_peel_completely,
+ decide_unroll_stupid, decide_unroll_constant_iterations,
+ decide_unroll_runtime_iterations, decide_peel_simple,
+ peel_loop_simple, unroll_loop_stupid, unroll_loop_constant_iterations,
+ unroll_loop_runtime_iterations): Use new simple loop analysis.
+ * loop-unswitch.c (compare_and_jump_seq): New.
+ (may_unswitch_on_p): Renamed to ...
+ (may_unswitch_on): Use new iv analysis.
+ (reversed_condition): Export.
+ (unswitch_single_loop, unswitch_loop): Use new iv analysis.
+ * predict.c (estimate_probability): Use new simple loop analysis.
+ * rtl.h (get_mode_bounds, reversed_condition,compare_and_jump_seq,
+ canon_condition, simplify_using_condition): Declare.
+ * stor-layout.c (get_mode_bounds): New.
+ * toplev.c (rest_of_handle_loop2): Some parts of
+ initialization/finalization moved here from loop-init.c.
+
+2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (FIXED_REGISTERS): Add the soft frame
+ pointer.
+ (CALL_USED_REGISTERS): Likewise.
+ (REG_ALLOC_ORDER): Likewise.
+ (REG_CLASS) <GENERAL_REGS>: Likewise.
+
+2004-02-16 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/md.texi (Insn Canonicalizations): Document left-chaining
+ in associative operators.
+ * rtlanal.c (commutative_operand_precedence): Create some new
+ variables. Prefer a commutative operand on the left, then
+ binary expressions, then NEG and NOT.
+
+2004-02-16 Matthias Klose <doko@debian.org>
+
+ * config/t-slibgcc-elf-ver: Define SHLIB_NAME and SHLIB_SONAME
+ in terms of SHLIB_SOVERSION.
+ * config/m68k/t-slibgcc-elf-ver: New file.
+ * config/pa/t-slibgcc-elf-ver: New file.
+ * config.gcc (m68k-linux, parisc-linux): Use them when not
+ sjlj exceptions are not configured.
+
+2004-02-16 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (get_pc_symbol_name): Mark with GTY(()).
+
+2004-02-16 Zack Weinberg <zack@codesourcery.com>
+
+ * sdbout.c (sdb_debug_hooks): Correct the type_decl entry.
+
+2004-02-16 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/sourcebuild.texi: Mention backends.html.
+
+2004-02-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c, c-ppoutput.c, cpphash.h, cpplib.h, dbxout.c,
+ line-map.c, line-map.h, var-tracking.c: Fix comment
+ formatting.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * cse.c (cse_insn): Don't lose REG_NON_LOCAL_GOTO note.
+
+ * fold-const.c (operand_equal_p): Fix VECTOR_CST comparison.
+
+2004-02-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Remove unnecessary parallels from
+ all define_insn and define_split patterns.
+
+2004-02-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Remove explicit (set_attr "cc"
+ "clobber").
+
+2004-02-15 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (PRINT_OPERAND_PUNCT_VALID_P): Restore support for
+ '%#'.
+
+2004-02-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ia64/ia64.c, config/mips/mips.c,
+ config/mmix/mmix-modes.def: Fix comment typos.
+
+2004-02-15 Roger Sayle <roger@eyesopen.com>
+
+ * c-common.h (GET_DIRECTIVE_LINE): Remove unused macro.
+ (get_directive_line): Remove unused function prototype.
+
+2004-02-14 Josef Zlomek <zlomekj@suse.cz>
+
+ * tree-inline.c (copy_body_r): Do not replace ret_label.
+
+2004-02-14 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_four_jump_limit): New variable.
+ (k8_avoid_jump_misspredicts): Rename to ...
+ (ix86_avoid_jump_misspredicts): .. this one.
+ (ix86_pad_returns): Break out from ...
+ (ix86_reorg): ... this one; do ix86_avoid_jump_misspredicts when asked
+ to.
+ * i386.h (TARGET_FOUR_JUMP_LIMIT): New macro.
+
+2004-02-14 Josef Zlomek <zlomekj@suse.cz>
+
+ * emit-rtl.c (set_decl_incoming_rtl): Check whether the 0th element of
+ PARALLEL is NULL.
+
+2004-02-14 Per Bothner <per@bothner.com>
+
+ * fix-header.c (line_table): Move local variable in main to global.
+ * scan.h (line_table): Use it.
+ * scan-decls.c (scan_decls): Need to call linemap_lookup on token's
+ line (recently renamed to src_loc) before calling recognized_function.
+
+2004-02-14 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in: Fix comment typos.
+
+2004-02-14 Olivier Hainque <hainque@act-europe.fr>
+
+ * loop.c (check_dbra_loop): Use gen_int_mode instead of GEN_INT
+ for start_value when it is directly moved into reg, and factorize
+ the retrieval of GET_MODE (reg).
+
+2004-02-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_load_got_page): Delete.
+ (mips_load_got_global): Delete.
+ (mips_gotoff_page): Declare.
+ * config/mips/mips.md (UNSPEC_LOAD_GOT): New constant.
+ (*xgot_lo[sd]i, *got_disp[sd]i, *got_page[sd]i): Build an
+ UNSPEC_LOAD_GOT pattern rather than a MEM.
+ (*load_got[sd]i): New patterns.
+ * config/mips/mips.c (mips_got_alias_set, mips_load_got): Delete.
+ (mips_load_got_page, mips_load_got_global): Delete.
+ (mips_gotoff_page): New function.
+ (override_options): Don't initialize mips_got_alias_set.
+
+2004-02-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MASK_DEBUG_[ABEFI], TARGET_DEBUG_[ABEFI]_MODE)
+ (TARGET_MIPS4100, TARGET_MIPS4300, TARGET_MIPS4KC, TARGET_MIPS5KC)
+ (TARGET_SB1, TUNE_SB1, TUNE_SR71K, BIGGEST_MAX_ARGS_IN_REGISTERS)
+ (GO_PRINTF, GO_PRINTF2, GO_DEBUG_RTX, DFMODE_NAN, SFMODE_NAN): Delete.
+ (TARGET_SWITCHES): Remove MASK_DEBUG_[ABEFI].
+ * config/mips/mips.c: Fix some overly-long lines.
+ (SINGLE_WORD_MODE_P, PIC_OFFSET_TABLE_MASK): Delete.
+ (init_cumulative_args): Remove TARGET_DEBUG_E_MODE handling.
+
+2004-02-13 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.ac: Search for as, ld below libexec/gcc.
+ * configure: Regenerate.
+
+2004-02-14 Ben Elliston <bje@wasabisystems.com>
+
+ * config/arm/mmintrin.h (_mm_setwcx): Reverse arguments in call to
+ __builtin_arm_setwcx ().
+ * config/arm/arm.c (arm_expand_builtin): Generate operands
+ correctly and reverse their order in call to gen_iwmmxt_tmcr ().
+
+2004-02-14 Ben Elliston <bje@wasabisystems.com>
+
+ * config/arm/arm.c (bdesc_2arg): Correct builtin names "wmulsh"
+ and "wmuluh" to "wmulsm" and "wmulum", respectively.
+ * config/arm/arm.h (enum arm_builtins): Rename enumerators to
+ ARM_BUILTIN_WMULSM and ARM_BUILTIN_WMULUM.
+ * config/arm/mmintrin.h (_mm_mulhi_pi16): Update intrinsic call.
+ (_mm_mulhi_pu16): Likewise.
+
+2004-02-13 Zack Weinberg <zack@codesourcery.com>
+
+ * xcoffout.c (xcoff_assign_fundamental_type_number): Check
+ DECL_NAME != 0 before dereferencing.
+
+2004-02-13 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_output_symbolic_const): Remove.
+ (s390_output_addr_const_extra): Declare.
+ (s390_output_pool_entry): Remove FILE * argument.
+ * config/s390/s390.c (s390_output_symbolic_const): Remove.
+ (s390_output_addr_const_extra): New function.
+ (print_operand_address): Call output_addr_const instead of
+ s390_output_symbolic_const.
+ (print_operand): Likewise.
+ (s390_output_pool_entry): Use assemble_integer for symbolic constants.
+ Remove FILE * argument.
+ * config/s390/s390.h (OUTPUT_ADDR_CONST_EXTRA): Define.
+ * config/s390/s390.md ("*pool_entry"): Adapt s390_output_pool_entry
+ call.
+
+2004-02-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopanal.c (mark_irreducible_loops): Rewriten.
+ (struct edge, struct vertex, struct graph): New.
+ (dump_graph, new_graph, add_edge, dfs, check_irred, for_each_edge,
+ free_graph): New functions.
+
+2004-02-12 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (casesi_internal, casesi_internal_di):
+ Use ".set macro" to avoid warnings about multi-instruction
+ macros, since they're intentional.
+
+2004-02-12 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.h: Add include guards. Remove old, now incorrect,
+ comment about STANDARD_EXEC_PREFIX.
+
+ * Makefile.in (install-man): Use $(CPP_INSTALL_NAME) and
+ $(GCOV_INSTALL_NAME) to install manpages. Remove generic rule
+ for installing .1 manpages. Add rules for installing cpp
+ and gcov manpages under their installed names.
+
+2004-02-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.ac (gcc_cv_ld): Don't set to LD if target is not
+ host, but try LD_FOR_TARGET first.
+ * configure: Rebuilt.
+
+2004-02-12 Zack Weinberg <zack@codesourcery.com>
+
+ * dbxout.c: Move declaration of dbxout_type_decl outside
+ #ifdef DBX_DEBUGGING_INFO.
+ * c-parse.in: Don't give the asmdef production a type.
+
+2004-02-12 Zack Weinberg <zack@codesourcery.com>
+
+ * debug.h (struct gcc_debug_hooks): Add type_decl field.
+ (debug_nothing_tree_int): Prototype.
+ (dwarf_debug_hooks): Delete, unused.
+ * debug.c (do_nothing_debug_hooks): Update.
+ (debug_nothing_tree_int): New function.
+ * langhooks.h (struct lang_hooks_for_decls):
+ Remove builtin_type_decls field.
+ * langhooks-def.h (LANG_HOOKS_BUILTIN_TYPE_DECLS): Delete.
+ (LANG_HOOKS_DECLS): Update.
+ * toplev.c (rest_of_decl_compilation, rest_of_type_compilation):
+ Use debug_hooks->type_decl.
+ * dbxout.c (preinit_symbols): New static.
+ (dbx_debug_hooks, xcoff_debug_hooks): Update.
+ (dbxout_init): Don't call DBX_OUTPUT_STANDARD_TYPES or
+ lang_hooks.decls.builtin_type_decls. Do scan preinit_symbols
+ for symbols to output.
+ (dbxout_type_decl): New function.
+ (dbxout_symbol): If called before dbxout_init has run, queue
+ the symbol for later. Apply DBX_ASSIGN_FUNDAMENTAL_TYPE_NUMBER
+ to TYPE_DECLs before emitting them.
+ * xcoffout.c (assign_type_number): Delete.
+ (xcoff_type_numbers): New static table.
+ (xcoff_assign_fundamental_type_number): New function.
+ * xcoffout.h: Define DBX_ASSIGN_FUNDAMENTAL_TYPE_NUMBER, not
+ DBX_OUTPUT_STANDARD_TYPES. Remove unnecessary #ifdefs.
+ * sdbout.c: Include varray.h.
+ (deferred_global_decls): New static.
+ (sdb_debug_hooks): Update.
+ (sdbout_global_decl): If we can't emit something right now,
+ remember it in deferred_global_decls.
+ (sdbout_finish): Just scan deferred_global_decls; don't call getdecls.
+ (sdbout_init): Initialize deferred_global_decls.
+ * Makefile.in: Update dependencies of sdbout.o.
+ * dwarf2out.c (dwarf2out_type_decl): New function.
+ (dwarf2_debug_hooks): Update.
+ * vmsdbgout.c (vmsdbg_debug_hooks): Update.
+ * c-decl.c (getdecls): Just return 0.
+ (check_for_loop_decls): Don't use getdecls.
+ (record_builtin_type): Call debug_hooks->type_decl on the TYPE_DECL.
+ * c-objc-common.c (c_objc_common_finish_file): Don't use getdecls.
+
+2004-02-12 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_sched_reorder2): Remove.
+ (TARGET_SCHED_REORDER2): Do not redefine.
+
+2004-02-12 Zack Weinberg <zack@codesourcery.com>
+
+ * c-parse.in (maybe_type_qual): Delete.
+ (maybe_volatile, simple_asm_expr, asmdef, asm_stmt)
+ (asm_argument): New grammar rules.
+ (extdef_1): Use asmdef.
+ (maybeasm): Move down with other asm rules; use simple_asm_expr.
+ (xexpr): Move up with other expression rules.
+ (stmt): Use asm_stmt.
+
+ * c-typeck.c (build_asm_expr): New function - body mostly
+ pulled from build_asm_stmt.
+ (build_asm_stmt): Just handle tacking on the volatile qualifier.
+ * c-tree.h (build_asm_expr, build_asm_stmt): Update prototypes.
+
+2004-02-12 Richard Sandiford <rsandifo@redhat.com>
+
+ PR bootstrap/13617
+ * config/mips/mips-protos.h (mips_output_aligned_decl_common): Declare.
+ (mips_declare_object): Make variadic.
+ * config/mips/mips.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Use
+ mips_output_aligned_decl_common.
+ * config/mips/mips.c (mips_output_aligned_decl_common): New function.
+ (mips_declare_object): Make variadic.
+
+2004-02-12 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * function.c (update_epilogue_consts): Teach about binary operations.
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Don't kill
+ previous MEM_VOLATILE in REF.
+ * function.c (fixup_var_refs): Save volatile_ok and set to 1.
+ * expr.c (emit_block_move_via_movstr): Save and restore volatile_ok.
+
+2004-02-12 Gunther Nikl <gni@gecko.de>
+
+ * config.gcc: Restore support for m68k-openbsd.
+
+2004-02-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-optimize.c (tree_rest_of_compilation): Do not release
+ DECL_ARGUMENTS.
+
+2004-02-11 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/install.texi: Fix the spelling of "explicitly".
+
+2004-02-11 Eric Christopher <echristo@redhat.com>
+
+ * cppcharset.c (_cpp_interpret_string_notranslate): Rename and
+ duplicate argument structure of cpp_interpret_string.
+ * cpphash.h: Move prototype...
+ * cpplib.h: Here.
+ * cpplib.c: Fix calls to match new function signature.
+
+2004-02-11 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/456
+ * cppexp.c (num_binary_op): Don't allow comma operators in #if
+ constant expressions at all outside C99 mode if pedantic.
+
+2004-02-11 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_log10 and OTI_log2.
+ (log10_optab, log2_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize log10_optab and log2_optab.
+ * genopinit.c (optabs): Implement log10_optab and log2_optab
+ using log10?f2 and log2?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG10{,F,L}
+ using log10_optab, and BUILT_IN_LOG2{,F,L} using log2_optab.
+ (expand_builtin): Expand BUILT_IN_LOG10{,F,L} and BUILT_IN_LOG2{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (log10sf2, log10df2, log10xf2, log2sf2,
+ log2df2, log2xf2): New patterns to implement log10, log10f, log10l,
+ log2, log2f and log2l built-ins as inline x87 intrinsics.
+
+2004-02-11 Richard Henderson <rth@redhat.com>
+
+ PR target/1532
+ * flow.c (insn_dead_p): A clobber of a dead hard register is a
+ dead insn after reload.
+
+2004-02-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * tree.h (frame_base_decl): Add GTY marker.
+ * var-tracking.c (frame_base_decl): Likewise.
+
+2004-02-11 Daniel Berlin <dberlin@dberlin.org>
+
+ * dwarf2out.c (output_loc_list): Remove no longer necessary, and now
+ incorrect, hunk.
+ (add_location_or_const_value_attribute): Use text_section_label,
+ not TEXT_SECTION_NAME.
+
+2004-02-11 Per Bothner <per@bothner.com>
+
+ Represent column numbers using line-map's source_location.
+ The "next available source_location" is now managed internally by
+ line-maps.c rather than by clients.
+ * line-map.h (struct line_map): New field column_bits.
+ <from_line>: Rename field to start_location.
+ (struct line_maps): New fields highest_location and max_column_hint.
+ (linemap_check_files_exited): New declaration.
+ (linemap_line_start): New declaration.
+ (linemap_add): Remove from_line parameter; use highest_location field.
+ (SOURCE_LINE, LAST_SOURCE_LINE): Modify to use column_bits.
+ (SOURCE_COLUMN, LAST_SOURCE_LINE_LOCATION): New macros.
+ (CURRENT_LINE_MAP): Remove macro.
+ (linemap_position_for_column): New inline function.
+ * line-map.c (linemap_init): Clear new fields.
+ (linemap_check_files_exited): New function, extracted from ...
+ (linemap_free): Use linemap_check_files_exited.
+ (linemap_add): Remove from_line parameter. Various updates.
+ (linemap_line_start): New function.
+ (linemap_lookeup): Update for new field names.
+ * cpphash.h (struct cpp_reader) <map>: Field removed. Because
+ linemap_position_for_column may unpredictably change the current map,
+ it is cleaner and simpler for us to not cache it in cpp_reader.
+ (struct cpp_buffer): New sysp field.
+ Changed warned_cplusplus_comments and from_stage3 to bitfields.
+ * cppinit.c (cpp_read_min_file): pfile->map no longer exists.
+ * cpplib.c (do_line, do_linemarker, _cpp_do_file_change): Get
+ current map using linemap_lookup.
+ (do_linemarker): Also set buffer's sysp field.
+ (destringize_and_run): No longer need to decrement current line.
+ * cppfiles.c (_cpp_stack_file): Set sysp from and in buffer.
+ (search_path_head, open_file_failed): Use buffer's sysp.
+ (cpp_make_system_header): Get current map using linemap_lookup.
+ Also set buffer's sysp flag.
+ * cppmacro.c (_cpp_builtin_macro_text): Likewise use linemap_lookup.
+ * cpphash.h (CPP_INCREMENT_LINE): New macro.
+ (struct cpp_buffer): Moved fields saved_cur, saved_rlimit to ...
+ (struct cpp_reader): ... and adding saved_line_base field.
+ * cpptrad.c (_cpp_overlay_buffer, _cpp_remove_overlay):
+ Update accordingly. Don't adjust line.
+ (_cpp_scan_out_logical_line): Use CPP_INCREMENT_LINE.
+ * cpphash.c (CPP_IN_SYSTEM_HEADER): Replaced macro by ...
+ (cpp_in_system_header): ... new inline function, using buffer's sysp.
+ * cpperror.c (_cpp_begin_message): Update to use cpp_in_system_header.
+ * cpplex.c (_cpp_lex_direct): Likewise.
+ * cppmacro.c (_cpp_builtin_macro_text): Likewise.
+ * cppmacro.c (_cpp_create_definition): Use buffer's sysp field.
+ * cpplib.h (struct cpp_token): Rename line field to src_loc.
+ Remove col field as it is now subsumed by src_loc.
+ * cpperror.c: Update various field, parameter, and macro names.
+ (print_location): If col==0, try SOURCE_COLUMN of line.
+ (cpp_error): Use cur_token's src_loc field, rather than line+col.
+ * cpplib.c (do_diagnostic): Token's src_loc fields replaces line+col.
+ * cpplex.c (_cpp_process_line_notes, _cpp_lex_direct,
+ _cpp_skip_block_comment): Use CPP_INCREMENT_LINE.
+ (_cpp_temp_token): Replace cpp_token's line+col fields by src_loc.
+ (_cpp_get_fresh_line): Don't need to adjust line for missing newline.
+ (_cpp_lex_direct): Use linemap_position_for_column.
+ * c-ppoutput.c (maybe_print_line, print_line): Don't take map
+ parameter. Instead get it from the line_table global. Adjust callers.
+ (print): Remove map field. Replace line field to src_line.
+ (init_pp_output, account_for_newlines, maybe_print_line): Adjust.
+ (cb_line_change): Use SOURCE_COLUMN. Minor optimizations.
+ (pp_file_change): Use MAIN_FILE_P since we cannot checked print.map.
+ Use LAST_SOURCE_LINE_LOCATION to "catch up" after #include.
+ * cpptrad.c (copy_comment): Rename variable.
+ * c-lex.c (map): Remove static variable, for same reason we removed
+ cpp_reader's map field.
+ (cb_line_change, cb_def_pragma, cb_define, cb_undef): Hence we need
+ to call linemap_lookup.
+ (cb_line_change): Token's line field replaced by src_loc.
+ (fe_file_change): Use MAINFILE_P and LAST_SOURCE_LINE macros.
+ Don't save new_map.
+
+ * cpphash.h, cpperror.c, cpplib.h: Some renames of fileline to
+ source_location.
+
+2004-02-11 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/rs6000/altivec.md (*movv4si_internal): At least one
+ operand must be register_operand.
+ (*movv8hi_internal1): Likewise.
+ (*movv16qi_internal1): Likewise.
+ (*movv4sf_internal1): Likewise.
+
+2004-02-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md ("*movv2si_internal"): Check for register
+ operand.
+ (movv4hi_internal): Same.
+ (movv2sf_internal): Same.
+ (movv1di_internal): Same.
+
+2004-02-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/mips/mips.h (TARGET_OLDABI): Define. Use TARGET_NEWABI and
+ TARGET_OLDABI consistently.
+ * config/mips/mips.c (function_arg,mips_setup_incoming_varargs,
+ mips_va_arg,override_options,compute_frame_size,
+ mips_initial_elimination_offset,mips16_fp_args,build_mips16_call_stub
+ ,mips_return_in_memory,mips_strict_argument_naming): Use TARGET_NEWABI
+ and TARGET_OLDABI consistently.
+ * config/mips/mips.md (exception_receiver): Likewise.
+ * config/mips/linux64.h: Likewise.
+
+2004-02-11 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (rs6000_override_options)
+ Set AltiVec ABI and vrsave as default for ppc64 linux.
+ (init_cumulative_args): Post error, if try to return
+ value in AltiVec register without enable AltiVec.
+ (function_arg_advance): Ditto for passing arguments.
+
+2004-02-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * emit-rtl.c (mark_label_nuses): Check that a LABEL_REF refers to
+ a label before updating its usage count.
+
+2004-02-10 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/install.texi: Remove extra cd.
+
+2004-02-10 Ziemowit Laski <zlaski@apple.com>
+
+ * c-common.c (vector_size_helper): Remove; call
+ reconstruct_complex_type() instead.
+ * tree.c (reconstruct_complex_type): New function
+ (formerly vector_size_helper() in c-common.c).
+ (make_vector): Make externally visible.
+ * tree.h (reconstruct_complex_type, make_vector): Add prototypes.
+
+2004-02-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ h8300_regs_ok_for_stm.
+ * config/h8300/h8300.c (h8300_regs_ok_for_stm): New.
+ * config/h8300/h8300.md (stm_h8300s_2_advanced,
+ stm_h8300s_2_normal, stm_h8300s_2, stm_h8300s_3_advanced,
+ stm_h8300s_3_normal, stm_h8300s_3, stm_h8300s_4_advanced,
+ stm_h8300s_4_normal, stm_h8300s_4, ldm_h8300s_2_advanced,
+ ldm_h8300s_2_normal, ldm_h8300s_2, ldm_h8300s_3_advanced,
+ ldm_h8300s_3_normal, ldm_h8300s_3, ldm_h8300s_4_advanced,
+ ldm_h8300s_4_normal, ldm_h8300s_4): Use
+ h8300_regs_ok_for_stm().
+
+2004-02-10 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c/14088
+ * real.c (real_from_string): Look for 'X' as well as 'x' in
+ hexfloat strings.
+
+2004-02-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Remove an incorrect comment about
+ peephole2. Add comments.
+
+2004-02-10 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/14058
+ * emit-rtl.c (set_decl_incoming_rtl): New.
+ * tree.h (set_decl_incoming_rtl): New.
+ * function.c (assign_parms): Use set_decl_incoming_rtl for setting
+ DECL_INCOMING_RTL.
+ * ada/misc.c (adjust_decl_rtl): Likewise.
+
+2004-02-10 Per Bothner <per@bothner.com>
+
+ * c-opts.c (c_common_post_options): Don't emit working directory
+ in cpp output if -P was specified.
+
+2004-02-10 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c/14092
+ * fold-const.c (fold) <NEGATE_EXPR>: Convert result of
+ negate_expr back to the original type.
+
+2004-02-10 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Don't
+ bump retaddr here.
+
+2004-02-10 Paolo Bonzini <bonzini@gnu.org>
+
+ * rtl.h (schedule_insns, schedule_ebbs, fix_sched_param,
+ gen_lowpart_SUBREG): Move under the file in which they
+ are actually declared.
+
+2004-02-10 Arnaud Charlet <charlet@act-europe.fr>
+
+ * doc/sourcebuild.texi: Add libada documentation.
+
+ * doc/install.texi: Update documentation on Ada build, now
+ that the GNAT lib and tools are built automatically.
+
+2004-02-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TARGET_GPWORD): Return false for TARGET_NEWABI
+ && TARGET_IRIX.
+
+2004-02-09 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (get_super_receiver): Move '#ifdef OBJCPLUS'
+ boundaries outside build_component_ref() call (a macro in ObjC++).
+
+2004-02-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa-protos.h (xtensa_copy_incoming_a7): Update.
+ (init_cumulative_args): Likewise.
+ (a7_overlap_mentioned_p): Delete prototype.
+ * config/xtensa/xtensa.c (struct machine_function): Replace
+ incoming_a7_copied field with need_a7_copy and vararg_a7 flags.
+ Add set_frame_ptr_insn field.
+ (xtensa_emit_move_sequence): Update call to xtensa_copy_incoming_a7.
+ (xtensa_copy_incoming_a7): Rewrite to check need_a7_copy flag and check
+ if the operand is an argument in a7. If so, copy a7 to a new pseudo
+ at the function entry and replace the operand with the pseudo.
+ (init_cumulative_args): Remove unused arguments. Add new "incoming"
+ argument and record this flag in CUMULATIVE_ARGS.
+ (function_arg): Remove result_mode and special-case code to handle
+ arguments in a7. Instead, set need_a7_copy flag when there is an
+ incoming argument in a7.
+ (xtensa_expand_prologue): Remove code to search for set_frame_ptr insn
+ and use the value recorded in cfun->machine->set_frame_ptr_insn.
+ (xtensa_builtin_saveregs): Check for negative gp_left value. Set
+ need_a7_copy and vararg_a7 flags. Use move_block_from_reg instead of
+ special-case code.
+ (a7_overlap_mentioned_p): Delete.
+ * config/xtensa/xtensa.h (CUMULATIVE_ARGS): Add "incoming" flag.
+ (INIT_CUMULATIVE_ARGS, INIT_CUMULATIVE_INCOMING_ARGS): Remove useless
+ arguments to init_cumulative_args and pass "incoming" flag instead.
+ (BLOCK_REG_PADDING): Delete.
+ * config/xtensa/xtensa.md (movdi, movsf, movdf): Remove unnecessary
+ checks for reload_in_progress and reload_completed. Update calls to
+ xtensa_copy_incoming_a7.
+ (ashlsi3): Rename existing insn to ashlsi3_internal. Add expander
+ to call xtensa_copy_incoming_a7.
+
+2004-02-09 DJ Delorie <dj@redhat.com>
+
+ * config/i386/xm-djgpp.h (GCC_DRIVER_HOST_INITIALIZATION): No
+ longer modify standard_exec_prefix, standard_bindir_prefix, or
+ standard_startfile_prefix.
+
+2004-02-09 James E Wilson <wilson@specifixinc.com>
+
+ PR c++/11295
+ * c-common.c (c_expand_expr, case STMT_EXPR): Change expand_expr call
+ to expand_expr_real call, and pass in alt_rtl as last argument.
+
+ PR libstdc++/5625
+ * builtin-types.def (BT_WORD, BT_FN_WORD_PTR): New.
+ * builtins.c (expand_builtin): Handle BUILT_IN_EXTEND_POINTER.
+ * builtins.def (BUILT_IN_EXTEND_POINTER): New.
+ * except.c (expand_builtin_extend_pointer): New.
+ * except.h (expand_builtin_extend_pointer): Declare.
+
+2004-02-09 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): Remove splitting slow
+ unaligned loads and stores.
+
+2004-02-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5.h (BSS_SECTION_ASM_OP): Define.
+ * config/mips/iris6.h (BSS_SECTION_ASM_OP): Undef.
+
+ * config/mips/iris6.h (TARGET_ASM_NAMED_SECTION): Moved ...
+ * config/mips/iris5.h: ... here.
+ * config/mips/iris5gas.h (TARGET_ASM_NAMED_SECTION): Remove.
+
+ * config/mips/iris6.h (EXTRA_SECTION_FUNCTIONS): Move ...
+ * config/mips/iris5.h: ... here.
+
+2004-02-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.ac: Remove default executable files before AC_PROG_CC.
+ * configure: Regenerate.
+
+2004-02-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/13721
+ * config/h8300/h8300.c (byte_reg): Call abort() if asked to
+ print a operand other than a register.
+
+2004-02-09 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <NOP_EXPR>: Use the original type conversion
+ tree code rather than call fold_convert, which doesn't specify a
+ default floating point to integer conversion.
+
+2004-02-08 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c, config/m68k/m68k.md (SGS, SGS_CMP_ORDER): Remove
+ code to support SGS assembler. Reformat adjacent code where possible.
+ * config/m68k/m68k.c (switch_table_difference_label_flag): Remove
+ definition.
+ * config/m68k/m68k.h (PRINT_OPERAND_PUNCT_VALID_P): Remove support
+ for '%#'.
+ * config/m68k/linux.h, config/m68k/m68k.c,
+ * config/m68k/math-68881.h: Replace `%#' with `#' in inline asm
+ macros and asm_printf() format strings.
+ * config/m68k/m68kelf.h (ASM_OUTPUT_CASE_END): Remove macro definition.
+ * config/m68k/linux.h: Update copyright.
+ * config/m68k/linux.h, config/m68k/m68k.c: Remove traling whitespace.
+
+2004-02-08 Andreas Schwab <schwab@suse.de>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (REGISTER_NAMES): Prefix each name with
+ REGISTER_PREFIX.
+ * (M68K_FP_REG_NAME): New macro to specify an alternate name for the
+ frame pointer register, overridable by OS targets.
+ * (M68K_REGNAME): Macro to obtain register name for asm output,
+ eventually replacing %a6 with M68K_FP_REG_NAME.
+ * config/m68k/coff.h (REGISTER_NAMES): Don't redefine.
+ * config/m68k/linux.h (REGISTER_NAMES): Likewise.
+ * config/m68k/m68kelf.h (REGISTER_NAMES): Likewise.
+ * config/m68k/netbsd-elf.h (REGISTER_NAMES): Likewise.
+ * config/m68k/m68k.c: Use M68K_REGNAME(x) in place of reg_names[x].
+
+2004-02-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * target-def.h (TARGET_STRUCT_VALUE_RTX): Define as
+ hook_rtx_tree_int_null.
+ * targhooks.c (default_struct_value_rtx): Remove.
+ * targhooks.h: Remove the prototype for
+ default_struct_value_rtx.
+ * config/alpha/alpha.c, config/arc/arc.c, config/avr/avr.c,
+ config/fr30/fr30.c, config/h8300/h8300.c, config/i386/i386.c,
+ config/ip2k/ip2k.c, config/iq2000/iq2000.c,
+ config/m32r/m32r.c, config/mcore/mcore.c, config/mips/mips.c,
+ config/mn10300/mn10300.c, config/pdp11/pdp11.c,
+ config/rs6000/rs6000.c, config/s390/s390.c,
+ config/stormy16/stormy16.c, config/v850/v850.c,
+ config/xtensa/xtensa.c (TARGET_STRUCT_VALUE_RTX): Remove.
+ * doc/tm.texi (TARGET_STRUCT_VALUE_RTX): Document the default.
+
+2004-02-08 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * README.Portability: Change "ISO C89" to "ISO C90".
+ * c-parse.in (primary, initelt): Likewise.
+
+2004-02-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * real.c (encode_ibm_extended): Normalize the input value before
+ converting it to a double. Handle the case where a normal value
+ rounds to infinity.
+
+2004-02-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-objc-common.c (c_cannot_inline_tree_fn): Fix a typo in a
+ warning.
+ * cse.c (preferrable): Change to preferable. Update all of its
+ callers.
+ * genautomata.c (ainsn): Change
+ first_ainsn_with_given_equialence_num to
+ first_ainsn_with_given_equivalence_num. Update all of its
+ references.
+
+2004-02-08 Jan Hubicka <jh@suse.cz>
+
+ * schedule-ebb.c (schedule_ebbs): Do not allocate reg life data.
+
+2004-02-07 David Edelsohn <edelsohn@gnu.org>
+
+ * function.c (assign_parms): Fix formatting.
+
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * default.h (PROMOTE_PROTOTYPES): Remove.
+ * system.h (PROMOTE_FUNCTION_RETURN, PROMOTE_PROTOTYPES,
+ STRUCT_VALUE_REGNUM, SETUP_INCOMING_VARARGS,
+ EXPAND_BUILTIN_SAVEREGS): Poison.
+ * target-def.h (TARGET_PROMOTE_FUNCTION_RETURN): Define as
+ hook_bool_tree_false.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ * target.h: Replace SETUP_INCOMING_VARARGS with
+ targetm.calls.setup_incoming_varargs().
+ * targhooks.c (default_promote_function_return): Remove.
+ (default_promote_prototypes): Likewise.
+ (default_struct_value_rtx): Always abort().
+ (default_expand_builtin_saveregs): Always print an error
+ message.
+ (default_setup_incoming_varargs): Do nothing.
+ (default_pretend_outgoing_varargs_named): Don't depend on
+ SETUP_INCOMING_VARARGS.
+ * targhooks.h: Remove the prototype for
+ default_promote_function_return and
+ default_promote_prototypes.
+
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (SHARED_SECTION_ASM_OP): Poison.
+ * varasm.c (data_section): Don't use SHARED_SECTION_ASM_OP.
+ * doc/tm.texi (SHARED_SECTION_ASM_OP): Remove.
+
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
+
+ Bug 13856
+ * c-decl.c (diagnose_mismatched_decls): Only give special
+ treatment when olddecl is DECL_BUILT_IN, if C_DECL_INVISIBLE
+ is also true.
+ (merge_decls): Don't clear DECL_BUILT_IN_CLASS and
+ DECL_FUNCTION_CODE when defining a built-in function.
+ Don't update DECL_ESTIMATED_INSNS.
+ * dwarf2out.c (dwarf2out_decl): Don't ignore built-in
+ FUNCTION_DECLs.
+ * tree.h: Delete DECL_ESTIMATED_INSNS.
+ * tree-inline.c (struct inline_data): Delete inlined_insns field.
+ (expand_call_inline, optimize_inline_calls): Don't update
+ DECL_ESTIMATED_INSNS nor inlined_insns.
+ * cgraphunit.c (cgraph_analyze_function): Don't update
+ DECL_ESTIMATED_INSNS.
+
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.c (shadow_warning): Delete.
+ * c-common.h (free_parser_stacks, shadow_warning, sw_kind): Delete.
+ * c-decl.c (warn_if_shadowing): Issue shadow warnings directly.
+ * c-opts.c (c_common_parse_file): Don't call free_parser_stacks.
+ * c-parse.in (free_parser_stacks): Delete.
+
+2004-02-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in, config/t-slibgcc-darwin, config/t-slibgcc-elf-ver,
+ config/t-slibgcc-sld, config/mips/t-iris5-6, config/sh/t-linux:
+ Use the top level mkinstalldirs, not the one in the gcc subdir.
+ * mkinstalldirs: Remove (from the gcc subdir).
+
+2004-02-07 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/13696
+ * fold-const.c (fold_convert): New function to provide type
+ conversion to the middle-end without using convert.
+ (negate_expr, associate_trees, size_diffop, omit_one_operand,
+ operand_equal_for_comparison_p, pedantic_omit_one_operand,
+ invert_truthvalue, optimize_bit_field_compare, range_binop,
+ decode_field_reference, make_range, build_range_check, unextend,
+ fold_truthop, extract_muldiv_1, fold_mathfn_compare,
+ fold_binary_op_with_conditional_arg, fold_inf_compare,
+ fold_single_bit_test, fold, multiple_of_p): Replace all calls to
+ convert with calls to fold_convert.
+
+2004-02-07 Jan Hubicka <jh@suse.cz>
+
+ * genrecog.c (find_operand): add extra argument stop.
+ (validate_pattern): Verify that mach_dup is duplicating operand
+ defined lexically earlier.
+
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config.gcc: Don't mention MAX_LONG_TYPE_SIZE.
+ * system.h (MAX_LONG_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE,
+ MAX_WCHAR_TYPE_SIZE, GCOV_TYPE_SIZE): Poison.
+ * config/avr/avr.h, config/h8300/h8300.h, config/i386/i386.h,
+ config/ia64/ia64.h, config/ip2k/ip2k.h,
+ config/iq2000/iq2000.h, config/mips/iris5.h,
+ config/mips/mips.h, config/pa/pa-64.h, config/pa/pa.h,
+ config/rs6000/aix51.h, config/rs6000/aix52.h,
+ config/rs6000/darwin.h, config/rs6000/rs6000.h,
+ config/s390/s390.h, config/sh/sh.h, config/sparc/freebsd.h,
+ config/sparc/linux.h, config/sparc/linux64.h,
+ config/sparc/netbsd-elf.h, config/sparc/sparc.h,
+ config/xtensa/xtensa.h: Remove the definitions of
+ MAX_LONG_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE, and/or
+ MAX_WCHAR_TYPE_SIZE.
+ * doc/tm.texi (MAX_LONG_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE,
+ MAX_WCHAR_TYPE_SIZE, GCOV_TYPE_SIZE): Remove.
+
+2004-02-07 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR bootstrap/13990
+ * config/m68hc11/m68hc11.md ("doloop_end"): Pass dummy arguments to
+ gen_rtx_NE.
+
+2004-02-07 Josef Zlomek <zlomekj@suse.cz>
+
+ * var-tracking.c (vt_add_function_parameters): Surround checkings by
+ #ifdef ENABLE_CHECKING and #endif.
+
+2004-02-07 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_expr_p, negate_expr): Optimize -(A+B) into
+ either (-A)-B or (-B)-A, if A or B is easily negated respectively.
+ (fold) <MINUS_EXPR>: Optimize (A*C) - (B*C) -> (A-B)*C for both
+ integer types and floating point with unsafe_math_optimizations.
+ Add similar optimization for (A*C1) - (A*C2) -> A*(C1-C2).
+ Optimize A - B as A + (-B), if B is easily negated.
+
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-ppoutput.c, cfganal.c, diagnostic.h, print-rtl.c,
+ config/darwin.c, config/darwin.h, config/ia64/ia64-c.c,
+ config/m32r/linux.h, config/rs6000/ppc64-fp.c,
+ config/sparc/openbsd.h, doc/makefile.texi, doc/passes.texi:
+ Update copyright.
+
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-ppoutput.c, var-tracking.c: Fix comment typos.
+
+2004-02-06 James E Wilson <wilson@specifixinc.com>
+
+ * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Only define for
+ glibc 2.3 or better.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi (TARGET_FLOAT_LIB_COMPARE_RETURNS_BOOL): Change
+ to FLOAT_LIB_COMPARE_RETURNS_BOOL.
+
+2004-02-07 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c.
+ (SHLIB_MAPFILES): Add libgcc-ppc64.ver.
+ (SHLIB_MKMAP_OPTS): Delete.
+ (TARGET_LIBGCC2_CFLAGS): Add -specs.
+ (bispecs): Add rule.
+ * config/rs6000/libgcc-ppc64.ver: New file.
+ * config/rs6000/ppc64-fp.c (__fixtfdi, __floatditf): New functions.
+ (__floatdidf, __floatdisf): Optimize multiply.
+ (__fixunstfdi): New function.
+ * config/rs6000/rs6000.c (rs6000_complex_function_value): Allow for
+ real and imag parts larger than one register.
+ (function_arg): Correct type of reg used when fp arg split partially
+ to stack.
+ * config/rs6000/darwin-ldouble.c: Protect with #if !_SOFT_FLOAT
+ and __MACH__ or __powerpc64__.
+
+2004-02-06 Roger Sayle <roger@eyesopen.com>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
+ * builtins.c (expand_builtin_signbit): Use extract_bit_field instead
+ of gen_highpart or gen_lowpart when the floating point format is
+ wider than the result mode.
+
+2004-02-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * dwarf2out.c (loclabel_num): Move into #ifdef
+ DWARF2_DEBUGGING_INFO.
+
+2004-02-06 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (build_super_template) the 'class' field of
+ 'struct _objc_super' shall be named 'super_class' #ifdef OBJCPLUS.
+ (get_super_receiver): Likewise.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (check_eliminable_occurrences): Optimize the reset
+ of can_eliminate.
+ (eliminate_regs_in_insn): Likewise.
+
+2004-02-06 Daniel Berlin <dberlin@dberlin.org>
+ Josef Zlomek <zlomekj@suse.cz>
+
+ * dwarf2out.c (struct gcc_debug_hooks): Call dwarf2out_begin_function
+ at the beginning of function, call dwarf2out_var_location for
+ NOTE_INSN_VAR_LOCATION note.
+ (struct var_loc_node, struct var_loc_list_def, loclabel_num,
+ decl_loc_table): New.
+ (lookup_decl_loc): New function.
+ (add_var_loc_to_decl): New function.
+ (based_loc_descr): Added parameter can_use_fbreg, DW_OP_fbreg is used
+ only if can_use_fbreg.
+ (mem_loc_descriptor): Added parameter can_use_fbreg, pass it to other
+ functions.
+ (loc_descriptor): Likewise. Process VAR_LOCATION.
+ (concat_loc_descriptor): Call loc_descriptor with can_use_fbreg == true.
+ (loc_descriptor_from_tree): Call mem_loc_descriptor with
+ can_use_fbreg == true.
+ (add_location_or_const_value_attribute): Added parameter enum
+ dwarf_attribute attr, generate attribute ATTR. Create the location list.
+ (add_bound_info): Call loc_descriptor with can_use_fbreg == true.
+ (gen_formal_parameter_die): Call add_location_or_const_value_attribute
+ with attr == DW_AT_location.
+ (gen_subprogram_die): Generate the location list for DW_AT_frame_base
+ if frame_base_decl is defined and has a location list.
+ (gen_variable_die): Call add_location_or_const_value_attribute with
+ attr == DW_AT_location.
+ (dwarf2out_var_location): New function.
+ (dwarf2out_begin_function): New function.
+ (dwarf2out_init): Create decl_loc_table.
+
+2004-02-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * loop.c (force_movables): Transitively increase the priorities of
+ all insns forces by an insn, not just the first one.
+
+2004-02-06 Josef Zlomek <zlomekj@suse.cz>
+ Daniel Berlin <dberlin@dberlin.org>
+
+ Josef Zlomek <zlomekj@suse.cz>
+ * Makefile.in (var-tracking.o): New.
+ * common.opt (fvar-tracking): New.
+ * flags.h (flag_var_tracking): New.
+ * gengtype.c (adjust_field_rtx_def): NOTE_INSN_VAR_LOCATION was added.
+ * opts.c (common_handle_option): Add OPT_fvar_tracking.
+ * print-rtl.c (print_rtx): NOTE_INSN_VAR_LOCATION was added.
+ * rtl.c (note_insn_name): Likewise.
+ * rtl.def (VAR_LOCATION): New.
+ * rtl.h (NOTE_VAR_LOCATION): New.
+ (NOTE_VAR_LOCATION_DECL): New.
+ (NOTE_VAR_LOCATION_LOC): New.
+ (enum insn_note): NOTE_INSN_VAR_LOCATION was added.
+ (variable_tracking_main): New exported function.
+ * timevar.def (TV_VAR_TRACKING): New.
+ * toplev.c (enum dump_file_index): Added DFI_vartrack.
+ (dump_file): "vartrack" was added (-dV).
+ (flag_var_tracking): New.
+ (f_options): "var-tracking" was added.
+ (rest_of_handle_variable_tracking): New function.
+ (rest_of_compilation): Run variable tracking.
+ (process_options): If user has not specified flag_var_tracking set it
+ according to optimize, debug_info_level and debug_hooks.
+ * tree.h (frame_base_decl): New.
+ * var-tracking.c: New file.
+ * config/ia64/ia64.c (ia64_flag_var_tracking): New variable.
+ (ia64_override_options): Set flags to run variable tracking in machine
+ dependent reorg instead of toplev.c.
+ (ia64_reorg): Run variable tracking if wanted.
+ * doc/invoke.texi: Mention variable tracking in -dV,
+ add and -fvar-tracking.
+ * doc/passes.texi: Added variable tracking pass.
+
+ Daniel Berlin <dberlin@dberlin.org>
+ * debug.h (struct gcc_debug_hooks): Added var_location debug hook.
+ * dbxout.c (dbx_debug_hooks): Likewise.
+ (xcoff_debug): Likewise.
+ * debug.c (do_nothing_debug_hooks): Likewise.
+ * dwarf2out.c (dwarf2_debug_hooks): Likewise.
+ * dwarfout.c (dwarf_debug_hooks): Likewise.
+ * sdbout.c (sdb_debug_hooks): Likewise.
+ * vmsdbgout.c (vmsdbg_debug_hooks): Likewise.
+ * final.c (final_scan_insn): Call var_location debug hook for each
+ NOTE_INSN_VAR_LOCATION.
+
+2004-02-06 Jan Hubicka <jh@suse.cz>
+
+ * flow.c (update_life_info): Allocate reg_deaths when called from
+ scheudler.
+ (attempt_auto_inc): Update life ranges accordingly.
+
+2004-02-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR debug/11816
+ * dwarf2out.c (gen_decl_die): Handle anonymous struct members.
+
+2004-02-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * cfganal.c (flow_call_edges_add): Never split a libcall block.
+
+2004-02-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * dwarf2out.c (output_loc_list): Don't use deltas if we have
+ a separate line info table in use.
+ Use the correct size for terminators.
+ (output_die): Use offset, not delta.
+
+2004-02-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * doc/invoke.texi: Remove the pni option from -mfpmath=.
+
+2004-02-06 Jan Hubicka <jh@suse.cz>
+
+ * recog.c (split_all_insns): Do not update reg info.
+ * regrename.c (regrename_optimize): Likewise.
+ * toplev.c (rest_of_handle_reorder_blocks): Likewise.
+ * flow.c (struct propagate_block_info): Add insn_num field.
+ (reg_deaths): New array.
+ (life_analysis): Free reg_deaths info.
+ (allocate_reg_life_data): Allocate reg_deaths array.
+ (propagate_one_insn): Use new array.
+ (init_propagate_block): Initialize it.
+ (free_propagate_block_info): Finish compuation of
+ REG_LIVE_LENGTH
+ (attempt_auto_inc): Sanity check that REG_INFO is not
+ computed at same time.
+ (mark_used_regs): Update new array.
+
+ * reg-stack.c (subst_stack_regs): Unshare clobbers before
+ substitution.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/s390/s390.md (*extendsiqi2_short_displ): Change to
+ *extendqisi2_short_displ.
+
+2004-02-06 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/tm.texi (INIT_CUMULATIVE_ARGS): Update doco.
+ * calls.c (expand_call): Pass n_named_args to INIT_CUMULATIVE_ARGS.
+ (emit_library_call_value_1): Likewise pass nargs.
+ * expr.c (block_move_libcall_safe_for_call_parm): Pass 3 here.
+ * function.c (assign_parms): Pass -1 to INIT_CUMULATIVE_ARGS.
+ * config/rs6000/rs6000.c (init_cumulative_args): Use n_named_args
+ parameter instead of scanning TYPE_ARGS_TYPES to count args.
+ * config/rs6000/rs6000-protos.h (init_cumulative_args): Update
+ prototype.
+ * config/rs6000/rs6000.h (INIT_CUMULATIVE_ARGS): Pass extra arg.
+ (INIT_CUMULATIVE_INCOMING_ARGS): Set extra arg to 1000.
+ (INIT_CUMULATIVE_LIBCALL_ARGS): Set extra arg to 0.
+ * config/sh/sh.c (sh_output_mi_thunk): Pass 1 as n_named_args to
+ INIT_CUMULATIVE_ARGS.
+ * config/alpha/alpha.h (INIT_CUMULATIVE_ARGS): Update.
+ * config/alpha/unicosmk.h, config/alpha/vms.h, config/arc/arc.h,
+ config/arm/arm.h, config/avr/avr.h, config/c4x/c4x.h,
+ config/cris/cris.h, config/fr30/fr30.h, config/frv/frv.h,
+ config/h8300/h8300.h, config/i386/i386.h, config/i860/i860.h,
+ config/ia64/ia64.h, config/ip2k/ip2k.h, config/iq2000/iq2000.h,
+ config/iq2000/iq2000.c, config/m32r/m32r.h, config/m68hc11/m68hc11.h,
+ config/m68k/m68k.h, config/mcore/mcore.h, config/mips/mips.h,
+ config/mmix/mmix.h, config/mn10300/mn10300.h, config/ns32k/ns32k.h,
+ config/pa/pa.h, config/pdp11/pdp11.h, config/s390/s390.h,
+ config/sh/sh.h, config/sparc/sparc.h, config/stormy16/stormy16.h,
+ config/v850/v850.h, config/vax/vax.h, config/xtensa/xtensa.h: Likewise.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genemit.c (gen_exp) [CONST_INT]: Use const_int_rtx whenever
+ possible.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (eliminate_regs_in_insn): If a set has a REG_EQUAL
+ note containing (plus (reg) (const_int)), where reg is an
+ eliminable reg, then perform the register elimination without
+ depending on eliminate_regs().
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arc/arc.c (arc_return_in_memory): Check the return
+ value of int_size_in_bytes against -1. Don't check
+ TREE_ADDRESSABLE.
+ * config/avr/avr.c (avr_return_in_memory): Check the return
+ value of int_size_in_bytes against -1.
+ * config/ip2k/ip2k.c (ip2k_return_in_memory): Likewise.
+ * config/m68hc11/m68hc11.c (m68hc11_return_in_memory):
+ Likewise.
+ * config/mcore/mcore.c (mcore_return_in_memory): Likewise.
+ * config/stormy16/stormy16.c (xstormy16_return_in_memory):
+ Likewise.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/frv/frv-protos.h: Remove the prototype for
+ frv_setup_incoming_varargs.
+ * config/frv/frv.c (TARGET_SETUP_INCOMING_VARARGS): New.
+ (frv_setup_incoming_varargs): Make it static.
+ * config/frv/frv.h (SETUP_INCOMING_VARARGS): Remove.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/fr30/fr30-protos.h: Remove the prototype for
+ fr30_setup_incoming_varargs.
+ Update the prototypes for fr30_num_arg_regs and
+ fr30_function_arg_partial_nregs.
+ * config/fr30/fr30.c (TARGET_STRUCT_VALUE_RTX): New.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (fr30_setup_incoming_varargs): Make it static.
+ Add argument second_time. Don't do anything when second_time
+ is nonzero.
+ (fr30_num_arg_regs): Change the type of the first argument to
+ enum machine_mode.
+ (fr30_function_arg_partial_nregs): Change the type of the
+ second argument to enum machine_mode.
+ * config/fr30/fr30.h (STRUCT_VALUE): Remove.
+ (SETUP_INCOMING_VARARGS): Remove.
+
+2004-02-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arc/arc-protos.h: Remove the prototype for
+ arc_setup_incoming_varargs.
+ * config/arc/arc.c (TARGET_ASM_EXTERNAL_LIBCALL): New.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (arc_setup_incoming_varargs): Make it static.
+ (arc_external_libcall): Likewise.
+ * config/arc/arc.h (SETUP_INCOMING_VARARGS): Remove.
+ Remove the commented-out definition of
+ ASM_OUTPUT_EXTERNAL_LIBCALL.
+
+2004-02-05 SUGIOKA Toshinobu <sugioka@itonet.co.jp>
+
+ * config/sh/t-linux (SHLIB_INSTALL): Prepend $$(DESTDIR)
+ to $$(slibdir) in the installation commands.
+
+2004-02-05 David Edelsohn <edelsohn@gnu.org>
+
+ * reload.c (refers_to_regno_for_reload_p): Index hard_regno_nregs
+ with inner_regno, not regno.
+ * rtlanal.c (refers_to_regno_p): Same.
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config.gcc: Remove i370 support.
+
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/install.texi: Update automake and autoconf version
+ requirements. Note where to find gcj automake version.
+
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (generate-manpages): Move dependencies to ...
+ (man): here.
+ * doc/makefile.texi: Document new targets.
+ * doc/sourcebuild.texi (Make-lang.in): Document new langhooks.
+
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
+
+ PR/13485
+ Makefile.in (srcextra): Add a level of indirection to ...
+ (gcc.srcextra): ... here.
+ (po-generated): Delete.
+ (po/$(PACKAGE).pot: Use srcextra instead of po-generated. Depend on
+ options.c.
+ (start.encap): Remove superfluous lang.srcextra dependency.
+ objc/Make-lang.in (po-generated): Delete.
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ia64/ia64.c (REG_GP): Remove.
+
+2004-02-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5gas.h (PREFERRED_DEBUGGING_TYPE): Define.
+
+2004-02-05 Devang Patel <dpatel@apple.com>
+
+ * dwarf2out.c (force_type_die): Look up input type itself
+ instead of root_type() of type.
+
+2004-02-05 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*tmqidi_ext"): New insn.
+ ("*extendqidi2_short_displ", "*extendsiqi2_short_displ"): Old
+ pre-reload splitters are transformed to post-reload
+ define_insn_and_split patterns.
+ ("*tmqisi_ext"): Renamed old "*tmqi_ext".
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/cris/cris.h: Replace PROMOTE_PROTOTYPES with
+ TARGET_PROMOTE_PROTOTYPES.
+
+2004-02-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ PR middle-end/13750
+ Revert:
+ 2004-01-15 Geoffrey Keating <geoffk@apple.com>
+ PR pch/13361
+ * c-typeck.c (constructor_asmspec): Delete.
+ (struct initializer_stack): Delete field 'asmspec'.
+ (start_init): Delete saving of asmspec.
+ (finish_init): Don't update constructor_asmspec.
+ * dwarf2out.c (rtl_for_decl_location): Duplicate string from tree.
+ * stmt.c (expand_asm): Duplicate strings from tree.
+ (expand_asm_operands): Likewise.
+ * tree.c (tree_size): Update computation of size of STRING_CST.
+ (make_node): Don't make STRING_CST nodes.
+ (build_string): Allocate string with tree node.
+ * tree.def (STRING_CST): Update comment.
+ * tree.h (TREE_STRING_POINTER): Adjust for change to STRING_CST.
+ (tree_string): Place contents of string in tree node.
+ * config/sh/sh.c (sh_handle_sp_switch_attribute): Duplicate string
+ from tree.
+
+2004-02-05 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * diagnostic.h (DEFINE_DIAGNOSTIC_KIND): Change parameter M to
+ msgid.
+
+2004-02-05 Dorit Naishlos <dorit@il.ibm.com>
+
+ * config/rs6000/altivec.md (*movv4si_internal): At least one
+ operand must be altivec_register_operand.
+ (*movv8hi_internal1): Likewise.
+ (*movv16qi_internal1): Likewise.
+ (*movv4sf_internal1): Likewise.
+
+2004-02-05 David Edelsohn <edelsohn@gnu.org>
+
+ * configure.ac (gcc_cv_as_powerpc_mfcrf): Correct test for mfcr.
+ * configure: Regenerate.
+
+2004-02-05 Jonathan Wakely <redi@gcc.gnu.org>
+
+ * doc/install.texi: Update description of --gxx-include-dir to
+ give correct default value.
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (REG_OK_FOR_BASE_NONSTRICT_P): Replace
+ 8 with MAC_REG.
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/pa/pa.c (emit_hpdiv_const): Replace gen_rtx with
+ gen_rtx_PARALLEL.
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * emit-rtl.c: Update the comment about the file.
+
+2004-02-05 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * sourcebuild.texi (Test Idioms): Update testcase naming
+ conventions.
+
+2004-02-04 Per Bothner <per@bothner.com>
+
+ Partially revert/redo 2003-10-01 change; fix -fworking-directory.
+ * c-ppoutput.c (pp_dir_change): New function.
+ * c-common.h (pp_dir_change): New declaration.
+ * cpplib.h (struct cpp_options): Remove working_directory field.
+ * cppinit.c (cpp_find_main_file, cpp_push_main_file): Merge back to
+ (cpp_read_main_file): as before 10-01. Call _cpp_stack_file.
+ Don't handle -fworking_directory here, but in c_common_post_options.
+ (read_original_directory): Don't back up when done.
+ Don't clear no-longer used working_directory flag.
+ * cpplib.h: Update declarations to match.
+ * c-lex.c (cb_dir_change): Move to c-opts.c.
+ (init_c_lex): Don't set dir_change callback here, since we want
+ to set it even if flag_preprocess_only.
+ * c-opts.c (cb_dir_change): Function moved from c-lex.c.
+ (c_common_post_options): Set dir_change callback.
+ Call pp_dir_change if approporiate.
+ (finish_options): Don't call cpp_find_main_file here. Hence remove
+ unneeded parameter and result. Do LC_RENAME for <built-in>.
+ (c_common_post_options): Call cpp_read_main_file here instead.
+ (c_common_init): Update accordingly.
+ (push_command_line_include): Don't cpp_push_main_file.
+ Do LC_RENAME rather than LC_LEASE to get back to main file.
+ Compared to pre-10-01 version, inline cpp_rename_to_main_file.
+ (c_common_parse_file): Call cpp_read_main_file for subsequent main
+ files, but call finish_options for all files.
+ * c-opts.c (sanitize_cpp_opts): Don't set cpp_opts->working_directory.
+ * fix-header.c (read_scan_file): Call cpp_read_main_file instead of
+ cpp_find_main_file + cpp_push_main_file.
+ * c-lex.c (fe_file_change): Don't set main_input_filename here.
+ * opts.c (handle_options): Only set main_input_filename first time.
+
+2004-02-05 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/arm.h (REG_CLASS_NAMES): Add missing comma.
+
+2004-02-04 Geoffrey Keating <geoffk@apple.com>
+
+ * reload.c (find_equiv_reg): When checking for register overlap,
+ don't index hard_regno_nregs with a pseudo-reg.
+
+2004-02-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_trampoline_template): Remove gen_rtx().
+
+2004-02-04 David Edelsohn <edelsohn@gnu.org>
+
+ * reload.c (refers_to_regno_for_reload_p): Test regno, not inner_regno,
+ against FIRST_PSEUDO_REGISTER.
+
+2004-02-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Makefile.in: Move target, host overrides after per-language
+ fragments.
+
+ * config/mips/t-iris5-as (FORCE_DEBUG_ADAFLAGS): Clear.
+ (GNATLIBCFLAGS): Remove -g.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c, config/arc/arc.c, config/avr/avr.c,
+ config/i386/i386.c, config/i386/i386.h, config/i386/i386.md,
+ config/ia64/ia64.c, config/ia64/unwind-ia64.c,
+ config/m32r/m32r.c, config/ns32k/ns32k.c, config/pa/pa.c,
+ config/pdp11/pdp11.c, config/rs6000/rs6000.c,
+ config/sparc/sparc.c, config/vax/vax.c: Revert the
+ replacements of "FALLTHRU" with "Fall through" done in the
+ previous patch.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/darwin.c, config/darwin.h, config/freebsd-spec.h,
+ config/arm/arm.c, config/arm/arm.md,
+ config/cris/cris-protos.h, config/fr30/fr30.c,
+ config/fr30/fr30.h, config/h8300/h8300.c, config/i386/i386.h,
+ config/i860/i860.c, config/i860/i860.h, config/ia64/ia64-c.c,
+ config/ia64/ia64.c, config/ia64/ia64.h, config/ip2k/ip2k.h,
+ config/ip2k/ip2k.md, config/ip2k/libgcc.S,
+ config/m32r/linux.h, config/m32r/m32r.c, config/m32r/m32r.h,
+ config/m68k/m68k.c, config/m68k/netbsd-elf.h,
+ config/mips/mips.c, config/mmix/mmix.c, config/mmix/mmix.md,
+ config/ns32k/netbsd.h, config/ns32k/ns32k.c,
+ config/ns32k/ns32k.h, config/pdp11/pdp11.h,
+ config/rs6000/darwin-ldouble.c, config/s390/s390.h,
+ config/s390/s390.md, config/sparc/netbsd-elf.h,
+ config/sparc/openbsd.h, config/sparc/sparc.c,
+ config/xtensa/lib2funcs.S: Fix comment formatting.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c, config/arc/arc.c,
+ config/arm/arm-cores.def, config/arm/arm.c, config/arm/arm.h,
+ config/arm/arm1026ejs.md, config/arm/arm1136jfs.md,
+ config/arm/arm926ejs.md, config/arm/vfp.md, config/avr/avr.c,
+ config/c4x/c4x.c, config/cris/cris.c, config/frv/frv.md,
+ config/i386/i386.c, config/i386/i386.h, config/i386/i386.md,
+ config/ia64/ia64.c, config/ia64/unwind-ia64.c,
+ config/iq2000/iq2000.c, config/m32r/m32r.c,
+ config/mips/mips.c, config/mmix/mmix.c, config/mmix/mmix.h,
+ config/ns32k/ns32k.c, config/pa/pa.c, config/pdp11/pdp11.c,
+ config/rs6000/darwin-ldouble.c, config/rs6000/rs6000.c,
+ config/rs6000/rs6000.h, config/sparc/sparc.c,
+ config/vax/vax.c: Fix comment typos. Follow spelling
+ conventions.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alloc-pool.h, c-convert.c, c-lang.c, c-tree.h,
+ caller-save.c, df.h, genconfig.c, global.c, lcm.c,
+ ra-rewrite.c, ra.c, regclass.c, regs.h, resource.c,
+ sched-rgn.c, config/arm/aof.h, config/arm/cirrus.md,
+ config/arm/fpa.md, config/arm/iwmmxt.md,
+ config/arm/netbsd-elf.h, config/arm/netbsd.h,
+ config/m68hc11/m68hc11.md, config/mips/iris5.h,
+ config/mn10300/mn10300.md, config/rs6000/altivec.md,
+ config/sparc/netbsd-elf.h: Update copyright.
+
+2004-02-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
+ for all modes whose size is greater than 8 bytes if ARCH32.
+ (sparc_va_arg): Handle all modes whose size is greater than 8 bytes
+ by reference if ARCH32.
+
+2004-02-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * cgraphunit.c (cgraph_postorder): Fix typo in comment.
+
+2004-02-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*la_64" + peepholes, "reload_indi"): Move
+ to before adddi3 insn patterns.
+ ("*la_31" + peepholes, "*la_31_and", "*la_31_and_cc", "force_la_31",
+ "reload_insi"): Move to before addsi3 insn patterns.
+
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ * calls.c (initialize_argument_information): Add CALL_FROM_THUNK_P
+ parameter. Use it instead of current_function_is_thunk.
+ * function.h (struct function): Update documentation for is_thunk.
+ * tree.h (CALL_FROM_THUNK_P): New macro.
+ * config/alpha/alpha.c (alpha_sa_mask): Do not check
+ no_new_pseudos when testing current_function_is_thunk.
+ * config/rs6000/rs6000.c (rs6000_ra_ever_killed): Likeiwse.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi: Replace SETUP_INCOMING_VARARGS with
+ TARGET_SETUP_INCOMING_VARARGS.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * emit-rtl.c (gen_rtx): Remove.
+ * genattrtab.c: Don't mention gen_rtx in a comment.
+ * rtl.h: Remove the prototype for gen_rtx.
+ * doc/md.texi: Replace gen_rtx with gen_rtx_REG.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arc/arc.h, config/fr30/fr30.h
+ (SETUP_INCOMING_VARARGS): Remove the target-independent
+ comments.
+ * doc/tm.texi: Don't mention deprecated target macros.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/fr30/fr30.h (FUNCTION_VALUE): Remove the
+ target-independent comment.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/interface.texi, doc/tm.texi, doc/trouble.texi: Don't
+ mention deprecated target macros.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config.gcc: Remove obsolete ports and configurations.
+ * config/linux-aout.h, config/netware.h,
+ config/t-linux-gnulibc1, config/d30v/abi,
+ config/d30v/d30v-protos.h, config/d30v/d30v.c,
+ config/d30v/d30v.h, config/d30v/d30v.md,
+ config/d30v/libgcc1.asm, config/d30v/t-d30v,
+ config/dsp16xx/dsp16xx-modes.def,
+ config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
+ config/dsp16xx/dsp16xx.h, config/dsp16xx/dsp16xx.md,
+ config/i370/README, config/i370/i370-c.c,
+ config/i370/i370-protos.h, config/i370/i370.c,
+ config/i370/i370.h, config/i370/i370.md, config/i370/linux.h,
+ config/i370/mvs.h, config/i370/oe.h, config/i370/t-i370,
+ config/i386/freebsd-aout.h, config/i386/linux-aout.h,
+ config/i386/moss.h, config/i386/netware.h,
+ config/i386/svr3.ifile, config/i386/svr3dbx.h,
+ config/i386/svr3gas.h, config/i386/svr3z.ifile,
+ config/i386/t-udk, config/i386/udk.h, config/i386/vsta.h,
+ config/i960/i960-c.c, config/i960/i960-coff.h,
+ config/i960/i960-modes.def, config/i960/i960-protos.h,
+ config/i960/i960.c, config/i960/i960.h, config/i960/i960.md,
+ config/i960/rtems.h, config/i960/t-960bare,
+ config/m68k/hp310.h, config/m68k/hp320.h,
+ config/m68k/hp320base.h, config/m68k/m68kv4.h,
+ config/m68k/netbsd.h, config/m68k/sgs.h, config/m68k/t-hp320:
+ Remove.
+ * doc/extend.texi, doc/install.texi, doc/invoke.texi,
+ doc/md.texi: Remove mentions of obsolete ports.
+
+2004-02-04 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-03 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/invoke.texi (x86 options): Fix spelling/wording.
+
+2004-02-03 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/iris5.h (ASM_OUTPUT_ASCII): Use mips_output_ascii to
+ put the original string in a comment.
+ * config/mips/mips-protos.h (mips_output_ascii): Add prefix argument.
+ * config/mips/mips.c (mips_output_ascii): Likewise.
+ * config/mips/mips.h (ASM_OUTPUT_ASCII): Adjust accordingly.
+
+2004-02-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (GIV_SORT_CRITERION): Poison.
+ * config/avr/avr.h (GIV_SORT_CRITERION): Remove.
+ * config/ip2k/ip2k.h (GIV_SORT_CRITERION): Likewise.
+
+2004-02-03 Roger Sayle <roger@eyesopen.com>
+
+ PR target/9348
+ * expr.c (expand_expr_real) <MULT_EXPR>: When performing widening
+ multiplies with a multiplication of the wrong signedness, its the
+ signedness of the multiplication that we've performed that needs to
+ be passed to expand_mult_highpart_adjust. Avoid emitting a nop-move
+ if expand_mult_highpart_adjust places the result in target.
+
+2004-02-03 Richard Henderson <rth@redhat.com>
+
+ * varasm.c (const_desc_rtx_sym_eq): Compare symbol strings.
+
+2004-02-03 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config.gcc (sh[234]l): Use little endian fragments.
+
+2004-02-03 Paul Koning <pkoning@equallogic.com>
+
+ * config/pdp11/pdp11-modes.def: Add RESET_FLOAT_FORMAT calls.
+ * config/pdp11/pdp11-protos.h (legitimate_const_double_p): Add.
+ * config/pdp11/pdp11.c (encode_pdp11_f, decode_pdp11_f,
+ encode_pdp11_d, decode_pdp11_d): New functions to handle PDP11
+ floating point format.
+ (pdp11_f_format, pdp11_d_format): New real_format descriptors for
+ the above functions.
+ (output_move_quad): Output float values in correct target format.
+ (legitimate_const_double_p): New function.
+ * config/pdp11/pdp11.h: Fix typos.
+ (FLOAT_WORDS_BIG_ENDIAN): Add definition.
+ (TARGET_FLOAT_FORMAT): Ditto.
+ (pdp11_f_format, pdp11_d_format): Add external declarations.
+ (MAX_REGS_PER_ADDRESS): Corrected.
+ (LEGITIMATE_CONSTANT_P): Use legitimate_const_double_p().
+ (PRINT_OPERAND): Output float literals in target format.
+
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13975
+ * tree.h (enum tree_index): Add TI_PUBLIC, TI_PROTECTED, and
+ TI_PRIVATE.
+ (access_public_node): Redefine.
+ (access_protected_node): Likewise.
+ (access_private_node): Likewise.
+ * tree.c (build_common_tree_nodes): Create access_public_node,
+ access_protected_node, and access_private_node.
+
+2004-02-03 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.h (MASK_INLINE_INT_DIV_LAT): Change value.
+ (MASK_INLINE_INT_DIV_THR): Ditto.
+ (MASK_INLINE_SQRT_LAT): Ditto.
+ (MASK_INLINE_SQRT_THR): Ditto.
+ (MASK_DWARF2_ASM): Ditto.
+ (MASK_EARLY_STOP_BITS): Ditto.
+
+2004-02-02 Paul Brook <paul@codesourcery.com>
+
+ Merge from csl-arm-branch.
+
+ 2004-01-30 Paul Brook <paul@codesourcery.com>
+
+ * aof.h (REGISTER_NAMES): Add vfp reg names
+ (ADDITIONAL_REGISTER_NAMES): Ditto.
+ * aout.h (REGISTER_NAMES): Ditto.
+ (ADDITIONAL_REGISTER_NAMES): Ditto.
+ * arm-protos.h: Update/Add Prototypes.
+ * arm.c (init_fp_table): Rename from init_fpa_table. Update users.
+ Only allow 0.0 for VFP.
+ (fp_consts_inited): Rename from fpa_consts_inited. Update users.
+ (values_fp): Rename from values_fpa. Update Users.
+ (arm_const_double_rtx): Rename from const_double_rtx_ok_for_fpa.
+ Update users. Only check valid constants for this hardware.
+ (arm_float_rhs_operand): Rename from fpa_rhs_operand. Update Users.
+ Only allow consts for FPA.
+ (arm_float_add_operand): Rename from fpa_add_operand. Update users.
+ Only allow consts for FPA.
+ (use_return_insn): Check for saved VFP regs.
+ (arm_legitimate_address_p): Handle VFP DFmode addressing.
+ (arm_legitimize_address): Ditto.
+ (arm_general_register_operand): New function.
+ (vfp_mem_operand): New function.
+ (vfp_compare_operand): New function.
+ (vfp_secondary_reload_class): New function.
+ (arm_float_compare_operand): New function.
+ (vfp_print_multi): New function.
+ (vfp_output_fstmx): New function.
+ (vfp_emit_fstm): New function.
+ (arm_output_epilogue): Output VPF reg restore code.
+ (arm_expand_prologue): Output VFP reg save code.
+ (arm_print_operand): Add 'P'.
+ (arm_hard_regno_mode_ok): Return modes for VFP regs.
+ (arm_regno_class): Return classes for VFP regs.
+ (arm_compute_initial_elimination_offset): Include space for VFP regs.
+ (arm_get_frame_size): Ditto.
+ * arm.h (FIXED_REGISTERS): Add VFP regs.
+ (CALL_USED_REGISTERS): Ditto.
+ (CONDITIONAL_REGISTER_USAGE): Enable VFP regs.
+ (FIRST_VFP_REGNUM): Define.
+ (LAST_VFP_REGNUM): Define.
+ (IS_VFP_REGNUM): Define.
+ (FIRST_PSEUDO_REGISTER): Include VFP regs.
+ (HARD_REGNO_NREGS): Handle VFP regs.
+ (REG_ALLOC_ORDER): Add VFP regs.
+ (enum reg_class): Add VFP_REGS.
+ (REG_CLASS_NAMES): Ditto.
+ (REG_CLASS_CONTENTS): Ditto.
+ (CANNOT_CHANGE_MODE_CLASS) Handle VFP Regs.
+ (REG_CLASS_FROM_LETTER): Add 'w'.
+ (EXTRA_CONSTRAINT_ARM): Add 'U'.
+ (EXTRA_MEMORY_CONSTRAINT): Define.
+ (SECONDARY_OUTPUT_RELOAD_CLASS): Handle VFP regs.
+ (SECONDARY_INPUT_RELOAD_CLASS): Ditto.
+ (REGISTER_MOVE_COST): Ditto.
+ (PREDICATE_CODES): Add arm_general_register_operand,
+ arm_float_compare_operand and vfp_compare_operand.
+ * arm.md (various): Rename as above.
+ (divsf3): Enable when TARGET_VFP.
+ (divdf3): Ditto.
+ (movdfcc): Ditto.
+ (sqrtsf2): Ditto.
+ (sqrtdf2): Ditto.
+ (arm_movdi): Disable when TARGET_VFP.
+ (arm_movsi_insn): Ditto.
+ (movsi): Only split with general regs.
+ (cmpsf): Use arm_float_compare_operand.
+ (push_fp_multi): Restrict to TARGET_FPA.
+ (vfp.md): Include.
+ * vfp.md: New file.
+ * fpa.md (various): Rename as above.
+ * doc/md.texi: Document ARM w and U constraints.
+
+ 2004-01-15 Paul Brook <paul@codesourcery.com>
+
+ * config.gcc: Add with_fpu. Allow with-float=softfp.
+ * config/arm/arm.c (arm_override_options): Rename *-s to *s.
+ Break out of loop when we find a float-abi. Fix typo.
+ * config/arm/arm.h (OPTION_DEFAULT_SPECS): Add "fpu".
+ Set -mfloat-abi=.
+ * doc/install.texi: Document --with-fpu.
+
+ 2003-01-14 Paul Brook <paul@codesourcery.com>
+
+ * config.gcc (with_arch): Add armv6.
+ * config/arm/arm.h: Rename TARGET_CPU_*_s to TARGET_CPU_*s.
+ * config/arm/arm.c (arm_overrride_options): Ditto.
+
+ 2004-01-08 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (FL_ARCH3M): Renamed from FL_FAST_MULT.
+ (FL_ARCH6): Renamed from FL_ARCH6J.
+ (arm_arch3m): Renamed from arm_fast_multiply.
+ (arm_arch6): Renamed from arm_arch6j.
+ * arm.h: Update all uses of above.
+ * arm-cores.def: Likewise.
+ * arm.md: Likewise.
+
+ * arm.h (CPP_CPU_ARCH_SPEC): Emit __ARM_ARCH_6J__ define for armV6j,
+ not arm6j. Add entry for arch armv6.
+
+ 2004-01-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_emit_extendsi): Delete.
+ * arm-protos.h (arm_emit_extendsi): Delete.
+ * arm.md (zero_extendhisi2): Also handle zero-extension of
+ non-subregs.
+ (zero_extendqisi2, extendhisi2, extendqisi2): Likewise.
+ (thumb_zero_extendhisi2): Only match if not v6.
+ (arm_zero_extendhisi2, thumb_zero_extendqisi2, arm_zero_extendqisi2)
+ (thumb_extendhisi2, arm_extendhisi2, arm_extendqisi)
+ (thumb_extendqisi2): Likewise.
+ (thumb_zero_extendhisi2_v6, arm_zero_extendhisi2_v6): New patterns.
+ (thumb_zero_extendqisi2_v6, arm_zero_extendqisi2_v6): New patterns.
+ (thumb_extendhisi2_insn_v6, arm_extendhisi2_v6): New patterns.
+ (thumb_extendqisi2_v6, arm_extendqisi_v6): New patterns.
+ (arm_zero_extendhisi2_reg, arm_zero_extendqisi2_reg): Delete.
+ (arm_extendhisi2_reg, arm_extendqisi2_reg): Delete.
+ (arm_zero_extendhisi2addsi): Remove subreg. Add attributes.
+ (arm_zero_extendqisi2addsi, arm_extendhisi2addsi): Likewise.
+ (arm_extendqisi2addsi): Likewise.
+
+ 2003-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ Revert this change:
+ * config/arm/arm.h (THUMB_LEGTITIMIZE_RELOAD_ADDRESS): Reload REG
+ + REG addressing modes.
+
+ * config/arm/arm.h (THUMB_LEGTITIMIZE_RELOAD_ADDRESS): Reload REG
+ + REG addressing modes.
+
+ 2003-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * config/arm/arm.h (THUMB_LEGITIMATE_CONSTANT_P): Accept
+ CONSTANT_P_RTX.
+
+ 2003-30-12 Paul Brook <paul@codesourcery.com>
+
+ * longlong.h: protect arm inlines with !defined (__thumb__)
+
+ 2003-30-12 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Always define __arm__.
+
+ 2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (expand_builtin_apply_args_1): Fix typo in previous
+ change.
+
+ 2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (expand_builtin_apply_args_1): Add pretend args size
+ to the virtual incoming args pointer for downward stacks.
+
+ 2003-12-29 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm-cores.def: Add cost function.
+ * config/arm/arm.c (arm_*_rtx_costs): New functions.
+ (arm_rtx_costs): Remove
+ (struct processors): Add rtx_costs field.
+ (all_cores, all_architectures): Ditto.
+ (arm_override_options): Set targetm.rtx_costs.
+ (thumb_rtx_costs): New function.
+ (arm_rtx_costs_1): Remove cases handled elsewhere.
+ * config/arm/arm.h (processor_type): Add COSTS parameter.
+
+ 2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/arm/arm.md (generic_sched): arm926 has its own scheduler.
+ (arm926ejs.md): Include it.
+ * config/arm/arm926ejs.md: New pipeline description.
+
+ 2003-12-24 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_arch6j): New variable.
+ (arm_override_options): Set it.
+ (arm_emit_extendsi): New function.
+ * config/arm/arm-protos.h (arm_emit_extendsi): Add prototype.
+ * config/arm/arm.h (arm_arch6j): Declare.
+ * config/arm/arm.md: Add sign/zero extend insns.
+
+ 2003-12-23 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (all_architectures): Add armv6.
+ * doc/invoke.texi: Document it.
+
+ 2003-12-19 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.md: Add load1 and load_byte "type" attrs. Modify
+ insn patterns to match.
+ * config/arm/arm-generic.md: Ditto.
+ * config/arm/cirrus.md: Ditto.
+ * config/arm/fpa.md: Ditto.
+ * config/amm/iwmmxt.md: Ditto.
+ * config/arm/arm1026ejs.md: Ditto.
+ * config/arm/arm1135jfs.md: Ditto. Add insn_reservation and bypasses
+ for 11_loadb.
+
+ 2003-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/arm/arm-protos.h (arm_no_early_alu_shift_value_dep): Declare.
+ * config/arm/arm.c (arm_adjust_cost): Check shift cost for
+ TYPE_ALU_SHIFT and TYPE_ALU_SHIFT_REG.
+ (arm_no_early_store_addr_dep, arm_no_early_alu_shift_dep,
+ arm_no_early_mul_dep): Correctly deal with conditional execution,
+ parallels and single shift operations.
+ (arm_no_early_alu_shift_value_dep): Define.
+ * arm.md (attr type): Replace 'normal' with 'alu',
+ 'alu_shift' and 'alu_shift_reg'.
+ (attr core_cycles): Adjust.
+ (*addsi3_carryin_shift, andsi_not_shiftsi_si, *arm_shiftsi3,
+ *shiftsi3_compare0, *notsi_shiftsi, *notsi_shiftsi_compare0,
+ *not_shiftsi_compare0_scratch, *cmpsi_shiftsi, *cmpsi_shiftsi_swp,
+ *cmpsi_neg_shiftsi, *arith_shiftsi, *arith_shiftsi_compare0,
+ *arith_shiftsi_compare0_scratch, *sub_shiftsi,
+ *sub_shiftsi_compare0, *sub_shiftsi_compare0_scratch,
+ *if_shift_move, *if_move_shift, *if_shift_shift): Set type
+ attribute appropriately.
+ * config/arm/arm1026ejs.md (alu_op): Adjust.
+ (alu_shift_op, alu_shift_reg_op): New.
+ * config/arm/arm1136.md: Add better bypasses for early
+ registers. Remove load[234] and store[234] bypasses.
+ (11_alu_op): Adjust.
+ (11_alu_shift_op, 11_alu_shift_reg_op): New.
+
+ 2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/arm/arm-protos.h (arm_no_early_store_addr_dep,
+ arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Declare.
+ * config/arm/arm.c (arm_no_early_store_addr_dep,
+ arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Define.
+ * config/arm/arm1026ejs.md: Add load-store bypass.
+ * config/arm/arm1136jfs.md (11_alu_op): Take 2 cycles.
+ Add bypasses between instructions.
+
+ 2003-12-10 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_fpu_model): New variable.
+ (arm_fload_abi): New variable.
+ (target_fpe_name): Rename from target_fp_name.
+ (target_fpu_name): New variable.
+ (arm_is_cirrus): Remove.
+ (fpu_desc): New struct.
+ (all_fpus): Define.
+ (pf_model_for_fpu): Define.
+ (all_loat_abis): Define.
+ (arm_override_options): Set fp arch flags based on -mfpu=
+ and -float-abi=.
+ (FIRST_FPA_REGNUM): Rename from FIRST_ARM_FP_REGNUM.
+ (LAST_FPA_REGNUM): Rename from LAST_ARM_FP_REGNUM.
+ (*): Use new TARGET_* flags.
+ * config/arm/arm.h (TARGET_ANY_HARD_FLOAT): Remove.
+ (TARGET_HARD_FLOAT): No longer implies TARGET_FPA.
+ (TARGET_SOFT_FLOAT): Ditto.
+ (TARGET_SOFT_FLOAT_ABI): New.
+ (TARGET_MAVERICK): Rename from TARGET_CIRRUS. No longer implies
+ TARGET_HARD_FLOAT.
+ (TARGET_VFP): No longer implies TARGET_HARD_FLOAT.
+ (TARGET_OPTIONS): Add -mfpu=.
+ (FIRST_FPA_REGNUM): Rename from FIRST_ARM_FP_REGNUM.
+ (LAST_FPA_REGNUM): Rename from LAST_ARM_FP_REGNUM.
+ (arm_pf_model): Define.
+ (arm_float_abi_type): Define.
+ (fputype): Add FPUTYPE_VFP. Change SOFT_FPA->NONE
+ * config/arm/arm.md: Use new TARGET_* flags.
+ * config/arm/cirrus.md: Ditto.
+ * config/arm/fpa.md: Ditto.
+ * config/arm/elf.h (ASM_SPEC): Pass -mfloat-abi= and -mfpu=.
+ * config/arm/semi.h (ASM_SPEC): Ditto.
+ * config/arm/netbsd-elf.h (SUBTARGET_ASM_FLOAT_SPEC): Specify vfp.
+ (FPUTYPE_DEFAULT): Set to VFP.
+ * doc/invoke.texi: Document -mfpu= and -mfloat-abi=.
+
+ 2003-11-22 Phil Edwards <phil@codesourcery.com>
+
+ PR target/12476
+ * config/arm/arm.c (arm_output_mi_thunk): In Thumb mode, use
+ 'bx' instead of 'b' to avoid branch range restrictions. Output
+ the thunk immediately before the thunked-to function.
+ * config/arm/arm.h (ARM_DECLARE_FUNCTION_NAME): Do not emit
+ .thumb_func if a thunk is being generated. Emit .code 16 along
+ with .thumb_func if a thunk is not being generated.
+
+ 2003-11-15 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/arm.md (ashldi3, arm_ashldi3_1bit, ashrdi3,
+ arm_ashrdi3_1bit, lshrdi3, arm_lshrdi3_1bit): New patterns.
+ * config/arm/iwmmxt.md (ashrdi3_iwmmxt): Renamed from ashrdi3.
+ (lshrdi3_iwmmxt): Renamed from lshrdi3.
+ * config/arm/arm.c (IWMMXT_BUILTIN2): Renamed argument accordingly.
+
+ 2003-11-12 Steve Woodford <scw@wasabisystems.com>
+ Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/lib1funcs.asm (ARM_DIV_BODY, ARM_MOD_BODY): Add new
+ code for __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__).
+
+ 2003-11-05 Phil Edwards <phil@codesourcery.com>
+
+ * config/arm/arm.md (insn): Add new V6 instruction names.
+ (generic_sched): New attr.
+ * config/arm/arm-generic.md: Use generic_sched here.
+ * config/arm/arm1026ejs.md: Do not model fetch/issue/decode
+ stages of pipeline. Adjust latency counts accordingly.
+ * config/arm/arm1136jfs.md: New file.
+
+ 2003-10-28 Mark Mitchell <mark@codesourcery.com>
+
+ * config/arm/arm.h (processor_type): New enumeration type.
+ (CPP_ARCH_DEFAULT_SPEC): Set appropriately for ARM 926EJ-S,
+ ARM1026EJ-S, ARM1136J-S, and ARM1136JF-S processor cores.
+ (CPP_CPU_ARCH_SPEC): Likewise.
+ * config/arm/arm.c (arm_tune): New variable.
+ (all_cores): Use cores.def.
+ (all_architectures): Add representative processor.
+ (arm_override_options): Restructure way in which tuning
+ information is deduced.
+ * arm.md: Update "insn" and "type" attributes throughout.
+ (insn): New attribute.
+ (type): Compute "mult" from "insn" attribute. Add load2,
+ load3, load4 alternatives.
+ (arm automaton): Move to arm-generic.md.
+ * config/arm/arm-cores.def: New file.
+ * config/arm/arm-generic.md: Likewise.
+ * config/arm/arm1026ejs.md: Likewise.
+
+2004-02-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/invoke.texi (SPARC options): Remove -mflat and
+ all -mxxx (xxx:chip) options.
+ * config/sparc/aout.h (DBX_REGISTER_NUMBER): Delete.
+ * config/sparc/litecoff.h (DBX_REGISTER_NUMBER): Likewise.
+ * config/sparc/netbsd-elf.h (DBX_REGISTER_NUMBER): Likewise.
+ * config/sparc/sol2.h (DBX_REGISTER_NUMBER): Likewise.
+ * config/sparc/sparc-protos.h: Delete sparc_flat_* prototypes.
+ * config/sparc/sparc.c: Likewise.
+ (sparc_output_function_prologue): Remove TARGET_FLAT handling.
+ (sparc_nonflat_function_prologue): Rename into sparc_function_prologue.
+ (sparc_output_function_epilogue): Remove TARGET_FLAT handling.
+ (sparc_nonflat_function_epilogue): Rename into sparc_function_epilogue.
+ (struct sparc_frame_info, current_frame_info, zero_frame_info): Delete.
+ (sparc_flat_must_save_register_p): Likewise.
+ (sparc_flat_compute_frame_size): Likewise.
+ (sparc_flat_save_restore): Likewise.
+ (sparc_flat_function_prologue): Likewise.
+ (sparc_flat_function_epilogue): Likewise.
+ (sparc_flat_epilogue_delay_slots): Likewise.
+ (sparc_flat_eligible_for_epilogue_delay): Likewise.
+ (sparc_function_ok_for_sibcall): Remove TARGET_FLAT handling.
+ * config/sparc/sparc.h (MASK_FLAT, TARGET_FLAT): Delete.
+ (TARGET_SWITCHES): Remove -mflat and all -mxxx (xxx:chip) options.
+ (SPARC_INCOMING_INT_ARG_FIRST): Remove TARGET_FLAT handling.
+ (CONDITIONAL_REGISTER_USAGE): Likewise.
+ (FRAME_POINTER_REQUIRED): Likewise.
+ (INITIAL_ELIMINATION_OFFSET): Likewise.
+ (BASE_RETURN_VALUE_REG): Likewise.
+ (BASE_OUTGOING_VALUE_REG): Likewise.
+ (BASE_PASSING_ARG_REG): Likewise.
+ (BASE_INCOMING_ARG_REG): Likewise.
+ (INCOMING_REGNO): Likewise.
+ (OUTGOING_REGNO): Likewise.
+ (LOCAL_REGNO): Likewise.
+ (DELAY_SLOTS_FOR_EPILOGUE): Likewise.
+ (ELIGIBLE_FOR_EPILOGUE_DELAY): Likewise.
+ (EPILOGUE_USES): Likewise.
+ * config/sparc/sparc.md ("isa" attribute): Change "v6" into "v7".
+ ("flat" attribute): Delete.
+ (do_builtin_setjmp_setup): Remove TARGET_FLAT and "flat" attribute
+ handling.
+ (call followed by jump define_peephole's): Delete.
+ (exception_receiver): Likewise.
+ (builtin_setjmp_receiver): Likewise.
+ * config/sparc/t-sparclite (MULTILIB_OPTIONS): Remove -mflat.
+
+2004-02-03 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c/11658
+ PR c/13994
+ * Makefile.in (c-parse.o, c-convert.o, c-typeck.o): Depend
+ on langhooks.h.
+ * objc/Make-lang.in (objc-parse.o): Depend on langhooks.h.
+ * c-parse.in, c-convert.c, c-typeck.c, objc/objc-act.c:
+ Include langhooks.h. Replace c_common_truthvalue_conversion
+ with the truthvalue_conversion language hook throughout.
+ (expr_no_commas): Call default_conversion before save_expr
+ for the first term of the production 'x ? : y'.
+ * c-common.c (c_common_truthvalue_conversion): Remove
+ obsolete block. Invoke recursively the hook instead
+ of this function.
+ * c-convert.c (convert): handle ERROR_MARK_NODE.
+ * c-typeck.c (build_binary_op): handle ERROR_MARK_NODE
+ returned by the truthvalue_conversion language hook.
+ * c-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Use
+ c_objc_common_truthvalue_conversion.
+ * c-objc-common.c (c_objc_common_truthvalue_conversion):
+ New function.
+ * c-tree.h (c_objc_common_truthvalue_conversion): Declare it.
+ * objc/objc-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Use
+ c_objc_common_truthvalue_conversion.
+
+2004-02-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/c4x/c4x.h (FUNCTION_VALUE): Use gen_rtx_REG instead
+ of gen_rtx.
+ (LIBCALL_VALUE): Likewise.
+ * config/ip2k/ip2k.c (mdr_try_propagate_clr_sequence): Use
+ gen_rtx_CC0 instead of gen_rtx.
+ * config/m68hc11/m68hc11.c (m68hc11_emit_libcall): Use
+ gen_rtx_fmt_e and gen_rtx_fmt_ee instead of gen_rtx.
+ (m68hc11_expand_compare): Use gen_rtx_fmt_ee instead of
+ gen_rtx.
+ (m68hc11_emit_logical): Likewise.
+
+2004-02-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c, config/arm/arm.c, config/c4x/c4x.c,
+ config/fr30/fr30.md, config/frv/frv.c, config/frv/frv.md,
+ config/h8300/h8300.c, config/ia64/ia64.c, config/ip2k/ip2k.md,
+ config/m32r/m32r.md, config/m68hc11/m68hc11.c,
+ config/mips/mips.md, config/mmix/mmix.c,
+ config/mn10300/mn10300.c, config/mn10300/mn10300.md,
+ config/ns32k/ns32k.c, config/pa/pa.md, config/pdp11/pdp11.c,
+ config/rs6000/altivec.md, config/s390/s390.c,
+ config/s390/s390.h, config/s390/s390.md, config/sh/sh.c,
+ config/sh/sh.h, config/sh/sh.md, config/stormy16/stormy16.c:
+ Use const0_rtx instead of GEN_INT (0). Do the same for other
+ constants that are readily available.
+
+2004-02-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doloop.c, optabs.c, regmove.c, sched-deps.c,
+ config/i386/i386.c, config/i386/i386.md: Use const0_rtx
+ instead of GEN_INT (0). Do the same for other constants that
+ are readily available.
+
+2004-02-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_set): Use gen_rtx_fmt_e instead of
+ gen_rtx.
+ * emit-rtl.c (init_emit_once): Use gen_rtx_PC and gen_rtx_CC0
+ instead of gen_rtx.
+ * reload1.c (init_elim_table): Use gen_rtx_fmt_e instead of
+ gen_rtx.
+ * config/ns32k/ns32k.md (udivmodhi4): Use gen_rtx_IOR and
+ gen_rtx_ASHIFT instead of gen_rtx.
+ (udivmodqi4): Likewise.
+
+2004-02-02 Richard Henderson <rth@redhat.com>
+
+ PR target/13789
+ * expr.c (store_expr): Use force_operand before emit_move_insn.
+
+2004-02-02 Jeff Law <law@redhat.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ * tree.c (commutative_tree_code, associative_tree_code): New
+ functions.
+ (iterative_hash_expr): Use commutative_tree_code.
+ * tree.h (commutative_tree_code, associative_tree_code): Declare.
+ * fold-const.c (operand_equal_p): Use commutative_tree_code
+ rather than inlining the commutativity check.
+ (fold): Likewise.
+
+2004-02-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (FUNCTION_ARG_KEEP_AS_REFERENCE): Poison.
+ * config/frv/frv-protos.h: Remove the prototype for
+ frv_function_arg_keep_as_reference.
+ * config/frv/frv.c (frv_function_arg_keep_as_reference):
+ Remove.
+ * config/frv/frv.h (FUNCTION_ARG_KEEP_AS_REFERENCE): Likewise.
+ * config/stormy16/stormy16.h: Remove the commented-out
+ definition of FUNCTION_ARG_KEEP_AS_REFERENCE.
+
+2004-02-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/13914
+ * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Use ap
+ for retaddr_column.
+
+2004-02-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genemit.c (gen_exp): Generate gen_rtx_fmt_e* instead of
+ gen_rtx.
+
+2004-02-02 Eric Christopher <echristo@redhat.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * c-opts.c (c_common_handle_option): Add -finput-charset.
+ * c.opt: Ditto.
+ * cppcharset.c (one_iso88591_to_utf8): Remove.
+ (convert_iso88591_utf8): Ditto.
+ (conversion_tab): Remove 8859-1 converter.
+ (_cpp_input_to_utf8): Remove.
+ (_cpp_init_iconv_buffer): Ditto.
+ (_cpp_close_iconv_buffer): Ditto.
+ (_cpp_convert_input): New function.
+ (_cpp_default_encoding): Ditto.
+ * cpphash.h: Add/remove prototypes for above.
+ * cppfiles.c (read_file_guts): Use _cpp_convert_input.
+ * cppinit.c (cpp_create_reader): Use _cpp_default_encoding
+ for narrow execution and input character sets.
+ * cpplib.c (cpp_push_buffer): Delete uses of removed functions.
+ * doc/cppopts.texi: Document -finput-charset.
+
+2004-02-02 David Edelsohn <edelsohn@gnu.org>
+
+ * rtlanal.c (refers_to_regno_p): Test regno, not inner_regno,
+ against FIRST_PSEUDO_REGISTER.
+
+2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/invoke.texi (SPARC options): Further improve.
+
+2004-02-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.md, config/c4x/c4x.md, config/cris/cris.md,
+ config/h8300/h8300.c, config/ip2k/ip2k.md,
+ config/iq2000/iq2000.c, config/mips/mips.c,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.md,
+ config/sh/sh.c, config/sh/sh.md, config/stormy16/stormy16.c,
+ config/v850/v850.md: Fix indentation.
+
+2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_slotno): Align TImode
+ arguments on a 16-byte boundary in the parameter array if ARCH64.
+ Split handling of TFmode.
+
+2004-02-02 Paolo Bonzini <bonzini@gnu.org>
+
+ * rtlanal.c (reg_overlap_mentioned_p) [!ENABLE_CHECKING]:
+ Don't test CONSTANT_P (x).
+ (reg_overlap_mentioned_p): Merge check for STRICT_LOWPART,
+ ZERO_EXTRACT, SIGN_EXTRACT with the switch statement.
+ Fix misindentation.
+
+2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/invoke.texi (SPARC options): Document that -mflat is deprecated.
+
+2004-02-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arc/arc.md, config/arm/arm.c, config/arm/arm.md,
+ config/c4x/c4x.c, config/c4x/c4x.md, config/cris/cris.md,
+ config/frv/frv.c, config/h8300/h8300.c, config/ip2k/ip2k.md,
+ config/iq2000/iq2000.c, config/m32r/m32r.c,
+ config/mcore/mcore.c, config/mips/mips.c, config/mmix/mmix.md,
+ config/mn10300/mn10300.c, config/rs6000/rs6000.c,
+ config/rs6000/rs6000.md, config/sh/sh.c, config/sh/sh.md,
+ config/stormy16/stormy16.c, config/v850/v850.md,
+ config/xtensa/xtensa.c: Replace gen_rtx with gen_rtx_fmt_e*.
+
+2004-02-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mcore/mcore.c (block_move_sequence): Replace
+ gen_rtx_CONST_INT with GEN_INT.
+
+2004-02-02 Jan Hubicka <jh@suse.cz>
+
+ * alias.c (record_set): Use hard_regno_nregs.
+ * bt-load.c (find_btr_reference, note_btr_set): Likewise.
+ * builtins.c (apply_args_size): Likewise.
+ * caller-save.c (setup_save_areas, save_call_clobbered_regs,
+ mark_set_regs, add_stored_regs, mark_referenced_regs,
+ insert_restore, insert_save, insert_one_insn): Likewise.
+ * cfgcleanup.c: Include regs.h
+ (mark_effect, mentions_nonequal_regs): Likewise.
+ * cfgrtl.c (mark_killed_regs): Likewise
+ * combine.c (update_table_tick, record_value_for_reg,
+ record_dead_and_set_regs, get_last_value_validate, use_crosses_set_p,
+ reg_dead_at_p_1, reg_dead_at_p, mark_used_regs_combine, move_deaths,
+ reg_bitfield_target_p, distribute_notes): Likewise.
+ * cse.c (mention_regs, insert, invalidate, invalidate_for_call,
+ exp_equiv_p, cse_insn): Likewise.
+ * cselib.c (cselib_lookup): Likewise.
+ (cselib_invalidate_regno, cselib_record_set): Likewise.
+ * df.c (df_ref_record): Likewise.
+ * dwarf2out.c (reg_loc_descriptor, multiple_reg_loc_descriptor):
+ Likewise.
+ * flow.c (mark_reg, insn_dead_p, mark_set_1, mark_used_reg,
+ count_or_remove_death_notes_bb): Likewise.
+ * function.c (aggregate_value_p, keep_stack_depressed): Likewise.
+ * gloval.c (global_alloc, find_reg, mark_reg_store, mark_reg_conflicts,
+ mark_reg_death, set_preference, reg_becomes_live, reg_dies): Likewise.
+ * integrate.c (mark_stores): Likewise.
+ * jump.c (delete_prior_computation): Likewise.
+ * lcm.c (reg_dies, reg_becomes_live): Likewise.
+ * local-alloc.c (combine_regs, find_free_reg, post_mark_life): Likewise.
+ * loop.c (LOOP_REGNO_NREGS): Likewise.
+ * postreload.c (reload_combine, reload_combine_note_store,
+ reload_combine_note_use, reload_cse_move2add, move2add_note_store): Likewise.
+ * ra-colorize.c (combine, color_usable_p, get_free_reg,
+ calculate_dont_begin, calculate_dont_begin, colorize_one_web,
+ try_recolor_web, insert_coalesced_conflicts, check_colors,
+ break_precolored_alias): Likewise.
+ * ra-debug.c: Include regs.h
+ (ra_print_rtx_object): Likewise.
+ * ra-rewrite (choose_spill_colors): Likewise.
+ (spill_same_color_p, update_spill_colors, spill_is_free): Likewise.
+ * ra.c (init_ra): Likewise.
+ * recog.c (reg_fits_class_p, peep2_reg_dead_p,
+ peep2_find_free_register): Likewise.
+ * reg-stack.c (subst_stack_regs_pat, convert_regs_exit): Likewise.
+ * regclass.c (hard_regno_nregs): New array.
+ (init_reg_modes_once): Initialize it.
+ (choose_hard_reg_mode): Use it.
+ (record_reg_classes): Likewise.
+ * regmove.c (mark_flags_life_zones): Likewise.
+ * regrename.c (note_sets, clear_dead_regs, regrename_optimize,
+ scan_rtx_reg, dump_def_use_chain, kill_value, set_value_regno,
+ copy_value, maybe_mode_change, find_oldest_value_reg,
+ copyprop_hardreg_forward_1):
+ * regs.h (hard_regno_nregs): Declare.
+ * realod.c (reload_inner_reg_of_subreg): Use it.
+ (push_reload, combine_reloads, find_dummy_reload,
+ hard_reg_set_here_p, operands_match_p, decompose, find_reloads,
+ refers_to_regno_for_reload_p, find_equiv_reg, regno_clobbered_p,
+ reload_adjust_reg_for_mode): Likewise.
+ * reload1.c (compute_use_by_pseudos, count_pseudo,
+ count_spilled_pseudo, find_reg, find_reload_regs, mark_home_live,
+ spill_hard_reg, forget_old_reloads_1, mark_reload_reg_in_use,
+ clear_reload_reg_in_use, reload_reg_free_for_value_p, free_for_value_p
+ allocate_reload_reg, choose_reload_regs, emit_reload_insns,
+ delete_output_reload): Likewise.
+ * resource.c (update_live_status, mark_referenced_resources,
+ mark_set_resources, mark_target_live_regs): Likewise.
+ * rtlanal.c: Include regs.h
+ (refers_to_regno_p, reg_overlap_mentioned_p, dead_or_set_p,
+ dead_or_set_regno_p, find_regno_note, find_reg_fusage,
+ subreg_regno_offset, subreg_offset_representable_p,
+ hoist_test_store): Likewise.
+ * sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
+ * sched-rgn.c (check_live_1, update_live_1): Likewise.
+ * stmt.c: Include regs.h
+ (decl_conflicts_with_clobbers_p): Likewise.
+ * varasm.c (make_decl_rtl): Likewise.
+ * Makefile.in (cfgcleanup.o, rtlanal.o, ra-debug.o): Add regs.h dependnecy.
+
+2004-02-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c, config/arm/arm.h, config/arm/arm.md,
+ config/arm/linux-gas.h, config/arm/netbsd-elf.h,
+ config/arm/netbsd.h, config/arm/pe.c, config/avr/avr.c,
+ config/avr/avr.h, config/avr/avr.md, config/c4x/c4x.h,
+ config/cris/cris.h, config/fr30/fr30.h, config/frv/frv.c,
+ config/frv/frv.h, config/ip2k/ip2k.c, config/iq2000/iq2000.c,
+ config/iq2000/iq2000.h, config/m32r/m32r.c,
+ config/m68hc11/m68hc11.c, config/m68hc11/m68hc11.h,
+ config/m68hc11/m68hc11.md, config/m68k/m68k.md,
+ config/mcore/mcore.c, config/mcore/mcore.h,
+ config/mcore/mcore.md, config/mips/mips.c,
+ config/ns32k/ns32k.h, config/ns32k/ns32k.md,
+ config/rs6000/rs6000.c, config/s390/s390.c,
+ config/s390/s390.md, config/sparc/sparc.c, config/v850/v850.c,
+ config/xtensa/xtensa.h, config/xtensa/xtensa.md: Replace
+ "gen_rtx (FOO, " with "gen_rtx_FOO (".
+
+2004-02-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (two peephole2's): New.
+
+2004-02-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sol2-bi.h: Handle TARGET_CPU_ultrasparc3.
+ (CPP_CPU_SPEC): Handle -mcpu=ultrasparc3.
+ (ASM_CPU_SPEC): Likewise
+ * config/sparc/sol2.h: Handle TARGET_CPU_ultrasparc3.
+ (ASM_CPU_SPEC): Remove -mcpu=v8plus. Handle -mcpu=ultrasparc3.
+
+2004-02-01 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_pow): If flag_unsafe_math_optimizations
+ isn't set, don't call expand_builtin_mathfn_2 to use the pow optab.
+ (expand_builtin): Always call expand_builtin_pow.
+
+2004-02-01 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (BUILT_IN_SIGNBIT, BUILT_IN_SIGNBITF,
+ BUILT_IN_SIGNBITL): New GCC builtins.
+ * builtins.c (expand_builtin_signbit): New function to RTL expand
+ calls to signbit, signbitf and signbitl as inline intrinsics.
+ (expand_builtin): Call expand_builtin_signbit for BUILT_IN_SIGNBIT*.
+ (fold_builtin_signbit): New function to perform constant folding
+ of signbit, signbitf and signbitl.
+ (fold_builtin): Call fold_builtin_signbit for BUILT_IN_SIGNBIT*.
+
+ * doc/extend.texi: Document new signbit{,f,l} builtins.
+
+2004-02-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (adddi3_internal_2): Remove superfluous %s.
+
+2004-02-01 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (PREDICATE_CODES): Remove entries for
+ "mips_const_double_ok" and "simple_memory_operand", which were
+ removed from the MIPS port with the mips-3_4-rewrite branch merge.
+ * config/mips/mips.c (mips16_lay_out_constants): Update comment
+ for removal of simple_memory_operand.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/c4x/c4x.md: Use GEN_INT instead of
+ gen_rtx (CONST_INT, ...).
+
+2004-01-31 Richard Henderson <rth@redhat.com>
+
+ * varasm.c (output_constant_pool): Don't zap the pool.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genrecog.c (decision_type): Add DT_const_int.
+ (write_cond) [DT_const_int]: Print a comparison against small
+ constant.
+ (write_node): Simplify comparisons against small constants
+ before printing tests.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c (m32r_load_pic_register): Use GEN_INT
+ instead of gen_rtx_CONST_INT.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/xtensa/xtensa.h (DYNAMIC_CHAIN_ADDRESS): Use GEN_INT
+ instead of gen_rtx_CONST_INT.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * target-def.h (TARGET_STRICT_ARGUMENT_NAMING): Define as
+ hook_bool_CUMULATIVE_ARGS_false.
+ * targhooks.c (default_strict_argument_naming): Rename to
+ hook_bool_CUMULATIVE_ARGS_false.
+ * targhooks.h: Update the prototype for
+ default_strict_argument_naming.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/sh.c: Replace "gen_rtx (FOO, " with "gen_rtx_FOO (".
+ * config/sh/sh.h: Likewise.
+ * config/sh/sh.md: Likewise.
+
+2004-01-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/invoke.texi (SPARC options): Restructure and update.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (PROMOTE_FUNCTION_ARGS, STRUCT_VALUE_INCOMING, and
+ STRICT_ARGUMENT_NAMING): Poison.
+ * target-def.h (TARGET_PROMOTE_FUNCTION_ARGS): Define as
+ hook_bool_tree_false.
+ * targhooks.c (default_promote_function_args): Remove.
+ (default_struct_value_rtx): Don't use STRUCT_VALUE_INCOMING.
+ Don't check incoming.
+ (default_strict_argument_naming): Don't use
+ STRICT_ARGUMENT_NAMING.
+ * targhooks.h: Remove the prototype for
+ default_promote_function_args.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-protos.h: Remove the prototype for
+ ix86_setup_incoming_varargs.
+ * config/i386/i386.c (TARGET_SETUP_INCOMING_VARARGS): New.
+ (ix86_setup_incoming_varargs): Make it static.
+ * config/i386/i386.h (SETUP_INCOMING_VARARGS): Remove.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alloc-pool.c: Fix comment typos.
+ * builtin-types.def: Likewise.
+ * builtins.def: Likewise.
+ * c-pretty-print.c: Likewise.
+ * df.h: Likewise.
+ * reload1.c: Likewise.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Follow spelling conventions.
+ * doc/tm.texi: Likewise.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+
+2004-01-31 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_decompose_address): Do not treat virtual
+ registers as pointers.
+ * config/s390/s390.md ("*la_31" second peephole2): Fix incorrect mode.
+
+2004-01-31 Paolo Bonzini <bonzini@gnu.org>
+
+ * combine.c (cse_main): Set gen_lowpart to gen_lowpart_for_combine
+ and restore it to gen_lowpart_general on exit.
+ (gen_lowpart_for_combine): Adjust all callers to go through
+ gen_lowpart.
+ * cse.c (cse_main): Set gen_lowpart to gen_lowpart_if_possible
+ and restore it to gen_lowpart_general on exit.
+ (gen_lowpart_if_possible): Adjust all callers to go through
+ gen_lowpart.
+ * emit-rtl.c (gen_lowpart_general): New name of gen_lowpart.
+ (gen_lowpart): Declare as pointer to function, initialized to
+ gen_lowpart_general.
+ * rtl.h (gen_lowpart): Declare as pointer to function.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bt-load.c: Replace "gen_rtx (FOO, " with "gen_rtx_FOO (".
+ * calls.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * function.c: Likewise.
+ * reload1.c: Likewise.
+ * config/i386/cygming.h: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/winnt.c: Likewise.
+
+2004-01-30 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ PR bootstrap/9249
+ * doc/install.texi: document --enable-__cxa_atexit option.
+ * configure.ac: Disable __cxa_atexit if not supported.
+ * configure: Regenerate.
+
+2004-01-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * ggc-zone.c (ggc_free): New function.
+
+2004-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ alloc-pool.c, c-lex.c, c-pragma.h, c-semantics.c, cfghooks.c,
+ cfghooks.h, cfglayout.c, cfgloopmanip.c, debug.c, debug.h,
+ flow.c, genextract.c, ggc-common.c, ggc-page.c, ggc.h,
+ ifcvt.c, jump.c, loop-unswitch.c, timevar.c, timevar.def,
+ tree-optimize.c, vmsdbgout.c, config/fp-bit.c,
+ config/alpha/alpha.c, config/alpha/alpha.h,
+ config/alpha/alpha.md, config/alpha/unicosmk.h,
+ config/alpha/vms.h, config/arm/linux-elf.h, config/avr/avr.c,
+ config/c4x/c4x-protos.h, config/c4x/c4x.md,
+ config/d30v/d30v.h, config/frv/frv.md, config/frv/frvbegin.c,
+ config/frv/frvend.c, config/i386/cygming.h,
+ config/i386/djgpp.h, config/i386/emmintrin.h,
+ config/i386/gthr-win32.c, config/i386/i386-interix.h,
+ config/i386/i386-protos.h, config/i386/openbsd.h,
+ config/i386/winnt.c, config/i386/xm-mingw32.h,
+ config/i386/xmmintrin.h, config/ia64/ia64.md,
+ config/iq2000/iq2000.md, config/m32r/m32r.md,
+ config/m68k/m68k.md, config/mcore/mcore-elf.h,
+ config/mcore/mcore.md, config/mips/elf.h, config/mips/elf64.h,
+ config/mips/iris5gas.h, config/mips/iris6.h,
+ config/mips/iris6gas.h, config/mips/linux.h,
+ config/mips/mips.md, config/mips/netbsd.h,
+ config/mips/openbsd.h, config/mips/windiss.h,
+ config/pa/fptr.c, config/rs6000/aix.h,
+ config/rs6000/altivec.h, config/rs6000/darwin.h,
+ config/rs6000/xcoff.h, config/s390/s390-protos.h,
+ config/s390/s390.c, config/s390/s390.h, config/s390/s390.md,
+ config/sh/netbsd-elf.h, config/sh/sh.h, config/sh/vxworks.h,
+ config/sparc/sol2.h: Update copyright.
+
+2004-01-30 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (abs_docdir, abs_srcdir): Define.
+ (doc/%.dvi, doc/gccinstall.dvi): Use $(abs_docdir).
+
+2004-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genconfig.c (main): Have CC0_P check its operand even on a
+ target without cc0.
+
+2004-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c: Remove mentions of deprecates macros
+ in comments, remove some target-independent comments about target
+ macros, and/or add minimal function comments for target hook
+ implementations.
+ * config/avr/avr.c: Likewise.
+ * config/ia64/ia64.h: Likewise.
+ * config/ip2k/ip2k.c: Likewise.
+ * config/iq2000/iq2000.c: Likewise.
+ * config/m32r/m32r.h: Likewise.
+ * config/m68hc11/m68hc11.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mmix/mmix.c: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/pdp11/pdp11.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+
+2004-01-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR optimization/12147
+ * reload1.c (reload_reg_free_p): RELOAD_OTHER conflicts with
+ RELOAD_FOR_OPADDR_ADDR.
+ (reload_reg_reaches_end_p): RELOAD_FOR_OTHER_ADDRESS register
+ might be reused as RELOAD_FOR_OPADDR_ADDR register.
+
+2004-01-30 Jan Hubicka <jh@suse.cz>
+
+ * reload.c (get_secondary_mem): Fix updating of
+ secondary_memlocs_elim_used.
+
+2004-01-30 Richard Henderson <rth@redhat.com>
+
+ * varasm.c (struct rtx_const, struct pool_constant): Remove.
+ (MAX_RTX_HASH_TABLE): Remove.
+ (const_rtx_hash_table, const_rtx_sym_hash_table): Remove.
+ (first_pool, last_pool, pool_offset): Remove.
+ (struct rtx_constant_pool): Split out from ...
+ (struct varasm_status): ... here. Reference one via pointer.
+ (struct constant_descriptor_rtx): Merge struct pool_constant.
+ (SYMHASH): Remove.
+ (decode_rtx_const): Remove.
+ (const_hash_rtx, compare_constant_rtx): Remove.
+ (record_constant_rtx): Remove.
+ (const_desc_rtx_hash, const_desc_rtx_eq): New.
+ (const_desc_rtx_sym_hash, const_desc_rtx_sym_eq): New.
+ (const_rtx_hash_1, const_rtx_hash): New.
+ (init_varasm_status): Allocate a rtx_constant_pool, and its hashes.
+ (simplify_subtraction): Use simplify_rtx.
+ (force_const_mem): Rewrite to use new data structures.
+ (find_pool_constant): Likewise.
+ (get_pool_constant, get_pool_constant_mark,
+ get_pool_constant_for_function, get_pool_mode,
+ get_pool_mode_for_function, get_pool_offset, get_pool_size): Likewise.
+ (output_constant_pool_2): Split out from output_constant_pool.
+ (output_constant_pool_1): Likewise. Use new pool datastructures.
+ (output_constant_pool): Zap entire pool datastructure.
+ (mark_constant): Use new pool datastructures.
+ (mark_constants): Use for_each_rtx.
+ (mark_constant_pool): Use new pool datastructures.
+
+2004-01-30 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): Remove #if 0.
+ Copy operands[1] to pseudo for simplify_gen_subreg.
+
+2004-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcse.c (bypass_block): Fix a typo in the previous check-in
+ to the file.
+
+2004-01-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * toplev.c: Include alloc-pool.h.
+ * Makefile.in (toplev.c): Update dependencies.
+
+2004-01-30 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * combine.c (simplify_shift_const, case XOR): Be careful when
+ commuting XOR with ASHIFTRT.
+
+2004-01-30 Kazu Hirata <kazu@cs.umass.edu>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc-protos.h: Remove the prototype for
+ sparc_builtin_saveregs.
+ * config/sparc/sparc.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_EXPAND_BUILTIN_SAVEREGS): Likewise.
+ (TARGET_STRICT_ARGUMENT_NAMING): Likewise.
+ (sparc_builtin_saveregs): Make it static.
+ (sparc_promote_prototypes): New.
+ (sparc_struct_value_rtx): Likewise.
+ (sparc_return_in_memory): Likewise.
+ * config/sparc/sparc.h: (PROMOTE_FUNCTION_ARGS): Remove.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (STRUCT_VALUE): Likewise.
+ (STRUCT_VALUE_INCOMING): Likewise.
+ (EXPAND_BUILTIN_SAVEREGS): Likewise.
+ (STRICT_ARGUMENT_NAMING): Likewise.
+ (PROMOTE_PROTOTYPES): Likewise.
+
+ * config/sparc/sparc.h (PROMOTE_MODE): Use word_mode.
+
+2004-01-30 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/12818
+ * varasm.c (const_hash_1) <STRING_CST>: Use the
+ address to compute the hash value if flag_writable_strings.
+ (compare_constant) <STRING_CST>: Compare the addresses
+ if flag_writable_strings.
+ (build_constant_desc): Do not copy the expression for a
+ STRING_CST if flag_writable_strings.
+
+2004-01-30 Jan Hubicka <jh@suse.cz>
+
+ * alloc-pool.c: Include hashtab.h
+ (alloc_pool_descriptor): New structure
+ (alloc_pool_hash): New global variable.
+ (hash_descriptor, eq_descriptor, alloc_pool_descriptor): New.
+ (create_alloc_pool): Update statistics.
+ (free_alloc_pool): Likewise.
+ (pool_alloc): Likewise.
+ (output_info): New structure
+ (print_statistics, dump_alloc_pool_statistics): New function.
+ * alloc-pool.h (alloc_pool_def): Turn name to be constant.
+ (dump_alloc_pool_statistics): Declare.
+ * toplev.c (finalize): Dump statistics.
+
+ * reload.c (secondary_memlocs_elim_used): New static variable.
+ (get_secondary_mem): Update it.
+ (find_reloads): Use it.
+
+2004-01-30 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * toplev.c: Fix broken checkin of 2003-12-30, again.
+
+2004-01-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * configure.ac (gcc_cv_as_dwarf2_debug_line): Enable test for
+ s390*-*-* targets by specifying a 'nop' insn.
+ * configure: Regenerate.
+
+2004-01-30 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/11475
+ * config/sparc/sparc.md (movhi_lo_sum): Tighten predicates.
+
+2004-01-29 Jakub Jelinek <jakub@redhat.com>
+
+ * emit-rtl.c (change_address): Use XEXP (memref, 0) instead
+ of addr when creating MEM copy.
+
+2004-01-29 Devang Patel <dpatel@apple.com>
+
+ * dwarf2out.c (gen_field_die): Do not equate decl number to die.
+
+2004-01-28 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR inline-asm/6162
+ * reload.c (find_reloads): Only support one pair of commutative
+ operands.
+
+2004-01-29 Roger Sayle <roger@eyesopen.com>
+
+ PR java/13824
+ * tree.c (unsafe_for_reeval): Handle EXIT_BLOCK_EXPR nodes specially
+ as their EXIT_BLOCK_LABELED_BLOCK operands can lead to unbounded
+ recursion.
+
+2004-01-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/frv/frv.c: Don't mention deprecated macros in
+ comments. Remove some target-independent comments about
+ target macros.
+ * config/frv/frv.h: Likewise.
+
+2004-01-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfghooks.c (split_block): Set probability and count of the
+ new edge.
+
+2004-01-29 Josef Zlomek <zlomekj@suse.cz>
+
+ * dwarf2out.c (struct die_struct): Added field decl_id.
+ (decl_die_table): Changed to hash table.
+ (decl_die_table_allocated): Deleted.
+ (decl_die_table_in_use): Deleted.
+ (DECL_DIE_TABLE_INCREMENT): Deleted.
+ (decl_die_table_hash): New function.
+ (decl_die_table_eq): New function.
+ (lookup_decl_die): Lookup in a hash table.
+ (equate_decl_number_to_die): Insert into a hash table.
+ (dwarf2out_init): Init hash table decl_die_table.
+
+2004-01-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR optimization/13424
+ * expr.c (store_constructor): Revert 2003-12-03 change.
+
+ * emit-rtl.c (change_address): Check also if MEM_ATTRS is set as
+ expected before returning early. Avoid sharing RTL if they
+ need to be changed.
+
+ * config/i386/i386.c (ix86_expand_movstr): Rework rep_mov and strmov
+ handling so that memory attributes are preserved. Don't call
+ ix86_set_move_mem_attrs.
+ (ix86_set_move_mem_attrs_1, ix86_set_move_mem_attrs): Removed.
+ (ix86_expand_clrstr): Rename src argument to
+ dst. Rework rep_stos and strset handling so that memory attributes
+ are preserved.
+ (ix86_expand_strlen): Pass src argument to
+ ix86_expand_strlensi_unroll_1. Rework strlenqi_1 handling so that
+ memory attributes are preserved.
+ (ix86_expand_strlensi_unroll_1): Add src argument. Use
+ change_address instead of gen_rtx_MEM.
+ * config/i386/i386.md (strmov, strmov_singleop, rep_mov): New
+ expanders.
+ (strmovdi_rex64, strmovsi, strmovsi_rex64, strmovhi, strmovhi_rex64,
+ strmovqi, strmovqi_rex64): Remove.
+ (rep_mov*, strmov*): Prefix insn names with *.
+ (strset, strset_singleop, rep_stos): New expanders.
+ (strsetdi_rex64, strsetsi, strsetsi_rex64, strsethi, strsethi_rex64,
+ strsetqi, strsetqi_rex64): Remove.
+ (rep_stos*, strset*): Prefix insn names with *.
+ (rep_stosqi_rex64): Likewise. Fix mode of dirflag reg from DImode
+ to SImode.
+ (cmpstrsi): Rework cmpstrqi_1 handling so that memory attributes
+ are preserved.
+ (cmpstrqi_nz_1, cmpstrqi_nz_rex_1, cmpstrqi_1, cmpstrqi_rex_1):
+ Prefix insn names with *.
+ (cmpstrqi_nz_1, cmpstrqi_1): New expanders.
+ (strlenqi_1, strlenqi_rex_1): Prefix insn names with *.
+ (strlenqi_1): New expander.
+ * config/i386/i386.h (ix86_set_move_mem_attrs): Remove prototype.
+
+2004-01-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
+ * basic-block.h (tidy_fallthru_edge, tidy_fallthru_edges, dump_bb,
+ verify_flow_info): Declaration removed.
+ * cfg.c (verify_flow_info, dump_bb): Moved to cfghooks.c.
+ (debug_bb, debug_bb_n): Add argument to dump_bb call.
+ * cfgcleanup.c (try_simplify_condjump, try_crossjump_to_edge,
+ try_optimize_cfg, delete_unreachable_blocks): Use delete_basic_block
+ instead of delete_block.
+ * cfghooks.c: Include timevar.h and toplev.h.
+ (cfg_hooks): Define here.
+ (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 functions.
+ * cfghooks.h (struct cfg_hooks): Added fields name,
+ make_forwarder_block, tidy_fallthru_edge and
+ move_block_after. Changed type of verify_flow_info, dump_bb,
+ split_block fields. Renamed cfgh_split_edge and delete_block
+ fields.
+ (redirect_edge_and_branch, redirect_edge_and_branch_force,
+ split_block, delete_block, split_edge, create_basic_block,
+ can_merge_blocks_p, merge_blocks): Macros removed.
+ (cfg_hooks): Do not export.
+ (verify_flow_info, dump_bb, 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):
+ Declare.
+ (cfg_layout_rtl_cfg_hooks): Declare.
+ * cfgloop.c (update_latch_info, mfb_keep_just, mfb_keep_nonlatch):
+ New functions.
+ (canonicalize_loop_headers): Use new semantics of make_forwarder_block.
+ (redirect_edge_with_latch_update): Removed.
+ (make_forwarder_block): Moved to cfghooks.c, semantics changed.
+ * cfgloopmanip.c (remove_bbs): Do not update dominators here.
+ * cfgrtl.c (cfg_layout_split_block, rtl_split_block, rtl_dump_bb,
+ rtl_delete_block, rtl_split_block, rtl_merge_blocks,
+ tidy_fallthru_edge, rtl_split_edge, cfg_layout_delete_block,
+ cfg_layout_merge_blocks, cfg_layout_split_edge): Partly moved to
+ cfghooks.c.
+ (rtl_create_basic_block): Coding style fix.
+ (rtl_tidy_fallthru_edge, rtl_move_block_after,
+ rtl_make_forwarder_block): New functions.
+ (update_cfg_after_block_merging): Removed.
+ (rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Fill in new entries.
+ * flow.c (verify_wide_reg, verify_local_live_at_start): Add argument
+ to dump_bb.
+ * ifcvt.c (merge_if_block, find_cond_trap, find_if_case_1,
+ find_if_case_2): Don't update dominators.
+ * timevar.def (TV_CFG_VERIFY): New.
+ * loop-unswitch.c (unswitch_loop): Don't call add_to_dominance_info.
+ * cfglayout.c (copy_bbs): Don't call add_to_dominance_info.
+ * 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.
+
+2004-01-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.h: Remove target-independent comments about
+ target macros.
+
+2004-01-28 Daniel Berlin <dberlin@dberlin.org>
+
+ * timevar.c (timevar_print): Mention when checking is enabled.
+
+2004-01-28 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * c-lex.c (c_lex): Rename to...
+ (c_lex_with_flags): Add new parameter to get CPP flags.
+ (c_lex): Thunk to c_lex_with_flags while keeping the old interface.
+ * c-pragma.h (c_lex_with_flags): Declare.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mcore/mcore.c (mcore_external_libcall): Add a
+ comment.
+ (mcore_return_in_memory): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mcore/mcore-protos.h: Remove the prototype for
+ mcore_setup_incoming_varargs.
+ * config/mcore/mcore.c (TARGET_ASM_EXTERNAL_LIBCALL): New.
+ (TARGET_PROMOTE_FUNCTION_ARGS): Likewise.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (mcore_setup_incoming_varargs): Make it static. Receive the
+ first argument by reference. Add argument second_time.
+ (mcore_external_libcall): New.
+ (mcore_return_in_memory): Likewise.
+ * config/mcore/mcore.h (PROMOTE_FUNCTION_ARGS): New.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+ (STRUCT_VALUE): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (SETUP_INCOMING_VARARGS): Likewise.
+ (PROMOTE_PROTOTYPES): Likewise.
+ (ASM_OUTPUT_EXTERNAL_LIBCALL): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r-protos.h: Remove the prototype for
+ m32r_setup_incoming_varargs.
+ * config/m32r/m32r.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (m32r_return_in_memory): New.
+ (m32r_setup_incoming_varargs): Make it static.
+ * config/m32r/m32r.h: Remove #undef of
+ ASM_OUTPUT_EXTERNAL_LIBCALL. Remove the commented-out
+ definitions of PROMOTE_FUNCTION_ARGS and
+ PROMOTE_FUNCTION_RETURN.
+ (PROMOTE_PROTOTYPES): Remove.
+ (RETURN_IN_MEMORY): Likewise.
+ (STRUCT_VALUE): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/m68k.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (m68k_struct_value_rtx): Likewise.
+ * config/m68k/m68k.h (STRUCT_VALUE_REGNUM): Rename to
+ STRUCT_VALUE_REGNUM.
+ (PROMOTE_PROTOTYPES): Remove.
+ * config/m68k/m68kelf.h (STRUCT_VALUE_REGNUM): Rename to
+ STRUCT_VALUE_REGNUM.
+ * config/m68k/m68kv4.h (STRUCT_VALUE_REGNUM): Likewise.
+ * config/m68k/netbsd-elf.h (STRUCT_VALUE_REGNUM): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/stormy16/stormy16.c
+ (TARGET_BUILD_BUILTIN_VA_LIST_TYPE): Rename to
+ TARGET_BUILD_BUILTIN_VA_LIST.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/v850/v850.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (v850_return_in_memory): Likewise.
+ (v850_setup_incoming_varargs): Likewise.
+ * config/v850/v850.h (PROMOTE_PROTOTYPES): Remove.
+ (SETUP_INCOMING_VARARGS): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (STRUCT_VALUE): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/fr30/fr30.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (fr30_setup_incoming_varargs): Don't use
+ STRICT_ARGUMENT_NAMING.
+ * config/fr30/fr30.h (PROMOTE_PROTOTYPES): Remove.
+ (STRICT_ARGUMENT_NAMING): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/frv/frv-protos.h: Remove the prototype for
+ frv_expand_builtin_saveregs.
+ * config/frv/frv.c (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_EXPAND_BUILTIN_SAVEREGS): Likewise.
+ (frv_stack_info): Use FRV_STRUCT_VALUE_REGNUM instead of
+ STRUCT_VALUE_REGNUM.
+ (frv_expand_builtin_saveregs): Make it static.
+ (frv_struct_value_rtx): New.
+ * config/frv/frv.h (EXPAND_BUILTIN_SAVEREGS): Remove.
+
+2004-01-29 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12850
+ * cgraph.c (cgraph_remove_node): Clear out saved/insns/arguments and
+ initial pointers.
+ * cgraphunit.c (cgraph_finalize_function): Clear out DECL_SAVED_INSNS
+ for functions that will be only inlined.
+ (cgraph_mark_function_to_output): Likewise.
+ (cgraph_expand_function): Sanity check that DECL_DEFER_OUTPUT is clear;
+ do not clear function body.
+ * tree-optimize.c (clear_decl_rtl): Use decl_function_context.
+ (tree_rest_of_compilation): Reorganize the logic releasing function
+ body to use callgraph datastructure.
+
+2004-01-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md: Change predicate of a peephole2 pattern from reg_or_0_operand
+ to register_operand.
+
+2004-01-28 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.md (fetchadd_acq_si, fetchadd_acq_di)
+ (cmpxchg_acq_si, cmpxchg_acq_di): Exchange match_dup and
+ match_operand expressions so that all match_dups appear
+ lexically after their corresponding match_operands.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (WORD_REG_USED): Use
+ HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM.
+ (compute_saved_regs): Likewise.
+ (h8300_expand_prologue): Likewise. Allocate locals after
+ saving registers.
+ (h8300_expand_epilogue): Use HARD_FRAME_POINTER_REGNUM instead
+ of FRAME_POINTER_REGNUM. Deallocate locals before saving
+ registers.
+ (h8300_initial_elimination_offset): Adjust for the new frame
+ layout, which swaps flips the order of locals and saved
+ registers.
+ * config/h8300/h8300.h (FIRST_PSEUDO_REGISTER): Change to 12.
+ (HARD_FRAME_POINTER_REGNUM): New.
+ (ELIMINABLE_REGS): Add an elimination rule from
+ FRAME_POINTER_REGNUM to HARD_FRAME_POINTER_REGNUM.
+ (REGISTER_NAMES): Add fp.
+ * config/h8300/h8300.md (FP_REG): Change to 11.
+ (HFP_REG): New.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genrecog.c (write_node): Remove a useless local variable.
+
+2004-01-28 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * Makefile.in (options.c options.h): Use stamp file s-options to
+ avoid unnecessary rebuilds.
+ (options.o): New target listing dependencies.
+ (gtyp-gen.h): Use stamp file s-gtyp-gen.
+ (STAGESTUFF): Add s-gtyp-gen.
+
+2004-01-28 Richard Henderson <rth@redhat.com>
+
+ * ggc.h (ggc_free): Declare.
+ * ggc-common.c (ggc_realloc): Use it.
+ * ggc-page.c: Remove lots of inline markers.
+ (globals): Add free_object_list.
+ (ggc_alloc): Tidy.
+ (ggc_free, validate_free_objects): New.
+ (poison_pages): Provide default.
+ (ggc_collect): Call validate_free_objects; emit markers to
+ the debug file.
+
+2004-01-28 Zack Weinberg <zack@codesourcery.com>
+ Jim Wilson <wilson@specifixinc.com>
+
+ * config/ia64/ia64.c (ia64_split_tmode, ia64_split_tmode_move):
+ Rewrite to use POST_INC/POST_DEC/POST_MODIFY instead of a
+ scratch pointer.
+ (ia64_secondary_reload_class): Delete case GR_REGS.
+ * config/ia64/ia64.md (movti, *movti_internal, movtf, *movtf_internal):
+ Do not allocate a scratch register.
+ (reload_inti, reload_outti, reload_intf, reload_outtf): Delete.
+
+2004-01-28 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (bypass_block): Prevent edges to be unified when we are
+ about to emit compenstation code.
+
+2004-01-28 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (arm_expand_builtin): Force second argument of
+ the setcwx insn into a register.
+
+2004-01-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/fp-bit.c (pack_d): When using paired doubles to implement
+ a long double, round the high part separately.
+ (unpack_d): Fix the case in which the high part is a power of two
+ and the low part is a nonzero value of the opposite sign.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/c4x/c4x.c (TARGET_ASM_EXTERNAL_LIBCALL): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (c4x_external_libcall): Likewise.
+ (c4x_struct_value_rtx): Likewise.
+ * config/c4x/c4x.h: Remove.
+ (STRUCT_VALUE_REGNUM): Likewise.
+ (ASM_OUTPUT_EXTERNAL_LIBCALL): Likewise.
+
+2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ * config/i386/i386.h (STRUCT_VALUE_INCOMING): Remove.
+ (STRUCT_VALUE): Likewise.
+ (PROMOTE_PROTOTYPES): Likewise.
+
+2004-01-27 Roger Sayle <roger@eyesopen.com>
+
+ * config/pa/pa.c (emit_move_sequence): Check that operand1 is a
+ CONST_INT before using INTVAL.
+
+2004-01-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (TARGET_DEFAULT): Default to !TARGET_BACKCHAIN.
+ * config/s390/s390.c (s390_return_addr_rtx): Fail for all but current
+ frame if !TARGET_BACKCHAIN.
+ * config/s390/s390.md ("allocate_stack"): Use pattern only if
+ TARGET_BACKCHAIN.
+ * doc/invoke.texi (-mbackchain/-mno-backchain): Document new default.
+
+2004-01-27 Zack Weinberg <zack@codesourcery.com>
+
+ * ia64.c (ia64_function_arg): When placing HFAs in integer
+ registers, do not special case the mode used for complex
+ types. Do not advance int_regs until the current register
+ is full.
+
+2004-01-27 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/7297
+ * except.c (init_eh): Use a 5-word __jbuf for __builtin_setjmp().
+
+2004-01-27 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): #if 0 splitting
+ slow, unaligned loads and stores while debugging. Fix formatting.
+
+2004-01-27 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (save_stack_nonlocal): Use Pmode instead
+ of computing wmode.
+ (restore_stack_nonlocal): Same.
+
+2004-01-27 Devang Patel <dpatel@apple.com>
+
+ * Makefile.in (dwarf2out.o): Depend on input.h
+ * dbxout.c (dbx_debug_hooks): Add new empty hook for
+ imported_module_or_decl.
+ (xcoff_debug_hooks): Same.
+ * sdbout.c (sdb_debug_hooks): Same.
+ * vmsdbgout.c (vmsdbg_debug_hooks): Same.
+ * debug.c (do_nothing_debug_hooks): Same.
+ (debug_nothing_tree_tree): New function.
+ * debug.h (gcc_debug_hooks): New hook, imported_module_or_decl.
+ * dwarf2out.c: Include input.h.
+ (dwarf2_debug_hooks): Add new hook for imported_module_or_decl.
+ (remove_child_TAG): New function.
+ (dwarf_tag_name): Handle DW_TAG_imported_module.
+ (gen_subprogram_die): Equate decl number to declaration die. Do not
+ remove all children dies while reusing declaration die for definition.
+ Instead, selectively remove only formal parameters.
+ (gen_variable_die): Equate variable decl to declaration die.
+ (gen_field_die): Equate field decl to line number.
+ (force_namespace_die): Replace it with ...
+ (force_decl_die): ... this.
+ (force_type_die): New function.
+ (setup_namespace_context): Replace use of force_namespace_die() with
+ force_decl_die().
+ (gen_namespace_die): Same.
+ (dwarf2out_imported_module_or_decl): New function.
+
+2004-01-27 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_copy_incoming_a7): Remove SUBREG
+ on CQImode and CHImode incoming arguments in register a7.
+ (function_arg): Wrap BLKmode argument in register a7 in a PARALLEL.
+ * config/xtensa/xtensa.h (BLOCK_REG_PADDING): Define.
+ * config/xtensa/xtensa.md (movdi, movdf): Only call force_reg or
+ xtensa_copy_incoming_a7 before reload.
+
+2004-01-27 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * coverage.c (get_coverage_counts): Give a different message
+ if flag_guess_branch_prob is set.
+ * predict.c (counts_to_freqs): Return an int.
+ (estimate_bb_frequencies): If counts_to_freqs returns zero,
+ calculate estimates.
+
+2004-01-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/iq2000/iq2000-protos.h: Remove the prototype for
+ iq2000_setup_incoming_varargs.
+ * config/iq2000/iq2000.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (TARGET_STRICT_ARGUMENT_NAMING): Likewise.
+ (iq2000_return_in_memory): Likewise.
+ (iq2000_setup_incoming_varargs): Make it static. Receive the
+ first argument by reference.
+ * config/iq2000/iq2000.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+ (PROMOTE_PROTOTYPES): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (STRUCT_VALUE): Likewise.
+ (SETUP_INCOMING_VARARGS): Likewise.
+ (STRICT_ARGUMENT_NAMING): Likewise.
+
+2004-01-24 James A. Morrison <ja2morri@uwaterloo.ca>
+
+ * fixinc/fixinc.c (test_test): Initialize res.
+ (start_flexer): Initialize pz_cmd_save.
+
+2004-01-27 Zack Weinberg <zack@codesourcery.com>
+
+ * doc/rtl.texi (Arithmetic): Rewrite entries for PLUS,
+ SS_PLUS, US_PLUS, LO_SUM, MINUS, SS_MINUS, US_MINUS.
+
+2004-01-27 Zack Weinberg <zack@codesourcery.com>
+
+ PR 7198
+ * config/ia64/ia64.md (*nmaddsf4, *nmadddf4, *nmadddf4_alts)
+ (*nmadddf4_trunc, *nmaddxf4, *nmaddxf4_truncsf, *nmaddxf4_truncdf)
+ (*nmaddxf4_alts, *nmaddxf4_truncdf_alts):
+ Rewrite pattern as (minus (op 3) (mult (op 1) (op 2))).
+ Possibly rename pattern for consistency.
+ Remove ??? comments suggesting that this be done.
+ (*nmaddsf4_alts, *nmadddf4_truncsf_alts, *nmaddxf4_truncsf_alts):
+ New patterns.
+ (divsi3_internal, divdi3_internal_lat, divdi3_internal_thr)
+ (divsf3_internal_lat, divsf3_internal_thr, sqrtsf2_internal_thr)
+ (divdf3_internal_lat, divdf3_internal_thr, sqrtdf2_internal_thr)
+ (divxf3_internal_lat, divxf3_internal_thr, sqrtxf2_internal_thr):
+ Update to match.
+
+2004-01-27 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/arm.c (output_return_instruction): Only restore IP
+ into SP if frame_pointer_needed.
+
+2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
+ for SCmode and DCmode if ARCH32.
+ (sparc_va_arg): Handle SCmode and DCmode by reference if ARCH32.
+ * config/sparc/sparc.h (RETURN_IN_MEMORY): Return 0 for TCmode
+ if ARCH32.
+ (BASE_RETURN_VALUE_REG): Return 32 for all FP modes except TFmode
+ if ARCH32.
+ (BASE_OUTGOING_VALUE_REG): Likewise.
+
+2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/10904
+ PR target/13058
+ * config/sparc/sparc.h (CANNOT_CHANGE_MODE_CLASS): New.
+ Forbid mode changes from SImode for lower FP regs if ARCH64.
+
+2004-01-27 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * Makefile.in (bt-load.o): Depend on except.h.
+ * bt-load.c (except.h): #include.
+ (compute_defs_uses_and_gen): If insn at end of BB can throw
+ within this function, consider registers used by it unavailable for
+ btr migration.
+ (move_btr_def): If insn at end of BB can throw, insert before rather
+ than after.
+
+ * flags.h (flag_btr_bb_exclusive): Declare.
+ * toplev.c (flag_btr_bb_exclusive): New variable.
+ (f_options): Add btr-bb-exclusive.
+ * bt-load.c (augment_live_range): Restore old behaviour if
+ flag_btr_bb_exclusive is set.
+ * common.opt: Add entry for -fbtr-bb-exclusive.
+ * opts.c (common_handle_options): Same.
+ * doc/invoke.texi: Document -fbtr-bb-exclusive.
+
+ * bt-load.c (btrs_live_at_end): New variable.
+ (compute_defs_uses_and_gen): Compute its pointed-to array.
+ (clear_btr_from_live_range, add_btr_to_live_range): Update it.
+ (augment_live_range): When augmenting with a new dominator,
+ use only its btrs_live_at_end set, but also add in the full set
+ of the old dominator.
+ (btr_def_live_range): Use btrs_live_at_end.
+ (move_btr_def): Set other_btr_uses_before_def, and move new set
+ to the end of the basic block, if appropriate.
+ (migrate_btr_defs): Allocate and free btrs_live_at_end.
+
+ * bt-load.c (basic_block_freq): Remove outdated comment.
+
+2004-01-27 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.h: Correct target_flags free bits comment.
+ (PREDICATE_CODES): Remove duplicate.
+ * config/rs6000/linux64.h (CPP_SYSV_SPEC): Don't define.
+ (SUBSUBTARGET_OVERRIDE_OPTIONS): Disallow 32 bit TARGET_PROFILE_KERNEL.
+ (MASK_PROFILE_KERNEL): Adjust define.
+
+2004-01-27 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (ix86_constant_alignment): Decrease alignment
+ of long string literals from 32 bytes to sizeof (void *) when !-Os
+ and to 1 with -Os.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_tiny_constant_address_p): Accept
+ constant addresses in the normal mode.
+
+2004-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h (CHAR_BITFIELD): Delete.
+ (BOOL_BITFIELD): New.
+ * c-decl.c (c_scope): Use BOOL_BITFIELD.
+ * gengtype-lex.l: Recognize BOOL_BITFIELD instead of CHAR_BITFIELD.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arc/arc.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (arc_return_in_memory): Likewise.
+ * config/arc/arc.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (STRUCT_VALUE): Likewise.
+
+2004-01-26 Richard Henderson <rth@redhat.com>
+
+ * c-parse.in (extension): Use itype.
+ (SAVE_EXT_FLAGS): Don't allocate a tree.
+ (RESTORE_EXT_FLAGS): Don't read a tree.
+
+2004-01-26 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (discard_useless_values): Clear out value pointer pointing
+ to datastructure to be recycled.
+
+2004-01-25 Jan Hubicka <jh@suse.cz>
+
+ * genextract.c (main): Do not output the memset when not checking.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_tiny_constant_address_p): Use a
+ switch statement instead of a chain of if statements.
+
+2004-01-26 Jeff Law <law@redhat.com>
+
+ * doc/contrib.texi: Minor cleanup for Paolo Carlini's entry. Add
+ acute accents for Petur Runolfsson's entry.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/pdp11/pdp11.c (TARGET_STRUCT_VALUE_RTX): New.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ * config/pdp11/pdp11.h (STRUCT_VALUE): Remove.
+ (RETURN_IN_MEMORY): Likewise.
+
+2004-01-26 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): split slow
+ unaligned load/store into smaller loads and stores.
+
+2004-01-26 Fariborz Jahanian <fjahanian@apple.com>
+
+ * function.c (assign_parms): Do not assign
+ long long argument to memory in prologue if
+ is it loaded into register.
+
+2004-01-26 Fariborz Jahanian <fjahanian@apple.com>
+
+ PR middle-end/13779
+ * expr.c (emit_group_load): split constant
+ correctly into register components of PARALLEL insn.
+
+2004-01-26 Fariborz Jahanian <fjahanian@apple.com>
+
+ * gcc/config/rs6000/rs6000.md (save_stack_nonlocal):
+ Use adjust_address_nv directly with appropriate mode.
+ (restore_stack_nonlocal): Ditto.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/xtensa/xtensa-protos.h: Remove the prototype for
+ xtensa_builtin_saveregs.
+ * config/xtensa/xtensa.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_EXPAND_BUILTIN_SAVEREGS): Likewise.
+ (xtensa_builtin_saveregs): Make it static.
+ (xtensa_return_in_memory): New.
+ * config/xtensa/xtensa.h (PROMOTE_FUNCTION_ARGS: Remove.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+ (PROMOTE_PROTOTYPES): Likewise.
+ (STRUCT_VALUE): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (EXPAND_BUILTIN_SAVEREGS): Likewise.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c (TARGET_SETUP_INCOMING_VARARGS): New.
+ (arm_setup_incoming_varargs): Likewise.
+ * config/arm/arm.h (SETUP_INCOMING_VARARGS): Remove.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/cris/cris.c (TARGET_SETUP_INCOMING_VARARGS): New.
+ (cris_setup_incoming_varargs): Likewise.
+ * config/cris/cris.h (SETUP_INCOMING_VARARGS): Remove.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ns32k/ns32k.c (TARGET_STRUCT_VALUE_RTX): New.
+ (ns32k_struct_value_rtx): Likewise.
+ * config/ns32k/ns32k.h (STRUCT_VALUE_REGNUM): Rename to
+ NS32K_STRUCT_VALUE_REGNUM.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (arm_struct_value_rtx): Likewise.
+ * config/arm/arm.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (STRUCT_VALUE): Likewise.
+ (STRUCT_VALUE_REGNUM): Likewise.
+ (PROMOTE_PROTOTYPES): Likewise.
+
+2004-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ia64/ia64-protos.h: Remove the prototype for
+ ia64_setup_incoming_varargs and ia64_return_in_memory.
+ * config/ia64/ia64.c (TARGET_STRUCT_VALUE_RTX): New.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (TARGET_STRICT_ARGUMENT_NAMING): Likewise.
+ (ia64_setup_incoming_varargs): Adjust the arguments to meet
+ the requirement of TARGET_SETUP_INCOMING_VARARGS.
+ (ia64_return_in_memory): Make it static. Change the return
+ type to bool from int. Add an argument.
+ (ia64_struct_value_rtx): New.
+ * config/ia64/ia64.h: Remove commented-out definitions of
+ PROMOTE_FUNCTION_ARGS, PROMOTE_FUNCTION_RETURN, and
+ PROMOTE_PROTOTYPES.
+ (RETURN_IN_MEMORY): Remove.
+ (STRUCT_VALUE_REGNUM): Likewise.
+ (STRICT_ARGUMENT_NAMING): Likewise.
+
+2004-01-26 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/13666
+ * config/sparc/sparc.c (function_arg_union_value): New function.
+ (function_arg): Use it to deal with unions.
+ (function_value): Likewise. Define 'regbase' only for ARCH64.
+ Replace a conditional statement by a simpler one.
+
+2004-01-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips16_optimize_gp): Delete.
+ (mips_reorg): Don't call it.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (addqi3_noclobber): Move up pecking order.
+ (floatunsqihf2): Remove operand 6.
+ (fixhfqi_set, fix_trunchfqi2, fixuns_trunchfqi2): Group with other
+ fix patterns.
+ (ldi_conditional, ldf_conditional): Validate operands.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (BCT_CHECK_LOOP_ITERATIONS): Remove.
+ (HAVE_GAS_HIDDEN): Undefine as interim measure.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_legitimate_address_p): Invalidate direct
+ memory references if TARGET_EXPOSE_LDP nonzero.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (legitimize_operands): Truncate invalid shift counts.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_valid_operands): More aggressively reject
+ invalid operand combinations.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_check_legit_addr): Rename to
+ c4x_legitimate_address_p. Fix post_modify check.
+
+ * config/c4x/c4x-protos.h (c4x_check_legit_addr): Adjust.
+ * config/c4x/c4x.h (c4x_check_legit_addr): Adjust.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/pa/pa-protos.h: Remove the prototype for
+ hppa_builtin_saveregs. Add a prototype for
+ pa_return_in_memory.
+ * config/pa/pa.c (TARGET_PROMOTE_FUNCTION_RETURN): New.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_EXPAND_BUILTIN_SAVEREGS): Likewise.
+ (pa_struct_value_rtx): Likewise.
+ (pa_return_in_memory): Likewise.
+ * config/pa/pa.h (STRUCT_VALUE_REGNUM): Rename to
+ PA_STRUCT_VALUE_REGNUM.
+ (INIT_CUMULATIVE_ARGS): Use pa_return_in_memory.
+ (EXPAND_BUILTIN_SAVEREGS): Remove.
+ (PROMOTE_PROTOTYPES): Likewise.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/vax/vax.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (vax_struct_value_rtx): Likewise.
+ * config/vax/vax.h (STRUCT_VALUE_REGNUM): Rename to
+ VAX_STRUCT_VALUE_REGNUM.
+ (PROMOTE_PROTOTYPES): Remove.
+
+2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (LEGITIMIZE_RELOAD_ADDRESS): Handle symref.
+
+2004-01-25 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (ISA_HAS_HILO_INTERLOCKS): MIPS32, MIPS32r2,
+ and MIPS64 have HI/LO interlocks. Update comment.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/stormy16/stormy16-protos.h: Remove the prototype for
+ xstormy16_setup_incoming_varargs.
+ * config/stormy16/stormy16.c
+ (xstormy16_setup_incoming_varargs): Remove.
+ (xstormy16_return_in_memory): New.
+ (TARGET_PROMOTE_FUNCTION_ARGS): Likewise.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ * config/stormy16/stormy16.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (PROMOTE_FUNCTION_RETURN): Likewise
+ (PROMOTE_PROTOTYPES): Likewise
+ (RETURN_IN_MEMORY): Likewise
+ (STRUCT_VALUE): Likewise
+ (SETUP_INCOMING_VARARGS): Likewise
+
+2004-01-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_offset_within_object_p): New function.
+ (mips_symbolic_constant_p): Use it in the SYMBOL_SMALL_DATA and
+ SYMBOL_CONSTANT_POOL cases. Also use it for SYMBOL_GENERAL if the
+ ABI has 64-bit pointers and the object file only allows 32-bit symbols.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/sh.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300-protos.h: Remove the prototype for
+ mn10300_builtin_saveregs.
+ * config/mn10300/mn10300.c (TARGET_PROMOTE_PROTOTYPES): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_EXPAND_BUILTIN_SAVEREGS): Likewise.
+ (mn10300_return_in_memory): Likewise.
+ (mn10300_builtin_saveregs): Make it static.
+ * config/mn10300/mn10300.h (PROMOTE_PROTOTYPES): Remove.
+ (RETURN_IN_MEMORY): Likewise.
+ (STRUCT_VALUE): Likewise.
+ (EXPAND_BUILTIN_SAVEREGS): Likewise.
+
+2004-01-25 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ PR bootstrap/13853
+ * cfgcleanup.c (try_optimize_cfg): Explicitly test against 0.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divnorm, modnorm): Optimize by
+ using ccr.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i860/i860-protos.h: Remove the prototype for
+ i860_saveregs.
+ * config/i860/i860.c (i860_saveregs): Make it static.
+ (i860_struct_value_rtx): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_EXPAND_BUILTIN_SAVEREGS): Likewise.
+ * config/i860/i860.h (STRUCT_VALUE_REGNUM): Rename to
+ I860_STRUCT_VALUE_REGNUM.
+ (EXPAND_BUILTIN_SAVEREGS): Remove.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68hc11/m68hc11.c (TARGET_STRUCT_VALUE_RTX): New.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (m68hc11_struct_value_rtx): Likewise.
+ (m68hc11_return_in_memory): Likewise.
+ * config/m68hc11/m68hc11.h: Remove a commented-out definition
+ of PROMOTE_PROTOTYPES.
+ (RETURN_IN_MEMORY): Remove.
+ (STRUCT_VALUE_REGNUM): Likewise.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mmix/mmix-protos.h: Remove the prototype for
+ mmix_setup_incoming_varargs.
+ * config/mmix/mmix.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (mmix_setup_incoming_varargs): Make it static.
+ (mmix_struct_value_rtx): New.
+ * config/mmix/mmix.h (PROMOTE_FUNCTION_ARGS): Remove.
+ Remove a commented-out definition of PROMOTE_FUNCTION_RETURN.
+ (STRUCT_VALUE_REGNUM): Remove.
+ (SETUP_INCOMING_VARARGS): Likewise.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mips/mips-protos.h: Remove the prototypes for
+ mips_setup_incoming_varargs and mips_return_in_memory.
+ * config/mips/mips.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_PROMOTE_PROTOTYPES): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (TARGET_STRICT_ARGUMENT_NAMING): Likewise.
+ (mips_setup_incoming_varargs): Match the prototype for
+ TARGET_SETUP_INCOMING_VARARGS.
+ (mips_return_in_memory): Make it static. Add argument fntype.
+ (mips_strict_argument_naming): New.
+ * config/mips/mips.h (PROMOTE_PROTOTYPES): Remove.
+ (PROMOTE_FUNCTION_ARGS): Likewise.
+ (PROMOTE_FUNCTION_RETURN): Likewise.
+ (STRUCT_VALUE): Likewise.
+ (RETURN_IN_MEMORY): Likewise.
+ (SETUP_INCOMING_VARARGS): Likewise.
+ (STRICT_ARGUMENT_NAMING): Likewise.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ip2k/ip2k.c (TARGET_STRUCT_VALUE_RTX): New.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_SETUP_INCOMING_VARARGS): Likewise.
+ (ip2k_return_in_memory): Likewise.
+ (ip2k_setup_incoming_varargs): Likewise.
+ * config/ip2k/ip2k.h (RETURN_IN_MEMORY): Remove.
+ (STRUCT_VALUE): Likewise.
+ (STRUCT_VALUE_INCOMING): Likewise.
+ (SETUP_INCOMING_VARARGS): Likewise.
+
+2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.c (TARGET_STRUCT_VALUE_RTX): New.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ (TARGET_STRICT_ARGUMENT_NAMING): Likewise.
+ (avr_return_in_memory): Remove.
+ * config/avr/avr.h (RETURN_IN_MEMORY): Remove.
+ (STRUCT_VALUE): Likewise.
+ (STRUCT_VALUE_INCOMING): Likewise.
+ (STRICT_ARGUMENT_NAMING): Likewise.
+
+2004-01-25 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (recog_for_combine): Avoid allocating unnecesary RTX.
+
+2004-01-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_reg_mode_ok_for_base_p): Delete.
+ (mips_regno_mode_ok_for_base_p): Declare.
+ * config/mips/mips.h (ARG_POINTER_REGNUM): Renumber to 77.
+ (FRAME_POINTER_REGNUM): Renumber to 78.
+ (FIRST_PSEUDO_REGISTER): Update comment accordingly.
+ (BASE_REG_P, GP_REG_OR_PSEUDO_STRICT_P): Delete.
+ (GP_REG_OR_PSEUDO_NONSTRICT_P): Delete.
+ (REGNO_MODE_OK_FOR_BASE_P): Use mips_regno_mode_ok_for_base_p.
+ (REG_MODE_OK_FOR_BASE_P): Likewise.
+ * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Change
+ entry for 77 to "$arg" and entry for 78 to "$frame".
+ (mips_regno_to_class): Map 77 and 78 to ALL_REGS.
+ (mips_reg_mode_ok_for_base_p): Remove.
+ (mips_regno_mode_ok_for_base_p): New function, derived from old
+ BASE_REG_P macro. Don't enforce the mips16 stack pointer
+ restrictions unless we're being strict.
+ (mips_valid_base_register_p): Use mips_regno_mode_ok_for_base_p.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.h: Fix comment typos.
+ * c-decl.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * combine.c: Likewise.
+ * et-forest.c: Likewise.
+ * flow.c: Likewise.
+ * function.c: Likewise.
+ * ifcvt.c: Likewise.
+ * integrate.c: Likewise.
+ * jump.c: Likewise.
+ * postreload.c: Likewise.
+ * varray.c: Likewise.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/frontends.texi: Update copyright.
+ * doc/gcov.texi: Likewise.
+ * doc/gty.texi: Likewise.
+ * doc/sourcebuild.texi: Likewise.
+ * doc/standards.texi: Likewise.
+
+2004-01-24 Herman A.J. ten Brugge <hermantenbrugge@home.nl>
+
+ PR target/12978
+ * c4x.md: (movstrqi*) Use match_scratch instead of match_dup.
+ Remove movstrqi_small because it conflicts with movstrqi_large.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/cris/cris.c (TARGET_PROMOTE_FUNCTION_ARGS): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (cris_struct_value_rtx): Likewise.
+ * config/cris/cris.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (CRIS_STACKADJ_REG): Use CRIS_STRUCT_VALUE_REGNUM instead of
+ STRUCT_VALUE_REGNUM.
+ (STRUCT_VALUE_REGNUM): Rename to CRIS_STRUCT_VALUE_REGNUM.
+
+2004-01-24 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR bootstrap/13848
+ * cse.c (cse_cc_succs): Change the mode of the source expression
+ as soon as decide we need a new mode. Don't permit changing modes
+ if we found a match in a successor block.
+ (cse_condition_code_reg): Save original mode of source expression
+ so that we know whether we have to change the mode in other
+ insns.
+
+2004-01-24 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (change_address, adjust_address_1, offset_address,
+ widen_memory_access): Return early when there is nothing to change.
+
+2004-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ * simplify-rtx.c (simplify_relational_operation): Don't
+ simplify address == constant into address + -constant == 0.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcc.c (process_command): Don't internationalize the
+ Copyright message.
+ * mips-tfile.c (main): Likewise.
+
+2004-01-24 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * cse.c: (cse_cc_succs) Fix comparison warning.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Remove extraneous USE in expanders.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Provide prototypes for
+ h8300_legitimate_constant_p and h8300_legitimate_address_p.
+ * config/h8300/h8300.c (h8300_legitimate_constant_p): New.
+ (h8300_rtx_ok_for_base_p): Likewise.
+ (h8300_legitimate_address_p): Likewise.
+ * config/h8300/h8300.h (LEGITIMATE_CONSTANT_P): Use
+ h8300_legitimate_constant_p.
+ (RTX_OK_FOR_BASE_P): Remove.
+ (GO_IF_LEGITIMATE_ADDRESS): Use h8300_legitimate_address_p.
+
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (REG_OK_FOR_INDEX_NONSTRICT_P): New.
+ (REG_OK_FOR_BASE_NONSTRICT_P): Likewise.
+ (REG_OK_FOR_INDEX_STRICT_P): Likewise.
+ (REG_OK_FOR_BASE_STRICT_P): Likewise.
+ (REG_OK_FOR_INDEX_STRICT_P): Use REGNO_OK_FOR_INDEX_P.
+ (REG_OK_FOR_BASE_STRICT_P): Use REGNO_OK_FOR_BASE_P.
+ (REG_OK_FOR_INDEX_P): Use REG_OK_FOR_INDEX_STRICT_P.
+ (REG_OK_FOR_BASE_P): Use REG_OK_FOR_BASE_STRICT_P.
+
+2004-01-24 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (remove_useless_values): Do not access discarded values.
+
+2004-01-24 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (build_conditional_expr): Do not allow non-lvalue
+ arrays.
+
+2004-01-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * recog.c: Fix a typo in copyright.
+
+2004-01-23 Andrew Pinski <apinski@apple.com>
+
+ * config/rs6000/rs6000.md (call): Fix misappiled patch.
+ (call_value): Likewise.
+
+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-23 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_va_arg): Handle complex values as
+ separate real and imaginary parts.
+ * config/xtensa/xtensa.h (SPLIT_COMPLEX_ARGS): Define.
+
+2004-01-23 Hartmut Penner <hpenner@de.ibm.com>
+
+ PR target/13674
+ * config/rs6000/rs6000.md (movdf_hardfloat64): Do not disparage
+ loading into GPR.
+
+2004-01-23 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (change_address_1): Do not re-generate the RTX if nothing
+ change.
+
+ * alloc-pool.c (align_four): Kill.
+ (create_alloc_pool): Align size to eight.
+ (free_alloc_pool, free_pool): Invalidate deallocated data.
+
+2004-01-23 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR gcc/1532
+ * cse.c (cse_change_cc_mode): New static function.
+ (cse_change_cc_mode_insns, cse_cc_succs): Likewise.
+ (cse_condition_code_reg): New function.
+ * rtl.h (cse_condition_code_reg): Declare.
+ * toplev.c (rest_of_handle_cse2): Call cse_condition_code_reg.
+ * target.h (struct gcc_target): Add fixed_condition_code_regs and
+ cc_modes_compatible.
+ * target-def.h (TARGET_FIXED_CONDITION_CODE_REGS): Define.
+ (TARGET_CC_MODES_COMPATIBLE): Define.
+ (TARGET_INITIALIZER): Add new initializers.
+ * targhooks.c (default_cc_modes_compatible): New function.
+ * targhooks.c (default_cc_modes_compatible): Declare.
+ * hooks.c (hook_bool_intp_intp_false): New function.
+ * hooks.h (hook_bool_intp_intp_false): Declare.
+ * config/i386/i386.c (TARGET_FIXED_CONDITION_CODE_REGS): Define.
+ (TARGET_CC_MODES_COMPATIBLE): Define.
+ (ix86_fixed_condition_code_regs): New static function.
+ (ix86_cc_modes_compatible): Likewise.
+ * doc/tm.texi (Condition Code): Document new hooks.
+
+2004-01-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (bad_lval): Renamed to ...
+ (alpha_bad_lval): ... this.
+ Removed file list.
+ Restrict to alpha*-dec-osf*.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/dirent.h: Remove, moving test ...
+ * fixinc/tests/base/testing.h: ... here, reflecting new name.
+
+2004-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/13814
+ * c-decl.c (diagnose_mismatched_decls): Also discard a
+ built-in if we encounter an old-style definition with the
+ same name.
+
+2004-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config.gcc (powerpc*-*): Clear $with_cpu or $with_tune if it was
+ set to default{32,64}.
+
+2004-01-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR)
+ [!__powerpc64__]: Corrected to handle kernels with changed ucontext.
+
+2004-01-23 Eric Botcazou <ebotcazou@act-europe.fr>
+ Olivier Hainque <hainque@act-europe.fr>
+
+ * fold-const.c (fold_binary_op_with_conditional_arg): Only
+ build a COMPOUND_EXPR if 'arg' is really a SAVE_EXPR.
+
+2004-01-23 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/arm/arm.c (arm_legitimate_address_p): Don't check the mode
+ size for minipool references.
+
+2004-01-23 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_floor, real_ceil): Tweak to allow input and output
+ arguments to overlap.
+ (real_round): New function to implement round(3m) semantics.
+ * real.h (real_round): Prototype here.
+ * builtins.c (fold_builtin_round): New function to constant fold
+ round, roundf and roundl.
+ (fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}.
+
+2004-01-23 Alexandre Oliva <aoliva@redhat.com>
+
+ PR optimization/13819
+ * config/sh/sh.c (sh_reorg): Compensate for sharing of CLOBBERs
+ introduced by 2004-01-20's Jan Hubicka's copy_insn change.
+ (sh_handle_sp_switch_attribute): Remove warning.
+
+2004-01-23 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_emit_restore_regs_using_mov): Deal with large offsets.
+
+2004-01-23 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * doc/tm.texi: Insert some weasel words when LOAD_EXTEND_OP
+ may or may not return non-NIL.
+ * postreload.c (reload_cse_simplify_operands): In LOAD_EXTEND_OP code,
+ check CANNOT_CHANGE_MODE_CLASS
+
+2004-01-23 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (PROP_POSTRELOAD): New macro.
+ (CLEANUP_LOG_LINKS): New.
+ * cfgcleanup.c (cleanup_cfg): Only PROP_LOG_LINKS when asked to.
+ * toplev.c (rest_of_handle_life): Preserve LOG_LINKS trought cleanup_cfg.
+
+ * cselib.c (value_pool): New.
+ (new_cselib_val): Use pool.
+ (cselib_init): Initialize value_pool
+ (cselib_finish): Free pool.
+
+2004-01-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (scan_record_type): New function.
+ (function_arg_slotno): Use it to determine which kinds of
+ registers the record can be passed in.
+
+2004-01-22 James A. Mmorrison <ja2morri@uwaterloo.ca>
+
+ * config/pa/fptr.c: Fix old-style definition.
+
+2004-01-22 Paolo Bonzini <bonzini@gnu.org>
+
+ PR optimization/13724
+ * cse.c (fold_rtx) <SUBREG>: Fold a SUBREG to zero if it
+ represents the zero bits produced by a ZERO_EXTEND operation.
+
+2004-01-22 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/13821
+ * simplify-rtx.c (simplify_subreg): Use subreg_lowpart_offset to
+ correctly calculate the lowpart offset of the contracted subreg.
+
+2004-01-22 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * doc/invoke.texi (Optimize Options): Note that --param arguments
+ are subject to change without notice.
+
+2004-01-22 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (mips-sgi-irix6*o32): Removed.
+ * config/mips/iris6-o32-as.h: Likewise.
+ * config/mips/iris6-o32-gas.h: Likewise.
+ * config/mips/iris6-o32.h: Likewise.
+
+2004-01-22 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (first_pass): New static variable.
+ (try_forward_edges): Add work limiting check for threading.
+ (try_crossjump_bb): Add work limiting check for crossjumping.
+ (try_optimize_cfg): Maintain first pass variable.
+
+2004-01-22 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (function_arg): Generalize logic so that it
+ handles complex and vector modes.
+
+2004-01-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (REG_OK_FOR_INDEX_P_STRICT): Remove.
+ (REG_OK_FOR_BASE_P_STRICT): Likewise.
+ (STRICT): Likewise.
+
+2004-01-22 Daniel Jacobowitz <drow@mvista.com>
+
+ * c-semantics.c (genrtl_while_stmt, genrtl_do_stmt_1)
+ (genrtl_for_stmt): Remove emit_nop calls.
+
+2004-01-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/13713
+ PR target/13324
+ * pa.md (movstrsi_prereload, movstrsi_postreload, movstrdi_prereload,
+ movstrdi_postreload, clrstrsi_prereload, clrstrsi_postreload,
+ clrstrdi_prereload, clrstrdi_postreload): Fix constraints.
+
+2004-01-22 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/arm/arm.c: Include "debug.h".
+ (thumb_pushpop): Take two new arguments. Add some commentary.
+ Output frame information when pushing.
+ (thumb_exit, thumb_unexpanded_epilogue): Update calls to
+ thumb_pushpop.
+ (thumb_output_function_prologue): Likewise. Accumulate a CFA
+ offset, and pass it to thumb_pushpop. Output CFI information.
+ (thumb_expand_prologue): Add some frame-related markers and notes.
+
+2004-01-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_frame_info): Allow large frame sizes
+ for TARGET_64BIT.
+ (s390_arg_frame_offset): Change return type to HOST_WIDE_INT.
+ * config/s390/s390-protos.h (s390_arg_frame_offset): Likewise.
+
+2004-01-22 Roger Sayle <roger@eyesopen.com>
+ Paolo Bonzini <bonzini@gnu.org>
+
+ * rtlanal.c (subreg_lsb_1): New function split out from subreg_lsb.
+ (subreg_lsb): Change to call new subreg_lsb_1 helper function.
+ * rtl.h (subreg_lsb_1): Prototype here.
+ * simplify-rtx.c (simplify_subreg): Optimize subregs of zero and
+ sign extensions.
+
+2004-01-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi (CASE_VECTOR_PC_RELATIVE): Mention that the
+ macro need not be defined if jump-tables should contain
+ relative addresses only when -fPIC or -fPIC is in effect.
+
+2004-01-22 Jan Hubicka <jh@suse.cz>
+
+ * alias.c (reg_base_value): Turn into varray.
+ (reg_base_value_size): Kill.
+ (old_reg_base_value): New deletable varray.
+ (alias_invariant_size): New variable.
+ (REG_BASE_VALUE): Update to use varray.
+ (find_base_value): Likewise.
+ (record_set): Likewise.
+ (record_base_value): Likewise.
+ (memrefs_conflict_p): Likewise.
+ (record_set): Likewise
+ (record_base_value): Likewise.
+ (memrefs_conflict_p): Use alias_invariant_size.
+ (init_alias_analysis): Use varray; set alias_invariant_size;
+ rescale other arrays to be sized by maxreg.
+ (end_alias_analysis): Save reg_base_value; clear alias_invariant_size.
+
+2004-01-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_slotno): Use
+ FLOAT_TYPE_P to detect FP fields in structures.
+ (function_arg_record_value_1): Likewise.
+ (function_arg_record_value_2): Likewise.
+
+2004-01-22 Jan Hubicka <jh@suse.cz>
+
+ * function.c (allocate_struct_function): Do not initialize expr, emit
+ and varasm.
+ (prepare_function_start): Do it here.
+ * c-parse.in (maybe_type_qual): Do not produce line number notes.
+
+2004-01-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/13559
+ * config/sparc/sparc.c (function_arg_record_value_3): Revert
+ to 'word_mode' once the first slot has been filled.
+
+2004-01-22 Olivier Hainque <hainque@act-europe.fr>
+
+ * config/sparc/sparc.c (function_arg_record_value_1): Fix
+ computation of the number of integer registers required.
+
+2004-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.md: Simplify certain comparisons of
+ const_int.
+
+2004-01-21 Andrew Pinski <apinski@apple.com>
+
+ PR target/13785
+ * config/rs6000/rs6000.md (call_value): Force operand
+ 1 not operand 0 into a register.
+
+2004-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cpperror.c, cpptrad.c, longlong.h, params.def, rtl.def,
+ unwind-dw2-fde.h: Update copyright.
+
+2004-01-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-protos.h: Update copyright.
+ * pa.h: Likewise.
+ * pa.md: Likewise.
+
+2004-01-21 Caroline Tice <ctice@apple.com>
+
+ PR target/12308
+ * config/i386/i386.md (fix_truncxfdi2): Add clause to clobber
+ flags register.
+ (fix_truncdfdi2): Likewise.
+ (fix_truncsfdi2): Likewise.
+ (*fix_truncdi_1): Likewise.
+ (fix_truncxfsi2): Likewise.
+ (fix_truncdfsi2): Likewise.
+ (fix_truncsfsi2): Likewise.
+ (*fix_truncsi_1): Likewise.
+ (fix_truncxfhi2): Likewise.
+ (fix_truncdfhi2): Likewise.
+ (fix_truncsfhi2): Likewise.
+ (*fix_trunchi_1): Likewise.
+
+2004-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c, basic-block.h, c-common.c, c-common.h,
+ c-cppbuiltin.c, c-opts.c, c-pragma.c, c-pretty-print.c,
+ calls.c, cfg.c, cfgcleanup.c, cfgrtl.c, cgraph.h, collect2.c,
+ combine.c, cppcharset.c, cpphash.h, cppinit.c, cpplib.c,
+ cpplib.h, cppmacro.c, crtstuff.c, cselib.c, cselib.h,
+ defaults.h, df.c, dominance.c, et-forest.c, expmed.c, expr.c,
+ expr.h, fix-header.c, function.h, gcc.c, gcse.c, genattrtab.c,
+ genautomata.c, genconditions.c, genemit.c, genflags.c,
+ gengtype.c, gengtype.h, genopinit.c, genrecog.c, gensupport.c,
+ ggc-zone.c, graph.c, haifa-sched.c, input.h, integrate.c,
+ langhooks-def.h, langhooks.c, langhooks.h, line-map.c,
+ line-map.h, local-alloc.c, optabs.c, optabs.h, postreload.c,
+ ra.h, recog.c, reg-stack.c, regmove.c, reload.c, reorg.c,
+ rtl.c, sched-deps.c, sched-ebb.c, sdbout.c, system.h,
+ target.h, targhooks.c, toplev.h, tree-inline.c, unwind-pe.h,
+ unwind.h, varray.c, varray.h: Update copyright.
+
+2004-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/coff.h: Update copyright.
+ * config/h8300/elf.h: Likewise.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+
+2004-01-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * fixinc/inclhack.def (hpux10_stdio_declarations, ultrix_const3,
+ ultrix_locale, ultrix_stdlib, ultrix_strings, ultrix_sys_time,
+ ultrix_unistd): New hacks.
+ * fixinc/tests/base/stdio.h (HPUX10_STDIO_DECLARATIONS_CHECK,
+ ULTRIX_CONST2_CHECK): Add checks.
+ * fixinc/tests/base/stdlib.h (ULTRIX_STDLIB_CHECK): Likewise.
+ * fixinc/tests/base/strings.h (ULTRIX_STRINGS2_CHECK): Likewise.
+ * fixinc/tests/base/unistd.h (ULTRIX_UNISTD_CHECK): Likewise.
+ * fixinc/tests/base/sys/time.h (ULTRIX_SYS_TIME_CHECK): Likewise.
+ * fixinc/tests/base/locale.h: New file.
+ * fixinc/fixincl.x: Rebuilt.
+
+2004-01-21 Andreas Jaeger <aj@suse.de>
+ Michael Matz <matz@suse.de>
+
+ * doc/extend.texi (Extended Asm): Clarify memory clobber.
+
+2004-01-21 Jakub Jelinek <jakub@redhat.com>
+
+ * crtstuff.c (frame_dummy, __do_global_ctors_1): Call
+ _Jv_RegisterClasses through a function pointer.
+
+2004-01-21 Falk Hueffner <falk@debian.org>
+
+ PR target/12898
+ * config/alpha/alpha.c (alpha_emit_set_const_1): If
+ no_new_pseudos, use gen_rtx_SET directly for SImode constants
+ which need multiple instructions to emit.
+
+2004-01-21 Inaoka Kazuhiro <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (CPP_SPEC): Define.
+
+2004-01-21 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (merge_decls): Kill different_binding_level and
+ different_tu arguments; simplify throughout.
+ (duplicate_decls): Likewise.
+ (pushdecl, merge_translation_unit_decls): Update calls to
+ duplicate_decls.
+
+2004-01-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (pretty-print.o): Depend on $(CONFIG_H) and
+ $(SYSTEM_H).
+ (print-rtl1.o): Depend on $(SYSTEM_H).
+
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ PR bootstrap/12730
+ * configure.ac: Delete definition and subsitution of docdir.
+ Add info, man, srcman and srcinfo to target hooks. Create doc/
+ directory.
+ * configure: Regenerate.
+ * Makefile.in: Don't substitute docdir and delete all references
+ throughout.
+ (MAKEINFOFLAGS): Define.
+ (stmp-docobjdir): Delete.
+ (INFOFILES, MANFILES): Define.
+ (info): Call lang.info, srcinfo and lang.srcinfo.
+ (generated-manpages): Call lang.man, srcman and lang.srcman.
+ (srcinfo, srcman): New rules to copy back files to source directory.
+ (doc/%.info, doc/%.dvi, doc/%.1, doc/%.7): New implict rule.
+ (install-man): Revamp rule.
+ (clean): Update dvi directory.
+ (distclean): Delete TAGS from front end directorys.
+ (maintainer-clean): Delete all document files in source directory.
+
+ objc/Make-lang.in (objc.man, objc.info): Dummy entries.
+ (objc.srcman, objc.srcinfo): Likewise.
+
+2004-01-20 Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/inclhack.def(math_exception): bypass only for glibc.
+ (matherr_decl): rename & relocate as exception_structure.
+ This fix must precede the math_exception fix.
+
+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.
+
+2004-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/sysv4.h (DWARF2_FRAME_REG_OUT): Define.
+ * dwarf2out.c (output_cfi): Map regs using DWARF2_FRAME_REG_OUT.
+ * doc/tm.texi (DWARF_FRAME_REGNUM, DWARF2_FRAME_REG_OUT): Document.
+
+2004-01-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-protos.h (compute_frame_size): Use HOST_WIDE_INT for frame sizes.
+ * pa.c (store_reg, store_reg_modify, load_reg, set_reg_plus_d):
+ Likewise. Handle frames larger than 0x7fffffff on 64-bit ports.
+ (emit_move_sequence): Check scratch_reg first in various if statements.
+ Extend source simplification to handle all 64-bit CONST_INTs.
+ (pa_output_function_prologue): Use HOST_WIDE_INT_PRINT_DEC for printing
+ frame size.
+ (hppa_expand_prologue, hppa_expand_epilogue): Use HOST_WIDE_INT for
+ frame offset calculations.
+ * pa.h (NEW_HP_ASSEMBLER): Add comment.
+ (MAX_LEGIT_64BIT_CONST_INT, MIN_LEGIT_64BIT_CONST_INT,
+ LEGITIMATE_64BIT_CONST_INT_P): Define.
+ (LEGITIMATE_CONSTANT_P): Use LEGITIMATE_64BIT_CONST_INT_P. Treat
+ any CONST_INT as legitimate during and after reload.
+ (VAL_32_BITS_P, INT_32_BITS): Define.
+ (LEGITIMIZE_RELOAD_ADDRESS): Handle large frame offsets.
+
+2004-01-20 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (verify_rtx_sharing, copy_insn_1,
+ emit_copy_of_insn_after, emit_copy_of_insn_after): Clobbers
+ containing hard regs are shared.
+ (gen_hard_reg_clobber): New function.
+ (hard_reg_clobbers): New array.
+ * genemit.c (gen_exp): Use gen_hard_reg_clobber.
+ (copy_rtx): Do not copy clobbers containing hard regs.
+ * rtl.h (gen_hard_reg_clobber): Declare.
+
+2004-01-20 Jan Hubicka <jh@suse.cz>
+
+ * varray.c: Include hashtab.h
+ (varray_descriptor): New structure.
+ (hash_descriptor, eq_descriptor, varray_descriptor,
+ print_statistics): New static functions
+ (varray_init, varray_grow): Update statistics
+ (dump_varray_statistics): New function.
+ * varray.h (dump_varray_statistics): Declare.
+ * toplev.c (finalize): Call it.
+ * Makefile.in (varray.o): Add dependency.
+
+2004-01-20 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c: Include alloc-pool.h
+ (empty_vals, empty_elt_lists, empty_elt_loc_lists): Kill.
+ (elt_loc_list_pool, elt_list_pool, cselib_val_pool): Declare.
+ (new_elt_list, new_elt_loc_list, unchain_one_elt_list,
+ unchain_one_elt_loc_list_pool, unchain_one_value,
+ new_cselib_val): Simplify using allocpool.
+ (cselib_init): Initialize allocpools.
+ (cselib_finish): Finish allocpools.
+ * Makefile.in (cselib.o): Depend on alloc-pool.h
+
+2004-01-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_load_call_address): Make the call insn
+ use $gp if it could be calling a lazy binding stub.
+
+2004-01-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/s390/s390.c (TARGET_PROMOTE_FUNCTION_ARGS): Define.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Likewise.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ * config/s390/s390.h (PROMOTE_FUNCTION_ARGS): Remove.
+ (PROMOTE_FUNCTION_RETURN): Remove.
+ (STRUCT_VALUE): Remove.
+
+2004-01-20 Denis Chertykov <denisc@overta.ru>
+
+ PR bootstrap/13735
+ * config/avr/avr.h (BASE_REG_CLASS): Don't permit to use X
+ register as pointer after reload.
+
+2004-01-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/12440
+ * loop.c: Include ggc.h.
+ (loop_optimize): Run garbage collector between optimization of loops.
+ * Makefile.in (loop.o): Add GGC_H dependency.
+
+2004-01-20 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (function_arg) Handle
+ vector register special in function without prototype.
+ (function_arg_advance): Vector parameters get always
+ GPRs allocated for the linux64 target.
+
+2004-01-20 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (TARGET_M32R2). Test for TARGET_M32R2_MASK
+ not TARGET_M32RX_MASK.
+
+2004-01-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/13557
+ * config/sparc/sparc.c (function_arg): Reorder the cases.
+
+2004-01-19 Per Bothner <per@bothner.com>
+
+ Move cpp_reader's line_maps field to a shared global.
+ * cpphash.h (cpp_reader): Rename line_maps field to line_table
+ and change the type to a pointer rather than a struct.
+ * cppinit.c (cpp_push_main_field): Adjust accordingly.
+ * cpplib.c (do_include_common, _cpp_do_file_change, cpp_get_callbacks):
+ Likewise.
+ * cppfiles.c (validate_pch): Likewise.
+ * cppmacro.c (_cpp_warn_if_unused_macro, _cpp_builtin_macro_text):
+ Likewise.
+ * cpperror.c (print_location): Likewise.
+ * cpplib.h (cpp_create_reader): New line_maps pointer parameter.
+ * cppinit.c (cpp_create_reader): Handle new parameter.
+ (cpp_destroy): Don't free line_maps - that's no longer our job.
+ * input.h (line_table): New variable.
+ * toplev.c (line_table): Declare variable.
+ (general_init): Initialize line_table.
+ * c-opts.c (c_common_init_options): Pass line_table to
+ cpp_create_reader.
+ * fix-header.c (read_scan_file): New local variable line_table.
+ Initialize, and pass it to cpp_create_reader.
+ * Makefile.in (LIBS, LIBDEPS): Add libcpp.a.
+ (C_AND_OBJC_OBJS, fix-header): Remove redundant libcpp.a.
+
+2004-01-19 Per Bothner <per@bothner.com>
+
+ Implement a cache for linemap_lookup.
+ * line-map.h (struct_line_maps): Add cache field.
+ * line-map.c (linemap_init): Zero cache field.
+ (linemap_add): Set cache field to offset of newly allocated map.
+ (linemap_lookup): Use and set cache field.
+
+2004-01-20 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR optimization/13567
+ * cse.c (cse_basic_block): Call cse_insn with a non-null
+ libcall_insn for the last SET insn of a no-confilict block.
+
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (target_noncanonical, program_transform_name): Use
+ immediate define instead of deferred.
+ (GCC_INSTALL_NAME, GCC_TARGET_INSTALL_NAME, CPP_INSTALL_NAME,
+ PROTOIZE_INSTALL_NAME, UNPROTOIZE_INSTALL_NAME, GCOV_INSTALL_NAME,
+ GCCBUG_INSTALL_NAME): Define via a immediate $(shell) instead of
+ deferred backquote.
+
+2004-01-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-decl.c (c_init_decl_processing): Set pedantic_lvalues to
+ true unconditionally.
+ * c-typeck.c (unary_complex_lvalue, pedantic_lvalue_warning):
+ Remove.
+ (build_unary_op, build_modify_expr): Don't handle extended
+ lvalues.
+ (build_component_ref, build_conditional_expr): Call non_lvalue
+ instead of pedantic_non_lvalue.
+ (build_c_cast): Don't condition use of non_lvalue on pedantic.
+ * fold-const.c (fold): Don't check pedantic directly for
+ COMPOUND_EXPR. Ensure that results for COMPOUND_EXPR are
+ passed to pedantic_non_lvalue.
+ * doc/extend.texi: Remove documentation of extended lvalues.
+
+2004-01-19 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/5263
+ * simplify-rtx.c (associative_constant_p): Delete.
+ (simplify_associative_operation): Rewrite to linearize terms, and
+ attempt to simplify new term against both left and right subterms.
+ (simplify_binary_operation): Call swap_commutative_operands_p on
+ op0 and op1, not trueop0 and trueop1. Move the initialization of
+ trueop0 and trueop1 down to where first needed.
+ (simplify_relational_operation): Likewise.
+ * rtlanal.c (commutative_operand_precedence): Also order constant
+ operands using avoid_constant_pool_reference.
+
+2004-01-19 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (aligned_memory_operand): Check MEM_ALIGN,
+ don't check memory mode.
+ (unaligned_memory_operand): Likewise.
+ (reload_inqi, reload_inhi, reload_outqi, reload_outhi): Don't
+ abort for op0 not MEM.
+
+ * config/alpha/alpha.c (alpha_expand_mov_nobwx): If the destination
+ is not a reg, copy to a scratch first.
+ (aligned_loadqi, aligned_loadhi, unaligned_loadqi, unaligned_loadhi,
+ unaligned_loadqi_le, unaligned_loadqi_be, unaligned_loadhi_le,
+ unaligned_loadhi_be): Expect op0 in DImode; don't SUBREG.
+ (reload_inqi, reload_inhi): Fix mode of op0.
+ (reload_inqi_help, reload_inhi_help, reload_outqi_help,
+ reload_outhi_help): Likewise. Use define_insn_and_split.
+
+ * config/alpha/alpha.md (call peepholes): Check for REG_NORETURN
+ as well as $29 dead.
+
+2004-01-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sol2.h (ASM_DECLARE_OBJECT_NAME): New. Emit
+ "tls_object" for thread-local objects.
+ * config/sparc/sparc.c (sparc_elf_asm_named_section): Emit
+ "#tls" for thread-local sections.
+ * configure.ac (thread-local checks): Specify --fatal-warnings in
+ every binutils-specific checks. For sparc*-*-*, test whether the
+ OS is Solaris and the tools are native and act accordingly.
+ * configure: Rebuild.
+
+2004-01-19 Jeff Law <law@redhat.com>
+
+ * contrib.texi: Update Paolo Carlini's entry. New entries for
+ Jerry Quinn and Petur Runolfsson.
+
+2004-01-19 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.md (*movhi_1, *movqi_1): When optimizing for
+ size, don't use the larger zero-extending loads.
+
+2004-01-19 Richard Henderson <rth@redhat.com>
+
+ * alpha.h (HARD_REGNO_MODE_OK): Disallow SImode in FP regs.
+ * alpha.md (UNSPEC_NT_LDA): Remove.
+ (UNSPEC_CVTLQ, cvtlq): New.
+ (extendsidi2_1): Rename from extendsidi2_nofix; remove f/f.
+ (extendsidi2_fix): Remove.
+ (extendsidi2 splitter): Use cvtlq.
+ (extendsidi2 fp peepholes): Remove.
+ (cvtql): Use SFmode instead of SImode.
+ (fix_trunc?fsi): Update to match.
+ (floatsisf2_ieee, floatsisf2, floatsidf2_ieee, floatsidf2): New.
+ (movsi): Rename from movsi_nofix, remove f alternatives.
+ (movsi_nt_vms): Similarly.
+ (movsi_fix, movsi_nt_vms_fix): Remove.
+ (nt_lda): Remove.
+ * alpha.c (alpha_expand_prologue): Use adddi3, not nt_lda.
+
+2004-01-19 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_remove_node): Fix removal from linked list.
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Clear next_needed
+ list.
+ (cgraph_remove_unreachable_nodes): New function
+ (cgraph_decide_inlining_of_small_function): Fix pasto.
+ (cgraph_decide_inlining_incrementally): Fix pasto.
+ (cgrpah_decide_inlining): Likewise; remove unreachable nodes.
+
+2004-01-19 Steven Bosscher <stevenb@suse.de>
+
+ * gengtype.c (header_file): Make it static.
+ (write_types_process_field, write_enum_defn): Minor whitespace fixes.
+ * gengtype.h (header_file): No longer extern.
+
+2004-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * defaults.h (CASE_VECTOR_PC_RELATIVE): Provide the default.
+ * expr.c (CASE_VECTOR_PC_RELATIVE): Remove.
+ * stmt.c (CASE_VECTOR_PC_RELATIVE): Likewise.
+
+2004-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * stmt.c (HAVE_casesi): Define it not already defined.
+ (HAVE_tablejump): Likewise.
+ (expand_end_case_type): Resort to the binary tree method if
+ neither casesi or tablejump is available.
+
+2004-01-18 Daniel Jacobowitz <drow@mvista.com>
+
+ * final.c (final_scan_insn): Make non-static again.
+ * output.h (final_scan_insn): Re-add prototype.
+ * config/arc/arc.c (arc_output_function_epilogue): Add NULL
+ to final_scan_insn call.
+ * config/cris/cris.c (cris_target_asm_function_epilogue): Likewise.
+ * config/mips/mips.c (mips_output_conditional_branch): Likewise.
+ * config/pa/pa.c (output_lbranch, output_call): Likewise.
+ * config/sh/sh.c (print_slot): Likewise.
+ * config/sparc/sparc.c (sparc_nonflat_function_epilogue): Likewise.
+ (output_sibcall, sparc_flat_function_epilogue): Likewise.
+
+2004-01-18 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (try_redirect_by_replacing_jump): Declare.
+ * cfgcleanup.c (try_optimize_cfg): Use it.
+ * cfgrtl.c (try_redirect_by_replacing_jump): Export.
+ (rtl_redirect_edge_and_branch, cfg_layout_redirect_edge_and_branch):
+ Kill hack.
+ (cfg_layout_merge_blocks): Use try_redirect_by_replacing_jump.
+
+ Revert:
+ 2004-01-16 Geoffrey Keating <geoffk@apple.com>
+
+ * cfgrtl.c (try_redirect_by_replacing_jump): Optimize tablejumps
+ even after reload, just don't remove the actual jump tables.
+
+2004-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/rs6000/rs6000.h (STRICT_ARGUMENT_NAMING): Remove.
+
+2004-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * defaults.h (ASM_OUTPUT_ADDR_VEC_ELT): Fix the computation of
+ the size of a pointer in bytes.
+
+2004-01-18 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_expect_jump): Fix thinko of reusing
+ live "next" variable, which could lead to an infinite loop.
+
+2004-01-18 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/altivec.h: Wrap C++ functions in extern "C++"
+ block.
+
+ * config/rs6000/rs6000.c (rs6000_special_round_type_align):
+ Check for NULL in the chain and remove repeated code.
+
+2004-01-18 Jan Hubicka <jh@suse.cz>
+
+ * coverage.c (checksum_string): Rename to ...
+ (coverage_checksum_string): ... this one, Use crc32_string; recognize
+ names containing random number and zero the number out in order to get
+ match.
+
+2004-01-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_got_alias_set): Mark for PCH.
+
+2004-01-18 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/c-tree.texi, doc/cpp.texi, doc/extend.texi,
+ doc/frontends.texi, doc/gcov.texi, doc/gty.texi, doc/install.texi,
+ doc/invoke.texi, doc/libgcc.texi, doc/md.texi, doc/rtl.texi,
+ doc/sourcebuild.texi, doc/standards.texi, doc/tm.texi,
+ doc/trouble.texi: Remove trailing whitespace.
+
+2004-01-18 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/7618
+ * config/mips/mips.c: Include cfglayout.h.
+ (TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): Define.
+ (mips_unspec_offset_high): Add temporary register argument.
+ (mips_load_call_address): New function, split out from...
+ (mips_expand_call): ...here.
+ (mips_output_cplocal): New function.
+ (mips_output_function_prologue, mips_output_function_epilogue): Use it.
+ (mips_emit_loadgp): New function, split out from...
+ (mips_expand_prologue): ...here.
+ (mips_output_mi_thunk): New function.
+
+2004-01-17 Bernardo Innocenti <bernie@develer.com>
+
+ * longlong.h (mc68020, __mc68030__, mc68030, __mc68040__, mc68040,
+ mcpu32): Remove redundant checks for implied target predefines.
+
+2004-1-17 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (rs6000_special_round_type_align):
+ Return type is unsigned int not int.
+ * config/rs6000/rs6000-protos.h (rs6000_special_round_type_align):
+ Likewise.
+
+2004-01-18 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/contrib.texi, doc/cppenv.texi, doc/extend.texi,
+ doc/install.texi, doc/invoke.texi, doc/tm.texi: Consistently use
+ "GNU/Linux" and "Microsoft Windows" terminology.
+
+2004-01-18 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/c-tree.texi, doc/compat.texi, doc/cpp.texi,
+ doc/cppopts.texi, doc/extend.texi, doc/install.texi,
+ doc/interface.texi, doc/invoke.texi, doc/libgcc.texi, doc/md.texi,
+ doc/objc.texi, doc/rtl.texi, doc/tm.texi, doc/trouble.texi: Use
+ @smallexample instead of @example.
+
+2004-01-17 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (build_objc_method_call): Use target
+ hooks instead of macros to determine if ..._stret
+ dispatchers should be used (NeXT runtime only).
+
+2004-01-17 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_expect_jump): Fix mistake in my
+ last patch. Use XEXP (x, 0) to get a LABEL_REF's CODE_LABEL.
+
+2004-01-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * rtl.h (emit_insn_before_sameloc, emit_jump_insn_before_sameloc)
+ (emit_call_insn_before_sameloc, emit_insn_after_sameloc)
+ (emit_jump_insn_after_sameloc, emit_call_insn_after_sameloc): New
+ macros.
+ * reload1.c (emit_reload_insns): Use them.
+ * emit-rtl.c (emit_insn_before_sameloc, emit_insn_after_sameloc)
+ (emit_jump_insn_after_sameloc, emit_call_insn_after_sameloc): Check
+ for NULL PATTERN.
+
+2004-01-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * final.c (SEEN_BB, SEEN_NOTE, SEEN_EMITTED): Define.
+ (final_scan_insn): Update to take an additional SEEN argument. Emit
+ a line note after the prologue. Make static.
+ (line_note_exists): Remove.
+ (final): Don't initialize line_note_exists. Update call to
+ final_scan_insn.
+ * output.h (final_scan_insn): Remove prologue.
+ * function.c (set_insn_locators): Update comment.
+ (thread_prologue_and_epilogue_insns): Add a comment.
+
+2004-01-17 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/10781
+ * config/rs6000/rs6000-protos.h (rs6000_special_round_type_align):
+ Prototype.
+ * config/rs6000/rs6000.c (rs6000_special_round_type_align):
+ New function.
+ * config/rs6000/linux64.h (ROUND_TYPE_ALIGN): Use it.
+ * config/rs6000/aix.h (ROUND_TYPE_ALIGN): Likewise.
+ * config/rs6000/darwin.h (ROUND_TYPE_ALIGN): Likewise.
+
+2004-01-17 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_handle_reorder_blocks): Fix pasto in previous
+ commit.
+
+ * toplev.c (HAVE_conditional_execution): Provide default.
+ (rest_of_handle_reorder_blocks): For conditional_execution target
+ update liveness once after all transformations
+ (rest_of_compilation): Do crossjumping before ce3.
+
+2004-01-17 Geoffrey Keating <geoffk@apple.com>
+
+ * alias.c (new_alias_set): Mark last_alias_set for PCH.
+ (get_varargs_alias_set): Rename 'set' to 'varargs_set' and mark it
+ for PCH.
+ (get_frame_alias_set): Likewise, except rename it to 'frame_set'.
+ * config/rs6000/rs6000.c (rs6000_sr_alias_set): Mark for PCH.
+ (get_TOC_alias_set): Mark 'set' for PCH.
+
+2004-01-16 Geoffrey Keating <geoffk@apple.com>
+
+ * cfgrtl.c (try_redirect_by_replacing_jump): Optimize tablejumps
+ even after reload, just don't remove the actual jump tables.
+
+2004-01-17 J. Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (is_subrange_type): Renamed from is_ada_subrange_type().
+ Remove checks for is_ada() and TREE_UNSIGNED.
+ (subrange_type_die): Emit a byte_size attribute if the subrange
+ type size is different from the base type size.
+ (modified_type_die): Replace call to is_ada_subrange_type() by
+ call to is_subrange_type().
+
+2004-01-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/sh/sh.c: Include ggc.h.
+
+2004-01-16 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (MD5_H): New.
+ (fold-const.o): Depend on md5.h.
+ (dwarf2out.o): Likewise.
+ (cppfiles.o): Likewise.
+ * cppfiles.c: Include md5.h.
+ (should_stack_file): Check against list read from PCH file.
+ (struct pchf_data): New.
+ (pchf): New variable.
+ (struct pchf_adder_info): New.
+ (pchf_adder): New.
+ (pchf_save_compare): New.
+ (_cpp_save_file_entries): New.
+ (_cpp_read_file_entries): New.
+ (struct pchf_compare_data): New.
+ (pchf_compare): New.
+ (check_file_against_entries): New.
+ * cpphash.h (_cpp_save_file_entries): Prototype.
+ (_cpp_read_file_entries): Prototype.
+ * cpppch.c (cpp_write_pch_state): Write the list of headers.
+ (cpp_read_state): Read the list of headers.
+
+2004-01-17 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (c_estimate_num_insns_1): Handle builtin_constant_p and
+ builtin_expect specially.
+ * params.def (PARAM_MAX_INLINE_INSNS_AUTO): Set to 100.
+ (PARAM_LARGE_FUNCTION_INSNS): Set to 3000.
+ * invoke.texi (max-inline-insns-single): Set to 100.
+ (large-function-insns): Set to 3000.
+
+2004-01-16 Eric Christopher <echristo@redhat.com>
+ Chandrakala Chavva <cchavva@redhat.com>
+
+ * cppcharset.c (one_iso88591_to_utf8): New function.
+ (convert_iso88591_utf8): Ditto. Use.
+ (conversion_tab): Use.
+ (_cpp_input_to_utf8): New function.
+ (_cpp_init_iconv_buffer): Ditto.
+ (_cpp_close_iconv_buffer): Ditto.
+ * cpphash.h: Prototype new functions.
+ (cpp_buffer): Add input_cset_desc.
+ * cppinit.c: Add input_charset default.
+ * cpplib.c (cpp_push_buffer): Support init and
+ close of iconv.
+ * cpplib.h (cpp_options): Add input_charset.
+
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (ASM_OUTPUT_SECTION_NAME): Poison.
+ * config/alpha/unicosmk.h: Remove a commented-out definition
+ of ASM_OUTPUT_SECTION_NAME.
+ * config/stormy16/stormy16.h: Likewise.
+
+2004-01-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (alpha___extern_prefix): Renamed to ...
+ (alpha___extern_prefix_sys_stat): ... this.
+ Apply to <sys/mount.h>, too.
+ Tweak to match more variations.
+ * fixinc/tests/base/sys/stat.h: Adapt for new hackname.
+
+ * fixinc/inclhack.def (alpha___extern_prefix,
+ alpha___extern_prefix_standards): New hacks to obey
+ __PRAGMA_EXTERN_PREFIX.
+ * fixinc/tests/base/testing.h [ALPHA___EXTERN_PREFIX_CHECK]: New
+ test.
+ * fixinc/tests/base/standards.h: Likewise.
+
+ * fixincl/inclhack.def (alpha_pthread): Tweak to match more
+ variations.
+ New testcase.
+ * fixinc/tests/base/pthread.h: Handle it.
+
+ * fixincl/inclhack.def (bad_lval): Sort file list.
+ Add many missing files up to Tru64 UNIX V5.1B.
+ * gcc/fixinc/tests/base/libgen.h: Renamed to ...
+ * gcc/fixinc/tests/base/dirent.h: ... this to match new file list
+ order.
+
+ * fixinc/fixincl.x: Regenerate.
+
+2004-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * version.c (version_string): Change to 3.5.0.
+ * doc/include/gcc-common.texi (version-GCC): Likewise.
+
+2004-01-16 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (load_tp_di): Fix pasto.
+
+ PR opt/13608
+ * i386.c (ix86_compute_frame_layout): Fix for alloca on leaf function.
+
+ * c-pretty-print.c (pp_c_type_cast, pp_c_abstract_declarator,
+ pp_c_character_constant, pp_c_floating_constant,
+ pp_c_additive_expression, pp_c_shift_expression,
+ pp_c_equality_expression, pp_c_and_expression,
+ pp_c_exclusive_or_expression, pp_c_inclusive_or_expression,
+ pp_c_logical_and_expression): Remove inline modifier.
+ * dwarf2out.c (get_AT): Likewise.
+ * et-forest.c (et_splay): Likewise.
+ * ra.h (ra_alloc, ra_calloc): Likewise
+
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/frv/frv-protos.h: Fix comment formatting.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/frv/frv.md: Likewise.
+ * config/frv/frvbegin.c: Likewise.
+ * config/frv/frvend.c: Likewise.
+
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (LINKER_DOES_NOT_WORK_WITH_DWARF2): Poison.
+ * doc/tm.texi (PREFERRED_DEBUGGING_TYPE): Don't mention
+ LINKER_DOES_NOT_WORK_WITH_DWARF2.
+ (LINKER_DOES_NOT_WORK_WITH_DWARF2): Remove.
+
+2004-01-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR 11864
+ * postreload.c (reload_cse_simplify_operands): Don't remove
+ implicit extension from LOAD_EXTEND_OP.
+
+2004-01-16 Jan Hubicka <jh@suse.cz>
+
+ PR opt/11350
+ * cfgcleanup.c (try_optimize_cfg): Suppress tablejump removal
+ after reload.
+ * cfgrtl.c (rtl_can_merge_blocks, cfglayout_can_merge_blocks,
+ rtl_try_redirect_by_replacing_branch): Likewise.
+
+2004-01-15 Geoffrey Keating <geoffk@apple.com>
+
+ PR pch/13689
+ * alias.c (struct alias_set_entry): Mark for GC.
+ (alias_sets): Make static, mark for GC.
+ (record_alias_subset): Use GC to allocate alias structures.
+ * varray.c (element): Make generic varrays GCed.
+
+ PR pch/13361
+ * c-typeck.c (constructor_asmspec): Delete.
+ (struct initializer_stack): Delete field 'asmspec'.
+ (start_init): Delete saving of asmspec.
+ (finish_init): Don't update constructor_asmspec.
+ * dwarf2out.c (rtl_for_decl_location): Duplicate string from tree.
+ * stmt.c (expand_asm): Duplicate strings from tree.
+ (expand_asm_operands): Likewise.
+ * tree.c (tree_size): Update computation of size of STRING_CST.
+ (make_node): Don't make STRING_CST nodes.
+ (build_string): Allocate string with tree node.
+ * tree.def (STRING_CST): Update comment.
+ * tree.h (TREE_STRING_POINTER): Adjust for change to STRING_CST.
+ (tree_string): Place contents of string in tree node.
+ * config/sh/sh.c (sh_handle_sp_switch_attribute): Duplicate string
+ from tree.
+
+ * config/rs6000/rs6000.c (rs6000_va_arg): No need to special-case
+ altivec operands.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.h: Fix comment formatting.
+ * c-cppbuiltin.c: Likewise.
+ * c-pragma.c: Likewise.
+ * calls.c: Likewise.
+ * collect2.c: Likewise.
+ * cppcharset.c: Likewise.
+ * cpptrad.c: Likewise.
+ * dbxout.c: Likewise.
+ * defaults.h: Likewise.
+ * dwarf2out.c: Likewise.
+ * fold-const.c: Likewise.
+ * genautomata.c: Likewise.
+ * genconditions.c: Likewise.
+ * genflags.c: Likewise.
+ * gengtype.c: Likewise.
+ * integrate.c: Likewise.
+ * loop.c: Likewise.
+ * predict.c: Likewise.
+ * sdbout.c: Likewise.
+
+2004-01-15 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.md (*movti_internal): C output template
+ extracted to ia64.c.
+ (*movti_internal_reg): Delete.
+ (reload_inti, reload_outti): Use the correct mode on operand 2
+ in the first place, don't fix it up in the output template.
+ (movtf, reload_ointf, reload_outtf): New expanders.
+ (*movtf_internal): New define_insn_and_split.
+ * config/ia64/ia64.c (ia64_split_timode): Rename to ia64_split_tmode;
+ make static; do not hand TFmode CONST_DOUBLEs to split_double.
+ (ia64_split_tmode_move): New function, body mostly pulled
+ from ia64.md:*movti_internal.
+ (ia64_function_arg_words): New function, extracted common
+ logic from ia64_function_arg et seq.
+ (ia64_function_arg_offset): Likewise. Handle correctly the
+ case of a scalar quantity 16 bytes wide with only 8-byte alignment.
+ (ia64_function_arg, ia64_function_arg_partial_nregs)
+ (ia64_function_arg_advance): Use ia64_function_arg_words and
+ ia64_function_arg_offset.
+ (ia64_function_value): TCmode does not go in float regs.
+ (ia64_secondary_reload_class): Also handle TFmode.
+ * config/ia64/ia64-protos.h: Remove prototype for
+ ia64_split_timode; add prototype for ia64_split_tmode_move.
+
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (MAINT): Make it an immediate assignment.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Remove useless calls to gen_lowpart.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/coff.h: Replace Hitachi with Renesas.
+ * config/h8300/elf.h: Likewise.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * config/h8300/lib1funcs.asm: Likewise.
+
+2004-01-15 Andrew Pinski <apinski@apple.com>
+
+ * config/rs6000/rs6000.c (uses_TOC): Wrap #if TARGET_ELF
+ around it.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_return_in_memory): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ * config/h8300/h8300.h (STRUCT_VALUE): Remove.
+ (RETURN_IN_MEMORY): Likewise.
+
+2004-01-15 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/13375
+ * gcse.c (handle_avail_expr): Just return if the source is not a
+ single set.
+
+2004-01-15 Richard Earnshaw <rearnsha@arm.com>
+ Daniel Jacobowitz <drow@mvista.com>
+
+ * arm/lib1funcs.asm (ARM_FUNC_START): Correct interworking case.
+ (EQUIV): Define.
+ (ARM_FUNC_ALIAS): New macro.
+ * arm/ieee754-df.S (gedf2, ledf2, nedf2, eqdf2): Use it.
+ * arm/ieee754-sf.S (gesf2, lesf2, nesf2, eqsf2): Use it.
+
+2004-01-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12372
+ * calls.c (expand_call): Add call_fusage data for stack arguments in
+ constant calls.
+
+2004-01-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (uses_TOC): Correct comment. Make static.
+ (rs6000_elf_declare_function_name): Formatting.
+ * config/rs6000/rs6000-protos.h (uses_TOC): Remove declaration.
+
+2004-01-15 Jan Hubicka <jh@suse.cz>
+
+ PR bootstrap/13692
+ * sched-deps.c (sched_analyze_1, sched_analyze_2): Fix thinko in
+ previous patch.
+
+2004-01-15 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.h (REG_ALLOC_ORDER): Reorder fp regs after
+ integer regs of the same call-savedness.
+
+2004-01-15 Andreas Schwab <schwab@suse.de>
+
+ PR bootstrap/13562
+ * config/m68k/m68k.c (output_move_const_into_data_reg): Clear cc
+ status for NOTB/NOTW/NEGW methods.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Update dump file names. Fix a typo.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c (expand_builtin_va_end): Don't use
+ EXPAND_BUILTIN_VA_END.
+ * system.h (EXPAND_BUILTIN_VA_END): Poison.
+ * config/d30v/d30v.h: Remove a commented-out definition of
+ EXPAND_BUILTIN_VA_END.
+ * config/stormy16/stormy16.h: Likewise.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (STRUCT_VALUE_INCOMING_REGNUM): Poison.
+ * targhooks.c (default_struct_value_rtx): Don't use
+ STRUCT_VALUE_INCOMING_REGNUM.
+
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
+
+ PR bootstrap/12744
+ * configure.in: Revamp enable-generated-files-in-srcdir rule to define
+ GENINSRC and not parsedir. Define srcextra as a langhook.
+ * configure: Regenerate.
+ * Makefile.in: Suppress default .l.c rule. Don't substitute
+ parsedir and delete all references throughout. Conditionally define
+ rule for srcextra dependent on GENINSRC.
+ (stmp-docobjdir): Delete.
+ (c-parse.o, gengtype-lex.o, gengtype-yacc.o): Use implicit build rule.
+ (srcextra): Copy c-parse.y, c-parse.c, gengtype-lex.c, gengtype-yacc.c,
+ and gengtype-yacc.h back to source directory.
+ (maintainer-clean): Delete all parse files in source directory.
+ (distclean): Delete generated files.
+
+ * objc/Make-lang.in (objc-parse.o): Use implicit build rule.
+ (objc-parse.c, objc-parse.y): Don't use parsedir.
+ (objc.srcextra): Copy objc-parse.y and objc-parse.c back to source
+ directory if requested.
+ (po-generated): Don't use parsedir.
+ (objc.maintainer-clean): Delete above files from source directory.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi (FUNCTION_VALUE): Fix a typo.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi: Replace RETURN_IN_MEMORY with
+ TARGET_RETURN_IN_MEMORY.
+
+2004-01-15 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (std_expand_builtin_va_arg): Align operand when needed.
+ * i386.c (init_cumulative_args): Set warn_sse; fix handling of variadic
+ functions accepting SSE arguments
+ (function_arg): Warn only when asked to warn.
+ * i386.h (ix86_args): Add warn_sse/warn_mmx fiels.
+
+2004-01-14 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-parse.in (stmts_and_decls): Make label at end of compound
+ statement a hard error.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (create_edge): Use local.redefined_extern_inline.
+ * cgraph.h (cgraph_local_info): Sort fields by size; add
+ redefined_extern_inline
+ (cgraph_global_info): Sort fields by size.
+ (cgraph_node): Likewise.
+ * cgraphunit.c (cgraph_finalize_function): Se
+ local.redefined_extern_inline on redefinition.
+ (cgraph_analyze_function): Use it; fix formating.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ PR c++/10776
+ * sched-deps.c (trye_dependency_cache, anti_dependency_cache,
+ outptu_dependency_cache, forward_dependency_cahe): Trun to vectors of
+ bitmaps
+ (cache_size): New variable
+ (add_dependence): Update use; canonize early memory locations
+ (sched_analyze_1): Likewise.
+ (sched_analyze_2): Likewise.
+ (init_dependency_caches): Initialize bitmaps.
+ (free_dependency_caches): Free bitmaps
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c: Replace STRICT_ARGUMENT_NAMING in comments with
+ targetm.calls.strict_argument_naming().
+ * target.h: Likewise.
+
+2004-01-14 Richard Henderson <rth@redhat.com>
+
+ PR debug/13231
+ * dwarf2out.c (dwarf2out_stack_adjust): Skip prologue and epilogue
+ instructions.
+
+2004-01-14 Richard Henderson <rth@redhat.com>
+
+ PR c++/12491
+ * except.c (struct eh_region): Add u.fixup.resolved.
+ (resolve_one_fixup_region): Split out from ...
+ (resolve_fixup_regions): ... here.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300.h (STRUCT_VALUE): Change to 0.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.h (STRUCT_VALUE): Remove.
+ * config/alpha/vms.h (STRUCT_VALUE_REGNUM): Remove #undef.
+ (STRUCT_VALUE): Remove.
+
+2004-01-14 Steven Bosscher <stevenb@suse.de>
+
+ * system.h: Poison PROMOTED_MODE
+ * integrate.c (expand_inline_function): Don't mention the
+ PROMOTED_MODE.
+ * loop.c (update_giv_derive): Same.
+ * tree.h (DECL_RTL): Same.
+
+2004-01-14 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR target/9365
+ * sh.c (gen_block_redirect): Add special handling of RETURN.
+ (gen_far_branch) Don't call gen_stuff_delay_slot if there is no
+ far branch target (i.e. it's a return).
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * regrename.c (find_oldest_value_reg): Fix a warning.
+
+2004-01-14 Richard Earnshaw <rearnsha@arm.com>
+
+ PR bootstrap/12527
+ * config.gcc (arm*-*-linux*): Don't include unknown-elf.h in tm_file.
+ Move linux-gas.h and linux-elf.h before aout.h.
+ * arm/arm.h (INITIALIZE_TRAMPOLINE): Only define if not already.
+ * arm/linux-elf.h (SUBTARGET_CPU_DEFAULT): Define.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Use GEN_INT instead of gen_rtx
+ (CONST_INT, VOIDmode, ...).
+
+2004-01-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * regrename.c (find_oldest_value_reg): If the replacement uses
+ multiple hard registers, check that all of them are in CLASS.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ * alias.c (get_alias_set): Initialize alias set to 0 when subset is
+ impossible.
+
+2004-01-14 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Define MAINT from --enable-maintainer-mode.
+
+2004-01-14 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (rs6000_stack_info)
+ Calculate always vrsave_mask if TARGET_ALTIVEC.
+ (rs6000_emit_prologue): Emit code for vrsave
+ only if TARGET_ALTIVEC_VRSAVE.
+ (rs6000_emit_epilogue): Likewise.
+
+2004-01-14 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.md (tie_add32): Fix pasto.
+ (tie_add64): Likewise.
+
+2004-01-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * config/i386/i386.md (*addqi_1_slp): Do not access operands[2].
+
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/iq2000/iq2000-protos.h: Fix comment formatting.
+ * config/iq2000/iq2000.c: Likewise.
+ * config/iq2000/iq2000.md: Likewise.
+
+2004-01-14 J. Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (is_ada_subrange_type): No longer check the TYPE_NAME.
+ (subrange_type_die): Add handle for nameless subrange types.
+
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Replace do_movsi with
+ h8300_expand_movsi.
+ * config/h8300/h8300.c (do_movsi): Change to
+ h8300_expand_movsi.
+ * config/h8300/h8300.md (movsi): Replace do_movsi with
+ h8300_expand_movsi.
+ (movsf): Likewise.
+
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (dosize): Change to
+ h8300_emit_stack_adjustment. Update callers.
+
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (movstrictqi): Add an alternative with
+ the source being post_inc. Tighten the predicate for the
+ destination to register_operand.
+ (movstricthi): Likewise.
+
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (SHARED_BSS_SECTION_ASM_OP): Poison.
+ * varasm.c (bss_section): Don't use SHARED_BSS_SECTION_ASM_OP.
+ * doc/tm.texi (SHARED_BSS_SECTION_ASM_OP): Remove.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ Partial fix PR c++/12850
+ * cgraphunit.c (cgraph_finalize_function): Always ggc_collect when
+ at zero nest level.
+
+2004-01-13 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/netbsd-elf.h (REGISTER_NAMES): Add missing "argptr"
+ pseudo-register.
+
+2004-01-13 Devang Patel <dpatel@apple.com
+
+ PR debug/7078
+ * dbxout.c (dbxout_symbol_name): Emit mangled names for
+ NAMESPACE_DECL memebers.
+
+2004-01-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/12709
+ * c-common.c (finish_fname_decls): Use the chain only if the
+ tree is an expr_stmt.
+
+2004-01-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ * rtl.def: Add comment about new option in automata_option.
+
+ * genautomata.c (PROGRESS_OPTION): New macro.
+ (progress_flag): New global variable.
+ (gen_automata_option): Process `progress'.
+ (transform_insn_regexps, check_unit_distributions_to_automata,
+ make_automaton, NDFA_to_DFA, build_automaton, create_automata,
+ expand_automata, write_automata): Print about the progress only if
+ progress_flag. Remove fflush.
+ (initiate_automaton_gen): Process command line flag `-progress'.
+
+ * doc/md.texi: Describe the new option.
+
+2004-01-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfg.c (dump_bb): Dump entry edges.
+
+2004-01-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_legitimate_address_p): Only allow constant pool
+ references from SImode.
+ * arm.md (thumb_movhi_insn): Don't allow minipool references.
+
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (TEXT_SECTION): Poison.
+ * varasm.c (text_section): Don't use TEXT_SECTION.
+ * config/sh/sh.c (sh_file_start): Fix a comment typo.
+ * doc/tm.texi (TEXT_SECTION): Remove.
+
+2004-01-13 Ben Elliston <bje@wasabisystems.com>
+
+ * doc/rtl.texi (Vector Operations): Remove defunct vec_const item.
+
+2004-01-12 James E Wilson <wilson@specifixinc.com>
+
+ * unwind-libunwind.c: Delete.
+
+2004-01-12 Zack Weinberg <zack@codesourcery.com>
+
+ PR 13656
+ * c-decl.c (diagnose_mismatched_decls): Whenever newtype or
+ oldtype is set, set *newtypep or *oldtypep too. Do not set
+ them at the very end.
+ (validate_proto_after_old_defn): Restructure for comprehensibility;
+ make error messages clearer.
+
+2004-01-12 Zack Weinberg <zack@codesourcery.com>
+
+ * varray.h (VARRAY_POP): Add checking variant, aborts on underflow.
+ (VARRAY_TOP): Use VARRAY_CHECK so the access is bounds-checked.
+ * varray.c: No need to prototype error.
+ (varray_check_failed): Wrap long string onto two lines.
+ (varray_underflow): New function.
+
+2004-01-13 Steven Bosscher <stevenb@suse.de>
+
+ PR c++/13376
+ * function.h (struct function): Kill `name' field.
+ (current_function_name): Make it an extern function.
+ * function.c (current_function_name): New function.
+ * graph.c: Update all uses of current_function_name.
+ * gcse.c: Likewise.
+ * config/alpha/alpha.c, config/avr/avr.c, config/c4x/c4x.c,
+ config/mips/mips.c, config/pdp11/pdp11.c: Likewise.
+ * config/ip2k/ip2k.c (function_prologue): Use MAIN_NAME_P
+ instead of a strcmp with "main".
+
+2004-01-13 Jan Hubicka <jh@suse.cz>
+
+ * c-decl.c (diagnose_mismatched_decls): Fix warning calls.
+
+ * cgraphunit.c (cgraph_optimize_function): Always do
+ optimize_inline_calls when there is always_inline callee.
+ (cgraph_decide_inlining): Fix formating.
+ * tree-inline.c (inlinable_function_p): Do sorry for alwaysinline
+ functions.
+ (expand_call_inline): Likewise.
+ * toplev.h (sorry): Fix prototype.
+
+2004-01-12 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_expect_jump): Simplify logic. Handle
+ conditional jumps that drop through to unconditional jumps or the
+ end of the sequence.
+
+2004-01-13 Jan Hubicka <jh@suse.cz>
+
+ * alias.c (new_alias_set): Construct the alias_set varray.
+ (init_alias_once): Don't do it here.
+
+2004-01-12 Marc Espie <espie@openbsd.org>
+
+ * system.h: handle YYBYACC like YYBISON.
+
+2004-01-12 Jonathan Merriman <jonm@dualitymedia.com>
+
+ PR target/10847
+ * config.gcc: No longer includes conflicting header sparc/sol2.h when
+ building on sparc64-*-openbsd*.
+
+2004-01-12 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR debug/13539
+ * dbxout.c (dbxout_type): Protected inheritance is not
+ private but protected.
+
+2004-01-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_symbolic_constant_p): Revert last patch.
+
+2004-01-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR optimization/12508.
+ * combine.c (try_combine): Remove a dead set in a parallel
+ even if its destination is a subreg.
+
+ Revert:
+ 2003-06-03 Kazu Hirata <kazu@cs.umass.edu>
+ * combine.c (simplify_set): Don't move a subreg in SET_SRC to
+ SET_DEST if WORD_REGISTER_OPERATIONS is not defined.
+
+2004-01-12 Geoffrey Keating <geoffk@apple.com>
+
+ * real.c: Update copyright date.
+ * emit-rtl.c: Likewise.
+ * rtl.h: Likewise.
+ * dwarf2out.c: Likewise.
+ * config/rs6000/darwin-ldouble.c: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+
+2004-01-12 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_init_libfuncs): Add AIX
+ TFmode to SImode libfuncs.
+
+2004-01-12 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11397
+ * varasm.c (assemble_alias): Remove weak aliases from weak_decls.
+
+2004-01-12 Jan Hubicka <jh@suse.cz>
+
+ PR opt/12826
+ * loop.c (insert_loop_mem): Preffer VOLATILE memory references to be
+ stored.
+
+ PR opt/12863
+ * cfgcleanup.c (label_is_jump_target_p): Move to...
+ * rtlanal.c (label_is_jump_target_p): ... here.
+ * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Fix redirecting of fallthru
+ edges unified with branch edges.
+
+2004-01-12 Richard Earnshaw <rearnsha@arm.com>
+
+ * simplify-rtx.c (simplify_immed_subreg): Correctly extract the
+ high word of an integral CONST_DOUBLE.
+
+2004-01-12 Paul Brook <paul@codesourcery.com>
+
+ * simplify-rtx.c (simplify_plus_minus): Always generate canonical form.
+
+2004-01-12 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR target/13585
+ * sh-protos.h (check_use_sfunc_addr): Declare.
+ * sh.c (extract_sfunc_addr, check_use_sfunc_addr): New functions.
+ * sh.md (use_sfunc_addr): Use check_use_sfunc_addr in insn predicate.
+
+2004-01-12 Jan Hubicka <jh@suse.cz>
+
+ * alias.c: Invlude varray.h
+ (alias_sets): Turn into varray.
+ (get_alias_set_entry): Use VARRAY; mark inline.
+ (mems_in_disjoint_alias_sets_p): Mark inline.
+ (record_alias_subset): Use varray.
+ (init_alias_once): Initialize varray.
+ (new_alias_set): Grow array.
+ * varray.c: Make VARRAY_GENERIC_PTR non GTYized.
+
+2004-01-12 Jan Hubicka <jh@suse.cz>
+
+ Partial fix for PR opt/10776 II
+ * cselib.c: Include params.h
+ (cselib_invalidate_mem): Limit amount of nonconflicting memory
+ locations.
+ * params.def (PARAM_MAX_CSELIB_MEMORY_LOCATIONS): New.
+ * Makefile.in (cselib.o): Depend on params.h
+
+2004-01-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * combine.c (combine_simplify_rtx): Don't pass VOIDmode to
+ simplify_unary_operation if the operand has a known mode.
+
+2004-01-12 Hartmut Penner <hpenner@de.ibm.com>
+
+ PR target/13534
+ * gcc/config/rs6000/rs6000.c (word_offset_memref_operand): New
+ predicate to handle 'ld' conform addresses.
+ * gcc/config/rs6000/rs6000.h (EXTRA_CONSTRAINT): New 'Y'
+ contraint.
+ (EXTRA_MEMORY_CONSTRAINT): Tell reload which constraint
+ are memory contraints.
+ * gcc/config/rs6000/rs6000-protos.h (word_offset_memref_operand):
+ New prototype.
+ * gcc/config/rs6000/rs6000.md (*movdf_hardfloat64):
+ Change 'o' to 'Y' constraint.
+ (*movdf_softfloat64): Ditto.
+
+2004-01-12 Bernardo Innocenti <bernie@develer.com>
+
+ * gcc/config/m68k/m68k.md: Switch from the "*..." syntax to the
+ brace-enclosed syntax in all C output statements.
+
+2004-01-12 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/13401
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue):
+ Objective-C language type value is 14.
+
+2004-01-12 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+
+ PR c/12148
+ * config/m68k/fpgnulib.c: Fix `-mshort' bugs: Use `long' instead of
+ `int' in a number of places to make sure we always have a SImode
+ and not a HImode. Add a 'L' suffix to a number of constants.
+
+2004-01-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c: Don't include obstack.h.
+
+ * pa.md: Correct constraint in pattern for loading PIC label address.
+
+2004-01-11 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (ASM_PREFERRED_EH_DATA_FORMAT): Undefine
+ before defining.
+
+2004-01-11 Steven Bosscher <stevenb@suse.de>
+
+ PR fortran/9972
+ * toplev.c (rest_of_handle_inline): Also consider functions
+ for deferral if the language is GNU F77.
+
+2004-01-11 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (diagnose_arglist_conflict): Add missing space to
+ diagnostic messages.
+
+2004-01-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/13392
+ * builtins.c (expand_builtin_expect_jump): Handle conditional jumps
+ to drop through label. Don't fall back to SCC even when conditional
+ jump has not been found.
+
+2004-01-11 Jan Hubicka <jh@suse.cz>
+
+ * invoke.texi: Fix syntax error in previous patch.
+
+ Partial fix for PR opt/10776
+ * Makefile.in (reload.o): Include param.h
+ * params.def (PARAM_MAX_RELOAD_SEARCH_INSNS): New parameter.
+ * reload.c: Include params.h.
+ (find_equiv_reg): Work limiting check.
+ * invoke.texi: Document.
+
+2004-01-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_symbolic_constant_p): Don't allow
+ out-of-bounds accesses to string constants. Simplify mips16
+ case accordingly.
+
+2004-01-11 Richard Sandiford <rsandifo@redhat.com>
+
+ PR optimization/13469
+ * toplev.c (rest_of_compilation): Call purge_all_dead_edges after
+ reload_cse_regs (-fnon-call-exceptions only).
+
+2004-01-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mcore/lib1.asm: Fix comment formatting.
+ * config/mcore/mcore-elf.h: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore.md: Likewise.
+
+2004-01-10 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (duplicate_decls): Break apart into...
+ (diagnose_arglist_conflict, validate_proto_after_old_defn)
+ (locate_old_defn, diagnose_mismatched_decls, merge_decls):
+ ... these new functions. Restructure for comprehensibility.
+ Remove various archaic special cases. Always report the
+ location of the previous declaration when a diagnostic is issued.
+ (redeclaration_error_message): Fold into diagnose_mismatched_decls.
+ (match_builtin_function_types): Delete unnecessary forward declaration.
+
+2004-01-10 Zack Weinberg <zack@codesourcery.com>
+
+ * genautomata.c (make_automaton, NDFA_to_DFA):
+ Print progress bars with '.' characters instead of '*'.
+ (build_automaton): Change notes to match.
+
+2004-01-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Use define_constants for unspec and
+ unspec_volatile.
+
+2004-01-10 Jan Hubicka <jh@suse.cz>
+
+ PR opt/11635
+ * expr.c (expand_expr_real): More curefully expand union casts.
+
+2004-01-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md (flush_icache): Use 1 for
+ unspec_volatile.
+
+2004-01-10 David Edelsohn <edelsohn@gnu.org>
+ James E Wilson <wilson@specifixinc.com>
+
+ PR debug/12860
+ * dbxout.c (dbxout_symbol): Remove initialization of
+ current_sym_code, current_sym_value, and current_sym_addr.
+ (dbxout_symbol_location): Same.
+ (dbxout_prepare_symbol): Zero current_sym_code,
+ current_sym_value, and current_sym_addr.
+
+2004-01-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * tree.c (get_unwidened): Reorder conditions so that the null pointer
+ check is done first.
+
+2004-01-09 Eric Christopher <echristo@redhat.com>
+
+ * toplev.c (rest_of_handle_cfg): Add reg_scan pass
+ if we're running mark_constant_function.
+
+2004-01-09 Jeff Bailey <jbailey@nisa.net>
+
+ PR target/12561
+ * config/t-gnu: Rename SYSTEM_HEADER_DIR to NATIVE_SYSTEM_HEADER_DIR.
+
+2004-01-09 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR debug/11231
+ * dbxout.c (dbxout_type_fields): Return if any item is
+ error_mark_node or the type is error_mark_node.
+
+2004-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/darwin-ldouble.c: Add big comment explaining
+ exactly what is expected as a 'long double'.
+ (_xlqadd): When a value to be returned is representable as a
+ 'double', just return it directly, do not construct it using a union.
+ Also, correct final fixup.
+ (_xlqmul): Likewise.
+ (_xlqdiv): Likewise.
+ * real.c (encode_ibm_extended): Make consistent with darwin-ldouble.c.
+
+ * config/rs6000/rs6000.md (fix_trunctfdi2): Delete.
+
+2004-01-09 Richard Henderson <rth@redhat.com>
+
+ * recog.c (constrain_operands): Validate mem operands.
+
+2004-01-09 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (init_spec): Remove -lunwind from shared case.
+ * conifg/ia64/t-hpux (SHLIB_LINK): Add -lunwind.
+
+2004-01-09 Steve Ellcey <sje@cup.hp.com>
+
+ * configure.ac: (gcc_cv_ld_hidden) Set to true for ia64*-*-hpux*.
+ * configure: Regenerate
+
+2004-01-09 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/11234
+ * c-typeck.c (build_c_cast): If pedantic, warn for conversions
+ between function and object pointers.
+ (digest_init): When comparing a pointer to function type to the
+ target type, only apply TREE_TYPE once to the pointer to function
+ type.
+ * except.c (for_each_eh_label_1): Treat data as a pointer to a
+ function pointer rather than casting it to a function pointer.
+ (for_each_eh_label): Update caller.
+ * recog.h (struct insn_data): Use a struct or union for output.
+ * genoutput.c (output_insn_data): Update.
+ * final.c (get_insn_template): Update.
+
+2004-01-09 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.h (expand_expr): Make it a macro, not a function.
+ (expand_expr_real): New function.
+ * expr.c (store_expr): Adjust logic for deciding whether or not to
+ copy the value returned by expand_expr.
+ (expand_expr): Rename to ...
+ (expand_expr_real): ... this. Add alt_rtl parameter. Adjust
+ calls to language hooks.
+ * c-common.h (c_expand_expr): Adjust prototype.
+ * c-common.c (c_expand_expr): Add alt_rtl parameter.
+ * langhooks-def.h (lhd_expand_expr): Change prototype.
+ * langhooks.c (lhd_expand_expr): Add all_rtl parameter.
+ * langhooks.h (lang_hooks): Change type of expand_expr.
+ * stmt.c (stmt_status): Add x_last_expr_alt_rtl.
+ (last_expr_alt_rtl): Likewise.
+ (expand_expr_stmt_value): Set last_expr_alt_rtl.
+ (clear_last_expr): Clear it.
+ (expand_end_stmt_expr): Set RTL_EXPR_ATL_RTL.
+ (expand_end_bindings): Save and restor last_expr_alt_rtl.
+ * tree.def (RTL_EXPR): Give it an additional operand.
+ * tree.h (RTL_EXPR_ALT_RTL): New macro.
+
+2004-01-09 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (TARGET_CPU_CPP_BUILTINS): Add __m32r__.
+ * config/m32r/m32r.c (call26_operand): Allow in PIC mode.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/13380.
+ * config/m32r/m32r.md: Replace (reg:SI 17) with (reg:CC 17)
+ or (ne:SI (reg:CC 17) (const_int 0)).
+ Be specific about modes wherever possible.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c (m32r_expand_block_move): Call
+ gen_movestrsi_internal with two more arguments.
+ (m32r_output_block_move): Adjust operand numbers.
+ Properly update the source and destination pointers.
+ * config/m32r/m32r.md (movstrsi_internal): Use 'r' instead of
+ 'r+'. Change the set detinations to match_operand.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * final.c (FIRST_INSN_ADDRESS): Remove.
+ (shorten_branches): Don't use FIRST_INSN_ADDRESS.
+ * system.h (FIRST_INSN_ADDRESS): Poison.
+ * config/avr/avr.h: Remove a comment about FIRST_INSN_ADDRESS.
+ * config/m32r/m32r-protos.h: Remove the prototype for
+ m32r_first_insn_address.
+ * config/m32r/m32r.c (m32r_first_insn_address): Remove.
+ * config/m32r/m32r.h (FIRST_INSN_ADDRESS): Likewise.
+ * doc/md.texi (FIRST_INSN_ADDRESS): Likewise.
+
+2004-01-09 J. Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (gen_enumeration_type_die): Return the DIE that
+ we just created.
+ (is_ada_subrange_type): DIEs for enumeration subtypes should be
+ emitted as subrange types too.
+ (subrange_type_die): Add handling of enumeration subtypes.
+
+2004-01-08 Richard Henderson <rth@redhat.com>
+
+ PR opt/12441
+ Revert: Sat Mar 30 14:08:55 CET 2002 Jan Hubicka <jh@suse.cz>
+ * i386.c (aligned_operand): Be prepared for SUBREGed registers.
+ (ix86_decompose_address): Use REG_P instead of GET_CODE (...) == REG.
+ (ix86_address_cost): Be prepared for SUBREGed registers.
+ (legitimate_address_p): Accept SUBREGed registers.
+
+2004-01-08 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Rename configure.in to configure.ac
+ * doc/sourcebuild.texi: Likewise.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2004-01-08 Stuart Hastings <stuart@apple.com>
+
+ * config/i386/i386.md: Typos in MMX/SSE immediate shifts.
+
+2004-01-08 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_decide_inlining): Fix typo.
+
+2004-01-08 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md (cmptf_internal1): Correct branch offset.
+ (UNSPEC_FIX_TRUNC_TF): New constant.
+ (movtf_internal): Make splitter active only when insn is active.
+ (extenddftf2): Rewrite to properly load zero into low part.
+ (extenddftf2_internal): New.
+ (extendsftf2): Rewrite.
+ (truncdftf2): Correct length.
+ (floatditf2): Delete.
+ (fix_trunc_helper): New.
+ (fix_trunctfdi2): Use fix_trunc_helper.
+ (fix_trunctfsi2): Likewise.fix_trunc
+ (fix_trunctfsi2_internal): New.
+
+ * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): lo_sum
+ addresses are legitimate on Darwin even when flag_pic.
+ (rs6000_legitimize_reload_address) [TARGET_MACHO]: Don't create
+ non-offsettable addresses for loads of TFmode constants.
+
+2004-01-08 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (ASM_OUTPUT_ALIGNED_BSS): Actually emit
+ variables in the appropriate bss section.
+
+2004-01-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Ensure
+ target_flags has MASK_POWERPC64 when -m64.
+ * config/rs6000/rs6000.c (processor_target_table): Add MASK_POWERPC64
+ to 620, 630, power3, power4 and rs64a entries.
+ * config/rs6000/rs6000.h (MASK_64BIT): Expand comment.
+
+2004-01-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * simplify-rtx.c (simplify_immed_subreg): Fix construction of
+ floating-point constants.
+
+2004-01-08 J. Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (subrange_type_die): Add context_die parameter.
+ Create the subrange_type DIE using the given context DIE.
+ (modified_type_die): Update call to subrange_type_die.
+
+2004-01-08 Zack Weinberg <zack@codesourcery.com>
+
+ * dwarf2.h, unwind-dw2-fde.h, unwind-pe.h, unwind.h:
+ Add multiple-include guard.
+
+2004-01-08 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (easy_vector_constant): Accept
+ all vector constant loadable by vsplt*.
+ (output_vec_const_move): Likewise.
+
+2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/6024
+ * c-typeck.c (comptypes): Only treat enumerated types in the same
+ translation unit as compatible with each other when they are the
+ same type.
+ * doc/extend.texi: Update.
+
+2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/12165
+ * c-decl.c (grokdeclarator): Take type qualifiers of typedefed
+ array type from the array element type.
+
+2004-01-07 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_dbx_register_number): New function.
+ * config/rs6000/rs6000-protos.h (rs6000_dbx_register_number): Declare.
+ * config/rs6000/rs6000.h (DWARF_FRAME_REGNUM): Define.
+ (DWARF_REG_TO_UNWIND_COLUMN): Correct column adjustment and comment.
+ * config/rs6000/sysv4.h (DBX_REGISTER_NUMBER): Define.
+
+2004-01-06 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.h (MDEBUG_ASM_SPEC): Change for dwarf2 default.
+ (DWARF2_DEBUGGING_INFO): Define.
+ (PREFERRED_DEBUGGING_TYPE): Set to dwarf2.
+ * config/mips/openbsd.h (PREFERRED_DEBUGGING_TYPE): Remove.
+ * config/mips/iris6.h (SUBTARGET_ASM_DEBUGGING_SPEC): Only pass -g0
+ for irix as.
+ (SUBTARGET_ASM_OPTIMIZING_SPEC): Only pass O0 for irix as.
+ * config/mips/iris6gas.h (MDEBUG_ASM_SPEC): Remove.
+ * config/mips/iris5gas.h: Ditto.
+ (DBX_DEBUGGING_INFO): Remove.
+ (DWARF2_DEBUGGING_INFO): Ditto.
+ (MIPS_DEBUGGING_INFO): Ditto.
+ (PREFERRED_DEBUGGING_TYPE): Ditto.
+ * config/mips/elf.h (DWARF2_DEBUGGING_INFO): Remove.
+ (PREFERRED_DEBUGGING_TYPE): Ditto.
+ (SUBTARGET_ASM_DEBUGGING_SPEC): Ditto.
+ * config/mips/elf64.h: Ditto.
+
+2004-01-06 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (STAGEPROFILE_FLAGS_TO_PASS): Use -fprofile-generate.
+ (STAGEFEEDBACK_FLAGS_TO_PASS): Use -fprofile-use.
+
+2004-01-06 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/t-darwin (LIB2FUNCS_EXTRA): Compile darwin-ldouble.c.
+ (TARGET_LIBGCC2_CFLAGS): Use -mlong-double-128.
+ * config/rs6000/darwin-ldouble.c: New.
+
+ * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg
+ for constants.
+ (constant_subword): Delete.
+ * rtl.h (constant_subword): Delete prototype.
+ (immed_double_const): Is not in varasm.c.
+ * simplify-rtx.c (simplify_immed_subreg): New.
+ (simplify_subreg): Use simplify_immed_subreg.
+
+ * config/rs6000/rs6000.md (floatsitf2): Use expand_float rather
+ than trying to generate RTL directly.
+ (fix_trunctfsi2): Use expand_fix rather than trying to generate
+ RTL directly.
+
+ * dwarf2out.c (add_const_value_attribute): Remove incorrect comment.
+
+2004-01-06 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/xcoff.h (EXTRA_SECTION_FUNCTIONS): Split each
+ function into a separate macro.
+ (read_only_data_section): Add void argument.
+ (private_data_section): Same.
+ (read_only_private_data_section): Same.
+ (toc_section): Same.
+
+2004-01-06 Jan Hubicka <jh@suse.cz>
+
+ * invoke.texi: Remove typo in last change.
+
+ PR target/10301
+ * config.gcc: Accept opteron and athlon-64 as variants
+ of k8.
+ * i386.c (override_options): Likewise.
+ * invoke.texi (i386 -mtune): Expand documentation.
+
+2004-01-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Fix comment typos.
+ * builtins.c: Likewise.
+ * cfg.c: Likewise.
+ * df.c: Likewise.
+ * dominance.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * expr.c: Likewise.
+ * final.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcse.c: Likewise.
+ * genattrtab.c: Likewise.
+ * genrecog.c: Likewise.
+ * gensupport.c: Likewise.
+ * ggc-zone.c: Likewise.
+ * integrate.c: Likewise.
+ * local-alloc.c: Likewise.
+ * loop.c: Likewise.
+ * recog.c: Likewise.
+ * regmove.c: Likewise.
+ * reg-stack.c: Likewise.
+ * reorg.c: Likewise.
+ * rtlanal.c: Likewise.
+ * rtl.h: Likewise.
+ * sched-ebb.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * toplev.c: Likewise.
+ * varasm.c: Likewise.
+
+2004-01-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+ * doc/md.texi: Likewise.
+
+2004-01-06 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (TRAMPOLINE_LINE_SIZE): Changed
+
+2004-01-06 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (init_cumulative_args): Add handling of MMX_REGPARM.
+ (function_arg_advance): Do not pass aggregates in SSE; deal handling
+ of MMX_REGPARM.
+ (function_arg): Add new warnings about ABI changes; fix SSE_REGPARM;
+ add MMX_REGPARM.
+ * i386.h (ix86_args): Add mmx_words/mmx_regs/mmx_regno fields.
+ (SSE_REGPARM_MAX): Default to 3 on i386 -msse ABI.
+ (MMX_REGPARM_MAX): Similarly for -mmmx.
+
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/linux.h: Fix comment formatting.
+ * config/sh/netbsd-elf.h: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sh/vxworks.h: Likewise.
+
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (ASM_OUTPUT_MAIN_SOURCE_FILENAME): Poison.
+ * toplev.c (output_file_directive): Don't use
+ ASM_OUTPUT_MAIN_SOURCE_FILENAME.
+
+2004-01-05 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * toplev.c: Fix broken checkin of 2003-12-30.
+
+2004-01-05 Daniel Berlin <dberlin@dberlin.org>
+
+ * ggc-zone.c: Remove everything in #ifdef USING_MALLOC_PAGE_GROUPS
+ (USING_MMAP): We don't support non-mmap.
+ (struct alloc_chunk): Steal 1 bit from typecode, use it to mark
+ large objects.
+ (struct page_entry): Remove bytes_free.
+ (struct page_table_chain): Remove.
+ (struct globals): Remove page_table member.
+ (loookup_page_table_entry): Function deleted.
+ (set_page_table_entry): Ditto.
+ (ggc_allocated_p): No longer need page table lookups.
+ (ggc_marked_p): Ditto.
+ (alloc_small_page): Don't care about bytes_free anymore.
+ (alloc_large_page): Round up size.
+ (ggc_alloc_zone_1): Mark large objects as such, and calculate
+ their size the new way.
+ Remove page table lookups and setting.
+ (ggc_get_size): Calculate large object size the new way.
+ (sweep_pages): Redo to account for fact that we no longer have
+ bytes_free.
+ (ggc_collect): No longer need to reincrement bytes_free.
+ (ggc_pch_alloc_object): Handle new large objects properly.
+ (ggc_pch_read): Put PCH stuff into it's own uncollected zone.
+
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Remove a page break.
+
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.c (avr_output_function_prologue): Remove an
+ extra pair of curly braces.
+
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300.c: Fix comment formatting.
+ * config/mn10300/mn10300.h: Likewise.
+
+2004-01-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree.h: Update documentation on nothrow_flag.
+ * print-tree.c (print_node): Print TREE_NOTHROW as "align-ok" for
+ types.
+
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Remove traces of dead ports.
+
+2004-01-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Add documentation for the MIPS -mexplicit-relocs
+ option.
+
+2004-01-05 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12945
+ * coverage.c (coverage_counter_alloc): Set SYMBOL_FLAG_LOCAL for
+ counter labels.
+ * config/mips/mips.c (INTERNAL_SYMBOL_P): Delete.
+ (mips_classify_symbol): Always treat SYMBOL_REF_FLAG as indicating
+ string constants if TARGET_MIPS16. Use SYMBOL_REF_DECL to check
+ the binding of decl symbols, otherwise check SYMBOL_REF_LOCAL_P.
+ (mips_symbol_insns): Don't trust the local/global classification.
+ (m16_usym8_4, m16_usym5_4): Same mips16 change as mips_classify_symbol.
+ (override_options): Make -mabicalls -fno-unit-at-a-time imply
+ -mno-explicit-relocs.
+ (mips_encode_section_info): Don't use SYMBOL_REF_FLAG to distinguish
+ between local and global symbols.
+
+2004-01-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_dangerous_for_la25_p): Declare.
+ (mips_preferred_reload_class): Declare.
+ * config/mips/mips.h (DANGEROUS_FOR_LA25_P): Replace with function.
+ (EXTRA_CONSTRAINT): Update accordingly.
+ (PREFERRED_RELOAD_CLASS): Use mips_preferred_reload_class.
+ * config/mips/mips.c (mips_dangerous_for_la25_p): New function.
+ (mips_preferred_reload_class): New function. Prefer LEA_REGS if
+ mips_dangerous_for_la25_p.
+ (mips_secondary_reload_class): Use LEA_REGS rather than GR_REGS
+ if mips_dangerous_for_la25_p.
+
+2004-01-05 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (output_andsi3): Fix signed/unsigned comparison
+ warning.
+
+2004-01-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Use AC_PROG_CPP_WERROR.
+ * configure: Regenerate.
+
+2004-01-04 Zack Weinberg <zack@codesourcery.com>
+
+ * .cvsignore: Add autom4te.cache.
+
+2004-01-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Revamp documentation of MIPS options. Remove
+ -mabi=meabi, -mabi-fake-default, -mmips-as, -mgas, -mmips-tfile,
+ -m4650, -mfix7000 and -(m)no-crt0. Put endianness options first,
+ then architecture options, then ABI options. General rewording.
+
+2004-01-04 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/3414
+ * doc/extend.texi: Clarify definition of malloc attribute.
+
+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-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Replace AC_INIT, AC_OUTPUT, AC_CANONICAL_SYSTEM
+ with modern equivalents.
+ * configure: Regenerate.
+
+ * configure.ac: Replace gcc_AC_CHECK_TYPE with AC_CHECK_TYPE.
+ * aclocal.m4 (gcc_AC_CHECK_TYPE): Remove.
+ * configure: Regenerate.
+
+ * doc/install.texi: Note that 'gcc' is now a 2.57 directory.
+
+ * configure.in: Rename to configure.ac.
+ * configure.ac: Renamed from configure.in; make minimum necessary
+ changes for autoconf 2.5x.
+ * aclocal.m4: Make minimum necessary changes for autoconf 2.5x.
+ * configure: Regenerate with autoconf 2.57.
+
+2004-01-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mips/linux.h: Fix comment formatting.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/mips/netbsd.h: Likewise.
+ * config/mips/windiss.h: Likewise.
+
+2004-01-02 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (fp constant pool splitter): Reorg suppression
+ for sse and 387; add suppression for mmx.
+
+2004-01-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * loop.c (loop_optimize): Free all loops_info's mems.
+
+ * c-typeck.c (finish_init): Free spelling_base before
+ setting it again.
+
+ * cfgloop.c (flow_loops_find): Always free the sbitmap
+ headers.
+
+ * predict.c (estimate_probability): Free bbs after being
+ done with it.
+
+2004-01-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300.h (PREDICATE_CODES): Add
+ const_8bit_operand and call_address_operand.
+
+2004-01-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_optimize_function): Call optimize_inline_calls
+ when there is nothing to inline but warnings are requested.
+ (cgraph_decide_inlining): Fix memory leak.
+
+2004-01-02 Jan Hubicka <jh@suse.cz>
+
+ * expr.c (store_constructor): Fix pasto in previous patch.
+
+2004-01-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/cygming.h: Fix comment formatting.
+ * config/i386/djgpp.h: Likewise.
+ * config/i386/gthr-win32.c: Likewise.
+ * config/i386/i386-interix.h: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/openbsd.h: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/xm-mingw32.h: Likewise.
+
+2004-01-02 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/gcc.texi, doc/invoke.texi, doc/install.texi: Update
+ copyright and last modification dates.
+
+2004-01-02 Andreas Jaeger <aj@suse.de>, Gerald Pfeifer <gp@suse.de>
+
+ * doc/install.texi (Specific): Mention x86_64.
+
+2004-01-01 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * builtins.c (expand_builtin_apply_args_1) [STACK_GROWS_DOWNWARD]:
+ Call force_operand on plus_constant result.
+
+2004-01-01 Jan Hubicka <jh@suse.cz>
+
+ * expmed.c (store_bit_field, extract_bit_field): Use new named patterns
+ * expr.c (store_constructor): Use vec_init pattern.
+ * genopinit.c (optabs): Initailize vec_set/vec_extract/vec_init.
+ * optabs.h (optab_index): ADD OTI_vec_set/OTI_vec_extract/OTI_vec_init
+ (vec_set_optab, vec_extract_optab, vec_init_optab): New.
+ * i386.md (vec_setv2df, vec_extractv2df, vec_setv4sf, vec_extractv4sf):
+ New patterns.
+ (sse2_unpc?pd): Fix pattern.
+ (sse2_movlpd): Kill.
+ (sse2_movsd): Deal with movlpd too.
+ * i386.c (ix86_expand_builtin): Use sse2_movsd instead of sse2_movlpd.
+ (ix86_expand_vector_init): New.
+ * emmintrin.h (__mm_set_pd, __mm_set_ps): Use vector extensions.
+ * md.texi (vec_set, vec_extract): Document
+
+2003-12-31 Jan Hubicka <jh@suse.cz>
+
+ PR opt/13473
+ * recog.c (validate_replace_rtx_1): Take care for RTL sharing inside
+ ASM input operands
+
+ PR opt/12617
+ * toplev.c (dump_file_index): Reorder ce3 and bbro.
+ (dump_file): Likewise.
+ (rest_of_compilation): Likewise.
+
+ PR debug/13367
+ * cgraph.c (cgraph_function_possibly_inlined): Even with
+ flag_really_no_inline we inline always_inline functions.
+ * cgraphunit.c (cgraph_analyze_function): Clear inlinable flag
+ for non-always_inline functions when there is flag_really_no_inline.
+ (cgraph_decide_inlining): Limit work done when not inlining.
+ (cgraph_decide_inlining_incrementally): Likewise.
+ (cgraph_optimize_function): Check whether something got inlined.
+ * c-objc-common.c (c_disregard_inline_limits): Do not always inline
+ extern inline functions when not inlining.
+
+ * opts.c (decode_options): Disable crossjumping at -O1
+ * invoke.texi (-O1): Document change.
+
+See ChangeLog.10 for earlier changes.
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/ada/5xcrtl.ads b/gcc/ada/5xcrtl.ads
new file mode 100644
index 00000000000..dd3292e384a
--- /dev/null
+++ b/gcc/ada/5xcrtl.ads
@@ -0,0 +1,159 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . C R 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. --
+-- --
+-- 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 low level interface to the C Run Time Library
+-- on 64 bit VMS
+
+with System.Parameters;
+package System.CRTL is
+pragma Preelaborate (CRTL);
+
+ subtype chars is System.Address;
+ -- Pointer to null-terminated array of characters
+
+ subtype FILEs is System.Address;
+ -- Corresponds to the C type FILE*
+
+ subtype int is Integer;
+
+ type long is range -(2 ** (System.Parameters.long_bits - 1))
+ .. +(2 ** (System.Parameters.long_bits - 1)) - 1;
+
+ subtype off_t is Integer;
+
+ type size_t is mod 2 ** Standard'Address_Size;
+
+ function atoi (A : System.Address) return Integer;
+ pragma Import (C, atoi, "decc$atoi");
+
+ procedure clearerr (stream : FILEs);
+ pragma Import (C, clearerr, "decc$clearerr");
+
+ function fclose (stream : FILEs) return int;
+ pragma Import (C, fclose, "decc$fclose");
+
+ function fdopen (handle : int; mode : chars) return FILEs;
+ pragma Import (C, fdopen, "decc$fdopen");
+
+ function fflush (stream : FILEs) return int;
+ pragma Import (C, fflush, "decc$fflush");
+
+ function fgetc (stream : FILEs) return int;
+ pragma Import (C, fgetc, "decc$fgetc");
+
+ function fgets (strng : chars; n : int; stream : FILEs) return chars;
+ pragma Import (C, fgets, "decc$fgets");
+
+ function fopen (filename : chars; Mode : chars) return FILEs;
+ pragma Import (C, fopen, "decc$fopen");
+
+ function fputc (C : int; stream : FILEs) return int;
+ pragma Import (C, fputc, "decc$fputc");
+
+ function fputs (Strng : chars; Stream : FILEs) return int;
+ pragma Import (C, fputs, "decc$fputs");
+
+ procedure free (Ptr : System.Address);
+ pragma Import (C, free, "decc$free");
+
+ function freopen
+ (filename : chars;
+ mode : chars;
+ stream : FILEs)
+ return FILEs;
+ pragma Import (C, freopen, "decc$freopen");
+
+ function fseek
+ (stream : FILEs;
+ offset : long;
+ origin : int)
+ return int;
+ pragma Import (C, fseek, "decc$fseek");
+
+ function ftell (stream : FILEs) return long;
+ pragma Import (C, ftell, "decc$ftell");
+
+ function getenv (S : String) return System.Address;
+ pragma Import (C, getenv, "decc$getenv");
+
+ function isatty (handle : int) return int;
+ pragma Import (C, isatty, "decc$isatty");
+
+ function lseek (fd : int; offset : off_t; direction : int) return off_t;
+ pragma Import (C, lseek, "decc$lseek");
+
+ function malloc (Size : size_t) return System.Address;
+ pragma Import (C, malloc, "decc$_malloc64");
+
+ procedure memcpy (S1 : System.Address; S2 : System.Address; N : size_t);
+ pragma Import (C, memcpy, "decc$_memcpy64");
+
+ procedure memmove (S1 : System.Address; S2 : System.Address; N : size_t);
+ pragma Import (C, memmove, "decc$_memmove64");
+
+ procedure mktemp (template : chars);
+ pragma Import (C, mktemp, "decc$_mktemp64");
+
+ function read (fd : int; buffer : chars; nbytes : int) return int;
+ pragma Import (C, read, "decc$read");
+
+ function realloc
+ (Ptr : System.Address; Size : size_t) return System.Address;
+ pragma Import (C, realloc, "decc$_realloc64");
+
+ procedure rewind (stream : FILEs);
+ pragma Import (C, rewind, "decc$rewind");
+
+ function setvbuf
+ (stream : FILEs;
+ buffer : chars;
+ mode : int;
+ size : size_t)
+ return int;
+ pragma Import (C, setvbuf, "decc$setvbuf");
+
+ procedure tmpnam (string : chars);
+ pragma Import (C, tmpnam, "decc$_tmpnam64");
+
+ function tmpfile return FILEs;
+ pragma Import (C, tmpfile, "decc$tmpfile");
+
+ function ungetc (c : int; stream : FILEs) return int;
+ pragma Import (C, ungetc, "decc$ungetc");
+
+ function unlink (filename : chars) return int;
+ pragma Import (C, unlink, "decc$unlink");
+
+ function write (fd : int; buffer : chars; nbytes : int) return int;
+ pragma Import (C, write, "decc$write");
+end System.CRTL;
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/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-direct.adb b/gcc/ada/a-direct.adb
new file mode 100644
index 00000000000..74757fe8077
--- /dev/null
+++ b/gcc/ada/a-direct.adb
@@ -0,0 +1,926 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . D I R E C T O R I E S --
+-- --
+-- 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. --
+-- --
+-- 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.Directories.Validity; use Ada.Directories.Validity;
+with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
+with Ada.Unchecked_Deallocation;
+
+with GNAT.Directory_Operations; use GNAT.Directory_Operations;
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+with GNAT.Regexp; use GNAT.Regexp;
+
+with System;
+
+package body Ada.Directories is
+
+ type Search_Data is record
+ Is_Valid : Boolean := False;
+ Name : Ada.Strings.Unbounded.Unbounded_String;
+ Pattern : Regexp;
+ Filter : Filter_Type;
+ Dir : Dir_Type;
+ Entry_Fetched : Boolean := False;
+ Dir_Entry : Directory_Entry_Type;
+ end record;
+
+ Empty_String : constant String := (1 .. 0 => ASCII.NUL);
+
+ procedure Free is new Ada.Unchecked_Deallocation (Search_Data, Search_Ptr);
+
+ function File_Exists (Name : String) return Boolean;
+ -- Returns True if the named file exists.
+
+ procedure Fetch_Next_Entry (Search : Search_Type);
+ -- Get the next entry in a directory, setting Entry_Fetched if successful
+ -- or resetting Is_Valid if not.
+
+ ---------------
+ -- Base_Name --
+ ---------------
+
+ function Base_Name (Name : String) return String is
+ Simple : constant String := Simple_Name (Name);
+ -- Simple'First is guaranteed to be 1
+
+ begin
+ -- Look for the last dot in the file name and return the part of the
+ -- file name preceding this last dot. If the first dot is the first
+ -- character of the file name, the base name is the empty string.
+
+ for Pos in reverse Simple'Range loop
+ if Simple (Pos) = '.' then
+ return Simple (1 .. Pos - 1);
+ end if;
+ end loop;
+
+ -- If there is no dot, return the complete file name
+
+ return Simple;
+ end Base_Name;
+
+ -------------
+ -- Compose --
+ -------------
+
+ function Compose
+ (Containing_Directory : String := "";
+ Name : String;
+ Extension : String := "") return String
+ is
+ Result : String (1 ..
+ Containing_Directory'Length +
+ Name'Length + Extension'Length + 2);
+ Last : Natural;
+
+ begin
+ -- First, deal with the invalid cases
+
+ if not Is_Valid_Path_Name (Containing_Directory) then
+ raise Name_Error;
+
+ elsif
+ Extension'Length = 0 and then (not Is_Valid_Simple_Name (Name))
+ then
+ raise Name_Error;
+
+ elsif Extension'Length /= 0 and then
+ (not Is_Valid_Simple_Name (Name & '.' & Extension))
+ then
+ raise Name_Error;
+
+ -- This is not an invalid case. Build the path name.
+
+ else
+ Last := Containing_Directory'Length;
+ Result (1 .. Last) := Containing_Directory;
+
+ -- Add a directory separator if needed
+
+ if Result (Last) /= Dir_Separator then
+ Last := Last + 1;
+ Result (Last) := Dir_Separator;
+ end if;
+
+ -- Add the file name
+
+ Result (Last + 1 .. Last + Name'Length) := Name;
+ Last := Last + Name'Length;
+
+ -- If extension was specified, add dot followed by this extension
+
+ if Extension'Length /= 0 then
+ Last := Last + 1;
+ Result (Last) := '.';
+ Result (Last + 1 .. Last + Extension'Length) := Extension;
+ Last := Last + Extension'Length;
+ end if;
+
+ return Result (1 .. Last);
+ end if;
+ end Compose;
+
+ --------------------------
+ -- Containing_Directory --
+ --------------------------
+
+ function Containing_Directory (Name : String) return String is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error;
+
+ else
+ -- Get the directory name using GNAT.Directory_Operations.Dir_Name
+
+ declare
+ Value : constant String := Dir_Name (Path => Name);
+ Result : String (1 .. Value'Length);
+ Last : Natural := Result'Last;
+
+ begin
+ Result := Value;
+
+ -- Remove any trailing directory separator, except as the first
+ -- character.
+
+ while Last > 1 and then Result (Last) = Dir_Separator loop
+ Last := Last - 1;
+ end loop;
+
+ -- Special case of current directory, identified by "."
+
+ if Last = 1 and then Result (1) = '.' then
+ return Get_Current_Dir;
+
+ else
+ return Result (1 .. Last);
+ end if;
+ end;
+ end if;
+ end Containing_Directory;
+
+ ---------------
+ -- Copy_File --
+ ---------------
+
+ procedure Copy_File
+ (Source_Name : String;
+ Target_Name : String;
+ Form : String := "")
+ is
+ pragma Unreferenced (Form);
+ Success : Boolean;
+
+ begin
+ -- First, the invalid cases
+
+ if (not Is_Valid_Path_Name (Source_Name)) or else
+ (not Is_Valid_Path_Name (Target_Name)) or else
+ (not Is_Regular_File (Source_Name))
+ then
+ raise Name_Error;
+
+ elsif Is_Directory (Target_Name) then
+ raise Use_Error;
+
+ else
+ -- The implementation uses GNAT.OS_Lib.Copy_File, with parameters
+ -- suitable for all platforms.
+
+ Copy_File
+ (Source_Name, Target_Name, Success, Overwrite, None);
+
+ if not Success then
+ raise Use_Error;
+ end if;
+ end if;
+ end Copy_File;
+
+ ----------------------
+ -- Create_Directory --
+ ----------------------
+
+ procedure Create_Directory
+ (New_Directory : String;
+ Form : String := "")
+ is
+ pragma Unreferenced (Form);
+
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (New_Directory) then
+ raise Name_Error;
+
+ else
+ -- The implementation uses GNAT.Directory_Operations.Make_Dir
+
+ begin
+ Make_Dir (Dir_Name => New_Directory);
+
+ exception
+ when Directory_Error =>
+ raise Use_Error;
+ end;
+ end if;
+ end Create_Directory;
+
+ -----------------
+ -- Create_Path --
+ -----------------
+
+ procedure Create_Path
+ (New_Directory : String;
+ Form : String := "")
+ is
+ pragma Unreferenced (Form);
+
+ New_Dir : String (1 .. New_Directory'Length + 1);
+ Last : Positive := 1;
+
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (New_Directory) then
+ raise Name_Error;
+
+ else
+ -- Build New_Dir with a directory separator at the end, so that the
+ -- complete path will be found in the loop below.
+
+ New_Dir (1 .. New_Directory'Length) := New_Directory;
+ New_Dir (New_Dir'Last) := Directory_Separator;
+
+ -- Create, if necessary, each directory in the path
+
+ for J in 2 .. New_Dir'Last loop
+
+ -- Look for the end of an intermediate directory
+
+ if New_Dir (J) /= Dir_Separator then
+ Last := J;
+
+ -- We have found a new intermediate directory each time we find
+ -- a first directory separator.
+
+ elsif New_Dir (J - 1) /= Dir_Separator then
+
+ -- No need to create the directory if it already exists
+
+ if Is_Directory (New_Dir (1 .. Last)) then
+ null;
+
+ -- It is an error if a file with such a name already exists
+
+ elsif Is_Regular_File (New_Dir (1 .. Last)) then
+ raise Use_Error;
+
+ else
+ -- The implementation uses
+ -- GNAT.Directory_Operations.Make_Dir.
+
+ begin
+ Make_Dir (Dir_Name => New_Dir (1 .. Last));
+
+ exception
+ when Directory_Error =>
+ raise Use_Error;
+ end;
+ end if;
+ end if;
+ end loop;
+ end if;
+ end Create_Path;
+
+ -----------------------
+ -- Current_Directory --
+ -----------------------
+
+ function Current_Directory return String is
+ begin
+ -- The implementation uses GNAT.Directory_Operations.Get_Current_Dir
+
+ return Get_Current_Dir;
+ end Current_Directory;
+
+ ----------------------
+ -- Delete_Directory --
+ ----------------------
+
+ procedure Delete_Directory (Directory : String) is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Directory) then
+ raise Name_Error;
+
+ else
+ -- The implementation uses GNAT.Directory_Operations.Remove_Dir
+
+ begin
+ Remove_Dir (Dir_Name => Directory, Recursive => False);
+
+ exception
+ when Directory_Error =>
+ raise Use_Error;
+ end;
+ end if;
+ end Delete_Directory;
+
+ -----------------
+ -- Delete_File --
+ -----------------
+
+ procedure Delete_File (Name : String) is
+ Success : Boolean;
+
+ begin
+ -- First, the invalid cases
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error;
+
+ elsif not Is_Regular_File (Name) then
+ raise Name_Error;
+
+ else
+ -- The implementation uses GNAT.OS_Lib.Delete_File
+
+ Delete_File (Name, Success);
+
+ if not Success then
+ raise Use_Error;
+ end if;
+ end if;
+ end Delete_File;
+
+ -----------------
+ -- Delete_Tree --
+ -----------------
+
+ procedure Delete_Tree (Directory : String) is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Directory) then
+ raise Name_Error;
+
+ else
+ -- The implementation uses GNAT.Directory_Operations.Remove_Dir
+
+ begin
+ Remove_Dir (Directory, Recursive => True);
+
+ exception
+ when Directory_Error =>
+ raise Use_Error;
+ end;
+ end if;
+ end Delete_Tree;
+
+ ------------
+ -- Exists --
+ ------------
+
+ function Exists (Name : String) return Boolean is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error;
+
+ else
+ -- The implementation is in File_Exists
+
+ return File_Exists (Name);
+ end if;
+ end Exists;
+
+ ---------------
+ -- Extension --
+ ---------------
+
+ function Extension (Name : String) return String is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error;
+
+ else
+ -- Look fir the first dot that is not followed by a directory
+ -- separator.
+
+ for Pos in reverse Name'Range loop
+
+ -- If a directory separator is found before a dot, there is no
+ -- extension.
+
+ if Name (Pos) = Dir_Separator then
+ return Empty_String;
+
+ elsif Name (Pos) = '.' then
+
+ -- We found a dot, build the return value with lower bound 1
+
+ declare
+ Result : String (1 .. Name'Last - Pos);
+ begin
+ Result := Name (Pos + 1 .. Name'Last);
+ return Result;
+ end;
+ end if;
+ end loop;
+
+ -- No dot were found, there is no extension
+
+ return Empty_String;
+ end if;
+ end Extension;
+
+ ----------------------
+ -- Fetch_Next_Entry --
+ ----------------------
+
+ procedure Fetch_Next_Entry (Search : Search_Type) is
+ Name : String (1 .. 255);
+ Last : Natural;
+ Kind : File_Kind;
+
+ begin
+ -- Search.Value.Is_Valid is always True when Fetch_Next_Entry is called
+
+ loop
+ Read (Search.Value.Dir, Name, Last);
+
+ -- If no matching entry is found, set Is_Valid to False
+
+ if Last = 0 then
+ Search.Value.Is_Valid := False;
+ exit;
+ end if;
+
+ -- Check if the entry matches the pattern
+
+ if Match (Name (1 .. Last), Search.Value.Pattern) then
+ declare
+ Full_Name : constant String :=
+ Compose
+ (To_String
+ (Search.Value.Name), Name (1 .. Last));
+ Found : Boolean := False;
+
+ begin
+ if File_Exists (Full_Name) then
+
+ -- Now check if the file kind matches the filter
+
+ if Is_Regular_File (Full_Name) then
+ if Search.Value.Filter (Ordinary_File) then
+ Kind := Ordinary_File;
+ Found := True;
+ end if;
+
+ elsif Is_Directory (Full_Name) then
+ if Search.Value.Filter (Directory) then
+ Kind := Directory;
+ Found := True;
+ end if;
+
+ elsif Search.Value.Filter (Special_File) then
+ Kind := Special_File;
+ Found := True;
+ end if;
+
+ -- If it does, update Search and return
+
+ if Found then
+ Search.Value.Entry_Fetched := True;
+ Search.Value.Dir_Entry :=
+ (Is_Valid => True,
+ Simple => To_Unbounded_String (Name (1 .. Last)),
+ Full => To_Unbounded_String (Full_Name),
+ Kind => Kind);
+ exit;
+ end if;
+ end if;
+ end;
+ end if;
+ end loop;
+ end Fetch_Next_Entry;
+
+ -----------------
+ -- File_Exists --
+ -----------------
+
+ function File_Exists (Name : String) return Boolean is
+ function C_File_Exists (A : System.Address) return Integer;
+ pragma Import (C, C_File_Exists, "__gnat_file_exists");
+
+ C_Name : String (1 .. Name'Length + 1);
+
+ begin
+ C_Name (1 .. Name'Length) := Name;
+ C_Name (C_Name'Last) := ASCII.NUL;
+
+ return C_File_Exists (C_Name (1)'Address) = 1;
+ end File_Exists;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Search : in out Search_Type) is
+ begin
+ if Search.Value /= null then
+
+ -- Close the directory, if one is open
+
+ if Is_Open (Search.Value.Dir) then
+ Close (Search.Value.Dir);
+ end if;
+
+ Free (Search.Value);
+ end if;
+ end Finalize;
+
+ ---------------
+ -- Full_Name --
+ ---------------
+
+ function Full_Name (Name : String) return String is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error;
+
+ else
+ -- Build the return value with lower bound 1.
+ -- Use GNAT.OS_Lib.Normalize_Pathname.
+
+ declare
+ Value : constant String := Normalize_Pathname (Name);
+ Result : String (1 .. Value'Length);
+ begin
+ Result := Value;
+ return Result;
+ end;
+ end if;
+ end Full_Name;
+
+ function Full_Name (Directory_Entry : Directory_Entry_Type) return String is
+ begin
+ -- First, the invalid case
+
+ if not Directory_Entry.Is_Valid then
+ raise Status_Error;
+
+ else
+ -- The value to return has already been computed
+
+ return To_String (Directory_Entry.Full);
+ end if;
+ end Full_Name;
+
+ --------------------
+ -- Get_Next_Entry --
+ --------------------
+
+ procedure Get_Next_Entry
+ (Search : in out Search_Type;
+ Directory_Entry : out Directory_Entry_Type)
+ is
+ begin
+ -- First, the invalid case
+
+ if Search.Value = null or else not Search.Value.Is_Valid then
+ raise Status_Error;
+ end if;
+
+ -- Fetch the next entry, if needed
+
+ if not Search.Value.Entry_Fetched then
+ Fetch_Next_Entry (Search);
+ end if;
+
+ -- It is an error if no valid entry is found
+
+ if not Search.Value.Is_Valid then
+ raise Status_Error;
+
+ else
+ -- Reset Entry_Fatched and return the entry
+
+ Search.Value.Entry_Fetched := False;
+ Directory_Entry := Search.Value.Dir_Entry;
+ end if;
+ end Get_Next_Entry;
+
+ ----------
+ -- Kind --
+ ----------
+
+ function Kind (Name : String) return File_Kind is
+ begin
+ -- First, the invalid case
+
+ if not File_Exists (Name) then
+ raise Name_Error;
+
+ elsif Is_Regular_File (Name) then
+ return Ordinary_File;
+
+ elsif Is_Directory (Name) then
+ return Directory;
+
+ else
+ return Special_File;
+ end if;
+ end Kind;
+
+ function Kind (Directory_Entry : Directory_Entry_Type) return File_Kind is
+ begin
+ -- First, the invalid case
+
+ if not Directory_Entry.Is_Valid then
+ raise Status_Error;
+
+ else
+ -- The value to return has already be computed
+
+ return Directory_Entry.Kind;
+ end if;
+ end Kind;
+
+ -----------------------
+ -- Modification_Time --
+ -----------------------
+
+ function Modification_Time (Name : String) return Ada.Calendar.Time is
+ Date : OS_Time;
+ Year : Year_Type;
+ Month : Month_Type;
+ Day : Day_Type;
+ Hour : Hour_Type;
+ Minute : Minute_Type;
+ Second : Second_Type;
+
+ begin
+ -- First, the invalid cases
+
+
+ if not (Is_Regular_File (Name) or else Is_Directory (Name)) then
+ raise Name_Error;
+
+ else
+ Date := File_Time_Stamp (Name);
+ -- ???? We need to be able to convert OS_Time to Ada.Calendar.Time
+ -- For now, use the component of the OS_Time to create the
+ -- Calendar.Time value.
+
+ GM_Split (Date, Year, Month, Day, Hour, Minute, Second);
+
+ return Ada.Calendar.Time_Of
+ (Year, Month, Day, Duration (Second + 60 * (Minute + 60 * Hour)));
+ end if;
+ end Modification_Time;
+
+ function Modification_Time
+ (Directory_Entry : Directory_Entry_Type) return Ada.Calendar.Time
+ is
+ begin
+ -- First, the invalid case
+
+ if not Directory_Entry.Is_Valid then
+ raise Status_Error;
+
+ else
+ -- The value to return has already be computed
+
+ return Modification_Time (To_String (Directory_Entry.Full));
+ end if;
+ end Modification_Time;
+
+ ------------------
+ -- More_Entries --
+ ------------------
+
+ function More_Entries (Search : Search_Type) return Boolean is
+ begin
+ if Search.Value = null then
+ return False;
+
+ elsif Search.Value.Is_Valid then
+
+ -- Fetch the next entry, if needed
+
+ if not Search.Value.Entry_Fetched then
+ Fetch_Next_Entry (Search);
+ end if;
+ end if;
+
+ return Search.Value.Is_Valid;
+ end More_Entries;
+
+ ------------
+ -- Rename --
+ ------------
+
+ procedure Rename (Old_Name, New_Name : String) is
+ Success : Boolean;
+
+ begin
+ -- First, the invalid cases
+
+ if not Is_Valid_Path_Name (Old_Name)
+ or else not Is_Valid_Path_Name (New_Name)
+ or else (not Is_Regular_File (Old_Name)
+ and then not Is_Directory (Old_Name))
+ then
+ raise Name_Error;
+
+ elsif Is_Regular_File (New_Name) or Is_Directory (New_Name) then
+ raise Use_Error;
+
+ else
+ -- The implemewntation uses GNAT.OS_Lib.Rename_File
+
+ Rename_File (Old_Name, New_Name, Success);
+
+ if not Success then
+ raise Use_Error;
+ end if;
+ end if;
+ end Rename;
+
+ -------------------
+ -- Set_Directory --
+ -------------------
+
+ procedure Set_Directory (Directory : String) is
+ begin
+ -- The implementation uses GNAT.Directory_Operations.Change_Dir
+
+ Change_Dir (Dir_Name => Directory);
+
+ exception
+ when Directory_Error =>
+ raise Name_Error;
+ end Set_Directory;
+
+ -----------------
+ -- Simple_Name --
+ -----------------
+
+ function Simple_Name (Name : String) return String is
+ begin
+ -- First, the invalid case
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error;
+
+ else
+ -- Build the value to return with lower bound 1.
+ -- The implementation uses GNAT.Directory_Operations.Base_Name.
+
+ declare
+ Value : constant String :=
+ GNAT.Directory_Operations.Base_Name (Name);
+ Result : String (1 .. Value'Length);
+ begin
+ Result := Value;
+ return Result;
+ end;
+ end if;
+ end Simple_Name;
+
+ function Simple_Name
+ (Directory_Entry : Directory_Entry_Type) return String
+ is
+ begin
+ -- First, the invalid case
+
+ if not Directory_Entry.Is_Valid then
+ raise Status_Error;
+
+ else
+ -- The value to return has already be computed
+
+ return To_String (Directory_Entry.Simple);
+ end if;
+ end Simple_Name;
+
+ ----------
+ -- Size --
+ ----------
+
+ function Size (Name : String) return File_Size is
+ C_Name : String (1 .. Name'Length + 1);
+
+ function C_Size (Name : System.Address) return File_Size;
+ pragma Import (C, C_Size, "__gnat_named_file_length");
+
+ begin
+ -- First, the invalid case
+
+ if not Is_Regular_File (Name) then
+ raise Name_Error;
+
+ else
+ C_Name (1 .. Name'Length) := Name;
+ C_Name (C_Name'Last) := ASCII.NUL;
+ return C_Size (C_Name'Address);
+ end if;
+ end Size;
+
+ function Size (Directory_Entry : Directory_Entry_Type) return File_Size is
+ begin
+ -- First, the invalid case
+
+ if not Directory_Entry.Is_Valid then
+ raise Status_Error;
+
+ else
+ -- The value to return has already be computed
+
+ return Size (To_String (Directory_Entry.Full));
+ end if;
+ end Size;
+
+ ------------------
+ -- Start_Search --
+ ------------------
+
+ procedure Start_Search
+ (Search : in out Search_Type;
+ Directory : String;
+ Pattern : String;
+ Filter : Filter_Type := (others => True))
+ is
+ begin
+ -- First, the invalid case
+
+ if not Is_Directory (Directory) then
+ raise Name_Error;
+ end if;
+
+ -- If needed, finalize Search
+
+ Finalize (Search);
+
+ -- Allocate the default data
+
+ Search.Value := new Search_Data;
+
+ begin
+ -- Check the pattern
+
+ Search.Value.Pattern := Compile (Pattern, Glob => True);
+
+ exception
+ when Error_In_Regexp =>
+ raise Name_Error;
+ end;
+
+ -- Initialize some Search components
+
+ Search.Value.Filter := Filter;
+ Search.Value.Name := To_Unbounded_String (Full_Name (Directory));
+ Open (Search.Value.Dir, Directory);
+ Search.Value.Is_Valid := True;
+ end Start_Search;
+
+end Ada.Directories;
+
diff --git a/gcc/ada/a-direct.ads b/gcc/ada/a-direct.ads
new file mode 100644
index 00000000000..d71e49357ed
--- /dev/null
+++ b/gcc/ada/a-direct.ads
@@ -0,0 +1,415 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . D I R E C T O R I E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived for use with GNAT from AI-00248, which is --
+-- expected to be a part of a future expected revised Ada Reference Manual. --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- Ada 2005: Implementation of Ada.Directories (AI95-00248). Note that this
+-- unit is available without -gnat05. That seems reasonable, since you only
+-- get it if you explicitly ask for it.
+
+-- External files may be classified as directories, special files, or ordinary
+-- files. A directory is an external file that is a container for files on
+-- the target system. A special file is an external file that cannot be
+-- created or read by a predefined Ada Input-Output package. External files
+-- that are not special files or directories are called ordinary files.
+
+-- A file name is a string identifying an external file. Similarly, a
+-- directory name is a string identifying a directory. The interpretation of
+-- file names and directory names is implementation-defined.
+
+-- The full name of an external file is a full specification of the name of
+-- the file. If the external environment allows alternative specifications of
+-- the name (for example, abbreviations), the full name should not use such
+-- alternatives. A full name typically will include the names of all of
+-- directories that contain the item. The simple name of an external file is
+-- the name of the item, not including any containing directory names. Unless
+-- otherwise specified, a file name or directory name parameter to a
+-- predefined Ada input-output subprogram can be a full name, a simple name,
+-- or any other form of name supported by the implementation.
+
+-- The default directory is the directory that is used if a directory or
+-- file name is not a full name (that is, when the name does not fully
+-- identify all of the containing directories).
+
+-- A directory entry is a single item in a directory, identifying a single
+-- external file (including directories and special files).
+
+-- For each function that returns a string, the lower bound of the returned
+-- value is 1.
+
+with Ada.Calendar;
+with Ada.Finalization;
+with Ada.IO_Exceptions;
+with Ada.Strings.Unbounded;
+
+package Ada.Directories is
+
+ -----------------------------------
+ -- Directory and File Operations --
+ -----------------------------------
+
+ function Current_Directory return String;
+ -- Returns the full directory name for the current default directory. The
+ -- name returned shall be suitable for a future call to Set_Directory.
+ -- The exception Use_Error is propagated if a default directory is not
+ -- supported by the external environment.
+
+ procedure Set_Directory (Directory : String);
+ -- Sets the current default directory. The exception Name_Error is
+ -- propagated if the string given as Directory does not identify an
+ -- existing directory. The exception Use_Error is propagated if the
+ -- external environment does not support making Directory (in the absence
+ -- of Name_Error) a default directory.
+
+ procedure Create_Directory
+ (New_Directory : String;
+ Form : String := "");
+ -- Creates a directory with name New_Directory. The Form parameter can be
+ -- used to give system-dependent characteristics of the directory; the
+ -- interpretation of the Form parameter is implementation-defined. A null
+ -- string for Form specifies the use of the default options of the
+ -- implementation of the new directory. The exception Name_Error is
+ -- propagated if the string given as New_Directory does not allow the
+ -- identification of a directory. The exception Use_Error is propagated if
+ -- the external environment does not support the creation of a directory
+ -- with the given name (in the absence of Name_Error) and form.
+
+ procedure Delete_Directory (Directory : String);
+ -- Deletes an existing empty directory with name Directory. The exception
+ -- Name_Error is propagated if the string given as Directory does not
+ -- identify an existing directory. The exception Use_Error is propagated
+ -- if the external environment does not support the deletion of the
+ -- directory (or some portion of its contents) with the given name (in the
+ -- absence of Name_Error).
+
+ procedure Create_Path
+ (New_Directory : String;
+ Form : String := "");
+ -- Creates zero or more directories with name New_Directory. Each
+ -- non-existent directory named by New_Directory is created. For example,
+ -- on a typical Unix system, Create_Path ("/usr/me/my"); would create
+ -- directory "me" in directory "usr", then create directory "my" in
+ -- directory "me". The Form can be used to give system-dependent
+ -- characteristics of the directory; the interpretation of the Form
+ -- parameter is implementation-defined. A null string for Form specifies
+ -- the use of the default options of the implementation of the new
+ -- directory. The exception Name_Error is propagated if the string given
+ -- as New_Directory does not allow the identification of any directory.
+ -- The exception Use_Error is propagated if the external environment does
+ -- not support the creation of any directories with the given name (in the
+ -- absence of Name_Error) and form.
+
+ procedure Delete_Tree (Directory : String);
+ -- Deletes an existing directory with name Directory. The directory and
+ -- all of its contents (possibly including other directories) are deleted.
+ -- The exception Name_Error is propagated if the string given as Directory
+ -- does not identify an existing directory. The exception Use_Error is
+ -- propagated if the external environment does not support the deletion of
+ -- the directory or some portion of its contents with the given name (in
+ -- the absence of Name_Error). If Use_Error is propagated, it is
+ -- unspecified if a portion of the contents of the directory are deleted.
+
+ procedure Delete_File (Name : String);
+ -- Deletes an existing ordinary or special file with Name. The exception
+ -- Name_Error is propagated if the string given as Name does not identify
+ -- an existing ordinary or special external file. The exception Use_Error
+ -- is propagated if the external environment does not support the deletion
+ -- of the file with the given name (in the absence of Name_Error).
+
+ procedure Rename (Old_Name, New_Name : String);
+ -- Renames an existing external file (including directories) with Old_Name
+ -- to New_Name. The exception Name_Error is propagated if the string given
+ -- as Old_Name does not identify an existing external file. The exception
+ -- Use_Error is propagated if the external environment does not support the
+ -- renaming of the file with the given name (in the absence of Name_Error).
+ -- In particular, Use_Error is propagated if a file or directory already
+ -- exists with New_Name.
+
+ procedure Copy_File
+ (Source_Name : String;
+ Target_Name : String;
+ Form : String := "");
+ -- Copies the contents of the existing external file with Source_Name
+ -- to Target_Name. The resulting external file is a duplicate of the source
+ -- external file. The Form can be used to give system-dependent
+ -- characteristics of the resulting external file; the interpretation of
+ -- the Form parameter is implementation-defined. Exception Name_Error is
+ -- propagated if the string given as Source_Name does not identify an
+ -- existing external ordinary or special file or if the string given as
+ -- Target_Name does not allow the identification of an external file.
+ -- The exception Use_Error is propagated if the external environment does
+ -- not support the creating of the file with the name given by Target_Name
+ -- and form given by Form, or copying of the file with the name given by
+ -- Source_Name (in the absence of Name_Error).
+
+
+ -- File and directory name operations:
+
+ function Full_Name (Name : String) return String;
+ -- Returns the full name corresponding to the file name specified by Name.
+ -- The exception Name_Error is propagated if the string given as Name does
+ -- not allow the identification of an external file (including directories
+ -- and special files).
+
+ function Simple_Name (Name : String) return String;
+ -- Returns the simple name portion of the file name specified by Name. The
+ -- exception Name_Error is propagated if the string given as Name does not
+ -- allow the identification of an external file (including directories and
+ -- special files).
+
+ function Containing_Directory (Name : String) return String;
+ -- Returns the name of the containing directory of the external file
+ -- (including directories) identified by Name. If more than one directory
+ -- can contain Name, the directory name returned is implementation-defined.
+ -- The exception Name_Error is propagated if the string given as Name does
+ -- not allow the identification of an external file. The exception
+ -- Use_Error is propagated if the external file does not have a containing
+ -- directory.
+
+ function Extension (Name : String) return String;
+ -- Returns the extension name corresponding to Name. The extension name is
+ -- a portion of a simple name (not including any separator characters),
+ -- typically used to identify the file class. If the external environment
+ -- does not have extension names, then the null string is returned.
+ -- The exception Name_Error is propagated if the string given as Name does
+ -- not allow the identification of an external file.
+
+ function Base_Name (Name : String) return String;
+ -- Returns the base name corresponding to Name. The base name is the
+ -- remainder of a simple name after removing any extension and extension
+ -- separators. The exception Name_Error is propagated if the string given
+ -- as Name does not allow the identification of an external file
+ -- (including directories and special files).
+
+ function Compose
+ (Containing_Directory : String := "";
+ Name : String;
+ Extension : String := "") return String;
+ -- Returns the name of the external file with the specified
+ -- Containing_Directory, Name, and Extension. If Extension is the null
+ -- string, then Name is interpreted as a simple name; otherwise Name is
+ -- interpreted as a base name. The exception Name_Error is propagated if
+ -- the string given as Containing_Directory is not null and does not allow
+ -- the identification of a directory, or if the string given as Extension
+ -- is not null and is not a possible extension, or if the string given as
+ -- Name is not a possible simple name (if Extension is null) or base name
+ -- (if Extension is non-null).
+
+
+ -- File and directory queries:
+
+ type File_Kind is (Directory, Ordinary_File, Special_File);
+ -- The type File_Kind represents the kind of file represented by an
+ -- external file or directory.
+
+ type File_Size is range 0 .. Long_Long_Integer'Last;
+ -- The type File_Size represents the size of an external file.
+
+ function Exists (Name : String) return Boolean;
+ -- Returns True if external file represented by Name exists, and False
+ -- otherwise. The exception Name_Error is propagated if the string given as
+ -- Name does not allow the identification of an external file (including
+ -- directories and special files).
+
+ function Kind (Name : String) return File_Kind;
+ -- Returns the kind of external file represented by Name. The exception
+ -- Name_Error is propagated if the string given as Name does not allow the
+ -- identification of an existing external file.
+
+ function Size (Name : String) return File_Size;
+ -- Returns the size of the external file represented by Name. The size of
+ -- an external file is the number of stream elements contained in the file.
+ -- If the external file is discontiguous (not all elements exist), the
+ -- result is implementation-defined. If the external file is not an
+ -- ordinary file, the result is implementation-defined. The exception
+ -- Name_Error is propagated if the string given as Name does not allow the
+ -- identification of an existing external file. The exception
+ -- Constraint_Error is propagated if the file size is not a value of type
+ -- File_Size.
+
+ function Modification_Time (Name : String) return Ada.Calendar.Time;
+ -- Returns the time that the external file represented by Name was most
+ -- recently modified. If the external file is not an ordinary file, the
+ -- result is implementation-defined. The exception Name_Error is propagated
+ -- if the string given as Name does not allow the identification of an
+ -- existing external file. The exception Use_Error is propagated if the
+ -- external environment does not support the reading the modification time
+ -- of the file with the name given by Name (in the absence of Name_Error).
+
+ -------------------------
+ -- Directory Searching --
+ -------------------------
+
+ type Directory_Entry_Type is limited private;
+ -- The type Directory_Entry_Type represents a single item in a directory.
+ -- These items can only be created by the Get_Next_Entry procedure in this
+ -- package. Information about the item can be obtained from the functions
+ -- declared in this package. A default initialized object of this type is
+ -- invalid; objects returned from Get_Next_Entry are valid.
+
+ type Filter_Type is array (File_Kind) of Boolean;
+ -- The type Filter_Type specifies which directory entries are provided from
+ -- a search operation. If the Directory component is True, directory
+ -- entries representing directories are provided. If the Ordinary_File
+ -- component is True, directory entries representing ordinary files are
+ -- provided. If the Special_File component is True, directory entries
+ -- representing special files are provided.
+
+ type Search_Type is limited private;
+ -- The type Search_Type contains the state of a directory search. A
+ -- default-initialized Search_Type object has no entries available
+ -- (More_Entries returns False).
+
+ procedure Start_Search
+ (Search : in out Search_Type;
+ Directory : String;
+ Pattern : String;
+ Filter : Filter_Type := (others => True));
+ -- Starts a search in the directory entry in the directory named by
+ -- Directory for entries matching Pattern. Pattern represents a file name
+ -- matching pattern. If Pattern is null, all items in the directory are
+ -- matched; otherwise, the interpretation of Pattern is
+ -- implementation-defined. Only items which match Filter will be returned.
+ -- After a successful call on Start_Search, the object Search may have
+ -- entries available, but it may have no entries available if no files or
+ -- directories match Pattern and Filter. The exception Name_Error is
+ -- propagated if the string given by Directory does not identify an
+ -- existing directory, or if Pattern does not allow the identification of
+ -- any possible external file or directory. The exception Use_Error is
+ -- propagated if the external environment does not support the searching
+ -- of the directory with the given name (in the absence of Name_Error).
+
+ procedure End_Search (Search : in out Search_Type);
+ -- Ends the search represented by Search. After a successful call on
+ -- End_Search, the object Search will have no entries available.
+
+ function More_Entries (Search : Search_Type) return Boolean;
+ -- Returns True if more entries are available to be returned by a call
+ -- to Get_Next_Entry for the specified search object, and False otherwise.
+
+ procedure Get_Next_Entry
+ (Search : in out Search_Type;
+ Directory_Entry : out Directory_Entry_Type);
+ -- Returns the next Directory_Entry for the search described by Search that
+ -- matches the pattern and filter. If no further matches are available,
+ -- Status_Error is raised. It is implementation-defined as to whether the
+ -- results returned by this routine are altered if the contents of the
+ -- directory are altered while the Search object is valid (for example, by
+ -- another program). The exception Use_Error is propagated if the external
+ -- environment does not support continued searching of the directory
+ -- represented by Search.
+
+ -------------------------------------
+ -- Operations on Directory Entries --
+ -------------------------------------
+
+ function Simple_Name (Directory_Entry : Directory_Entry_Type) return String;
+ -- Returns the simple external name of the external file (including
+ -- directories) represented by Directory_Entry. The format of the name
+ -- returned is implementation-defined. The exception Status_Error is
+ -- propagated if Directory_Entry is invalid.
+
+ function Full_Name (Directory_Entry : Directory_Entry_Type) return String;
+ -- Returns the full external name of the external file (including
+ -- directories) represented by Directory_Entry. The format of the name
+ -- returned is implementation-defined. The exception Status_Error is
+ -- propagated if Directory_Entry is invalid.
+
+ function Kind (Directory_Entry : Directory_Entry_Type) return File_Kind;
+ -- Returns the kind of external file represented by Directory_Entry. The
+ -- exception Status_Error is propagated if Directory_Entry is invalid.
+
+ function Size (Directory_Entry : Directory_Entry_Type) return File_Size;
+ -- Returns the size of the external file represented by Directory_Entry.
+ -- The size of an external file is the number of stream elements contained
+ -- in the file. If the external file is discontiguous (not all elements
+ -- exist), the result is implementation-defined. If the external file
+ -- represented by Directory_Entry is not an ordinary file, the result is
+ -- implementation-defined. The exception Status_Error is propagated if
+ -- Directory_Entry is invalid. The exception Constraint_Error is propagated
+ -- if the file size is not a value of type File_Size.
+
+ function Modification_Time
+ (Directory_Entry : Directory_Entry_Type) return Ada.Calendar.Time;
+ -- Returns the time that the external file represented by Directory_Entry
+ -- was most recently modified. If the external file represented by
+ -- Directory_Entry is not an ordinary file, the result is
+ -- implementation-defined. The exception Status_Error is propagated if
+ -- Directory_Entry is invalid. The exception Use_Error is propagated if
+ -- the external environment does not support the reading the modification
+ -- time of the file represented by Directory_Entry.
+
+ ----------------
+ -- Exceptions --
+ ----------------
+
+ Status_Error : exception renames Ada.IO_Exceptions.Status_Error;
+ Name_Error : exception renames Ada.IO_Exceptions.Name_Error;
+ Use_Error : exception renames Ada.IO_Exceptions.Use_Error;
+ Device_Error : exception renames Ada.IO_Exceptions.Device_Error;
+
+private
+ type Directory_Entry_Type is record
+ Is_Valid : Boolean := False;
+ Simple : Ada.Strings.Unbounded.Unbounded_String;
+ Full : Ada.Strings.Unbounded.Unbounded_String;
+ Kind : File_Kind;
+ end record;
+
+ -- The type Search_Data is defined in the body, so that the spec does not
+ -- depend on packages of the GNAT hierarchy.
+
+ type Search_Data;
+ type Search_Ptr is access Search_Data;
+
+ -- Search_Type need to be a controlled type, because it includes component
+ -- of type Dir_Type (in GNAT.Directory_Operations) that need to be closed
+ -- (if opened) during finalization.
+ -- The component need to be an access value, because Search_Data is not
+ -- fully defined in the spec.
+
+ type Search_Type is new Ada.Finalization.Controlled with record
+ Value : Search_Ptr;
+ end record;
+
+ procedure Finalize (Search : in out Search_Type);
+ -- Close the directory, if opened, and deallocate Value.
+
+ procedure End_Search (Search : in out Search_Type) renames Finalize;
+
+end Ada.Directories;
+
+
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-dirval.adb b/gcc/ada/a-dirval.adb
new file mode 100644
index 00000000000..f0740d2c0e0
--- /dev/null
+++ b/gcc/ada/a-dirval.adb
@@ -0,0 +1,90 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 --
+-- (POSIX 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 POSIX version of this package
+
+package body Ada.Directories.Validity is
+
+ ------------------------
+ -- Is_Valid_Path_Name --
+ ------------------------
+
+ function Is_Valid_Path_Name (Name : String) return Boolean is
+ begin
+ -- A path name cannot be empty and cannot contain any NUL character
+
+ if Name'Length = 0 then
+ return False;
+
+ else
+ for J in Name'Range loop
+ if Name (J) = ASCII.NUL then
+ return False;
+ end if;
+ end loop;
+ end if;
+
+ -- If Name does not contain any NUL character, it is valid
+
+ return True;
+ end Is_Valid_Path_Name;
+
+ --------------------------
+ -- Is_Valid_Simple_Name --
+ --------------------------
+
+ function Is_Valid_Simple_Name (Name : String) return Boolean is
+ begin
+ -- A file name cannot be empty and cannot contain a slash ('/') or
+ -- the NUL character.
+
+ if Name'Length = 0 then
+ return False;
+
+ else
+ for J in Name'Range loop
+ if Name (J) = '/' or else Name (J) = ASCII.NUL then
+ return False;
+ end if;
+ end loop;
+ end if;
+
+ -- If Name does not contain any slash or NUL, it is valid
+
+ return True;
+ end Is_Valid_Simple_Name;
+
+end Ada.Directories.Validity;
+
+
diff --git a/gcc/ada/a-dirval.ads b/gcc/ada/a-dirval.ads
new file mode 100644
index 00000000000..23d681cdbfd
--- /dev/null
+++ b/gcc/ada/a-dirval.ads
@@ -0,0 +1,47 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 --
+-- --
+-- 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. --
+-- --
+-- 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 private child package is used in the body of Ada.Directories.
+-- It has several bodies, for different platforms.
+
+private package Ada.Directories.Validity is
+
+ function Is_Valid_Simple_Name (Name : String) return Boolean;
+ -- Returns True if Name is a valid file name
+
+ function Is_Valid_Path_Name (Name : String) return Boolean;
+ -- Returns True if Name is a valid path name
+
+end Ada.Directories.Validity;
+
+
diff --git a/gcc/ada/a-elchha.adb b/gcc/ada/a-elchha.adb
new file mode 100644
index 00000000000..6e2da234a4b
--- /dev/null
+++ b/gcc/ada/a-elchha.adb
@@ -0,0 +1,165 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . E X C E P T I O N S . L A S T _ C H A N C E _ H A N D L E R --
+-- --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- Default version for most targets
+
+procedure Ada.Exceptions.Last_Chance_Handler
+ (Except : Exception_Occurrence)
+is
+ procedure Unhandled_Terminate;
+ pragma No_Return (Unhandled_Terminate);
+ pragma Import (C, Unhandled_Terminate, "__gnat_unhandled_terminate");
+ -- Perform system dependent shutdown code
+
+ function Tailored_Exception_Information
+ (X : Exception_Occurrence) return String;
+ -- Exception information to be output in the case of automatic tracing
+ -- requested through GNAT.Exception_Traces.
+ --
+ -- This is the same as Exception_Information if no backtrace decorator
+ -- is currently in place. Otherwise, this is Exception_Information with
+ -- the call chain raw addresses replaced by the result of a call to the
+ -- current decorator provided with the call chain addresses.
+
+ pragma Import
+ (Ada, Tailored_Exception_Information,
+ "__gnat_tailored_exception_information");
+
+ procedure Tailored_Exception_Information
+ (X : Exception_Occurrence;
+ Buff : in out String;
+ Last : in out Integer);
+ -- Procedural version of the above function. Instead of returning the
+ -- result, this one is put in Buff (Buff'first .. Buff'first + Last)
+
+ procedure To_Stderr (S : String);
+ pragma Import (Ada, To_Stderr, "__gnat_to_stderr");
+ -- Little routine to output string to stderr
+
+ Nline : constant String := String'(1 => ASCII.LF);
+ -- Convenient shortcut
+
+ Msg : constant String := Except.Msg (1 .. Except.Msg_Length);
+
+ Max_Static_Exc_Info : constant := 1024;
+ -- This should be enough for most exception information cases
+ -- even though tailoring introduces some uncertainty. The
+ -- name+message should not exceed 320 chars, so that leaves at
+ -- least 35 backtrace slots (each slot needs 19 chars for
+ -- representing a 64 bit address).
+
+ subtype Exc_Info_Type is String (1 .. Max_Static_Exc_Info);
+ type Str_Ptr is access Exc_Info_Type;
+ Exc_Info : Str_Ptr;
+ Exc_Info_Last : Natural := 0;
+ -- Buffer that is allocated to store the tailored exception
+ -- information while Adafinal is run. This buffer is allocated
+ -- on the heap only when it is needed. It is better to allocate
+ -- on the heap than on the stack since stack overflows are more
+ -- common than heap overflows.
+
+ procedure Tailored_Exception_Information
+ (X : Exception_Occurrence;
+ Buff : in out String;
+ Last : in out Integer)
+ is
+ Info : constant String := Tailored_Exception_Information (X);
+ begin
+ Last := Info'Last;
+ Buff (1 .. Last) := Info;
+ end Tailored_Exception_Information;
+
+begin
+ -- First allocate & store the exception info in a buffer when
+ -- we know it will be needed. This needs to be done before
+ -- Adafinal because it implicitly uses the secondary stack.
+
+ if Except.Id.Full_Name.all (1) /= '_'
+ and then Except.Num_Tracebacks /= 0
+ then
+ Exc_Info := new Exc_Info_Type;
+ if Exc_Info /= null then
+ Tailored_Exception_Information
+ (Except, Exc_Info.all, Exc_Info_Last);
+ end if;
+ end if;
+
+ -- Let's shutdown the runtime now. The rest of the procedure
+ -- needs to be careful not to use anything that would require
+ -- runtime support. In particular, functions returning strings
+ -- are banned since the sec stack is no longer functional.
+ System.Standard_Library.Adafinal;
+
+ -- Check for special case of raising _ABORT_SIGNAL, which is not
+ -- really an exception at all. We recognize this by the fact that
+ -- it is the only exception whose name starts with underscore.
+
+ if Except.Id.Full_Name.all (1) = '_' then
+ To_Stderr (Nline);
+ To_Stderr ("Execution terminated by abort of environment task");
+ To_Stderr (Nline);
+
+ -- If no tracebacks, we print the unhandled exception in the old style
+ -- (i.e. the style used before ZCX was implemented). We do this to
+ -- retain compatibility.
+
+ elsif Except.Num_Tracebacks = 0 then
+ To_Stderr (Nline);
+ To_Stderr ("raised ");
+ To_Stderr (Except.Id.Full_Name.all (1 .. Except.Id.Name_Length - 1));
+
+ if Msg'Length /= 0 then
+ To_Stderr (" : ");
+ To_Stderr (Msg);
+ end if;
+
+ To_Stderr (Nline);
+
+ -- Traceback exists
+
+ else
+ -- Note we can have this whole information output twice if
+ -- this occurrence gets reraised up to here.
+
+ To_Stderr (Nline);
+ To_Stderr ("Execution terminated by unhandled exception");
+ To_Stderr (Nline);
+ To_Stderr (Exc_Info (1 .. Exc_Info_Last));
+ end if;
+
+ Unhandled_Terminate;
+end Ada.Exceptions.Last_Chance_Handler;
diff --git a/gcc/ada/a-elchha.ads b/gcc/ada/a-elchha.ads
new file mode 100644
index 00000000000..7efbe0f5558
--- /dev/null
+++ b/gcc/ada/a-elchha.ads
@@ -0,0 +1,46 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . E X C E P T I O N S . L A S T _ C H A N C E _ H A N D L E R --
+-- --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- Last chance handler. Unhandled exceptions are passed to this
+-- routine.
+
+procedure Ada.Exceptions.Last_Chance_Handler
+ (Except : Exception_Occurrence);
+pragma Export (C,
+ Last_Chance_Handler,
+ "__gnat_last_chance_handler");
+pragma No_Return (Last_Chance_Handler);
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-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..47231a89444
--- /dev/null
+++ b/gcc/ada/a-numaux-x86.adb
@@ -0,0 +1,572 @@
+------------------------------------------------------------------------------
+-- --
+-- 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-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. --
+-- --
+------------------------------------------------------------------------------
+
+-- 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;
+
+ -----------------------
+ -- 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)
+
+ procedure Reduce (X : in out Double; Q : out Natural);
+ -- Implements reduction of X by Pi/2. Q is the quadrant of the final
+ -- result in the range 0 .. 3. The absolute value of X is at most 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 --
+ ------------
+
+ procedure Reduce (X : in out Double; Q : out Natural) is
+ Half_Pi : constant := Pi / 2.0;
+ Two_Over_Pi : constant := 2.0 / Pi;
+
+ HM : constant := Integer'Min (Double'Machine_Mantissa / 2, Natural'Size);
+ M : constant Double := 0.5 + 2.0**(1 - HM); -- Splitting constant
+ P1 : constant Double := Double'Leading_Part (Half_Pi, HM);
+ P2 : constant Double := Double'Leading_Part (Half_Pi - P1, HM);
+ P3 : constant Double := Double'Leading_Part (Half_Pi - P1 - P2, HM);
+ P4 : constant Double := Double'Leading_Part (Half_Pi - P1 - P2 - P3, HM);
+ P5 : constant Double := Double'Leading_Part (Half_Pi - P1 - P2 - P3
+ - P4, HM);
+ P6 : constant Double := Double'Model (Half_Pi - P1 - P2 - P3 - P4 - P5);
+ K : Double := X * Two_Over_Pi;
+ begin
+ -- For X < 2.0**32, all products below are computed exactly.
+ -- Due to cancellation effects all subtractions are exact as well.
+ -- As no double extended floating-point number has more than 75
+ -- zeros after the binary point, the result will be the correctly
+ -- rounded result of X - K * (Pi / 2.0).
+
+ while abs K >= 2.0**HM loop
+ K := K * M - (K * M - K);
+ X := (((((X - K * P1) - K * P2) - K * P3)
+ - K * P4) - K * P5) - K * P6;
+ K := X * Two_Over_Pi;
+ end loop;
+
+ if K /= K then
+
+ -- K is not a number, because X was not finite
+
+ raise Constraint_Error;
+ end if;
+
+ K := Double'Rounding (K);
+ Q := Integer (K) mod 4;
+ X := (((((X - K * P1) - K * P2) - K * P3)
+ - K * P4) - K * P5) - K * P6;
+ 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 := abs X;
+ Result : Double;
+ Quadrant : Natural range 0 .. 3;
+
+ begin
+ if Reduced_X > Pi / 4.0 then
+ Reduce (Reduced_X, Quadrant);
+
+ case Quadrant is
+ when 0 =>
+ Asm (Template => "fcos",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ when 1 =>
+ Asm (Template => "fsin",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", -Reduced_X));
+ when 2 =>
+ Asm (Template => "fcos ; fchs",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ when 3 =>
+ Asm (Template => "fsin",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ end case;
+
+ else
+ Asm (Template => "fcos",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ end if;
+
+ 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, do divide 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;
+ Quadrant : Natural range 0 .. 3;
+
+ begin
+ if abs X > Pi / 4.0 then
+ Reduce (Reduced_X, Quadrant);
+
+ case Quadrant is
+ when 0 =>
+ Asm (Template => "fsin",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ when 1 =>
+ Asm (Template => "fcos",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ when 2 =>
+ Asm (Template => "fsin",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", -Reduced_X));
+ when 3 =>
+ Asm (Template => "fcos ; fchs",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ end case;
+
+ else
+ Asm (Template => "fsin",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ end if;
+
+ return Result;
+ end Sin;
+
+ ---------
+ -- Tan --
+ ---------
+
+ function Tan (X : Double) return Double is
+ Reduced_X : Double := X;
+ Result : Double;
+ Quadrant : Natural range 0 .. 3;
+
+ begin
+ if abs X > Pi / 4.0 then
+ Reduce (Reduced_X, Quadrant);
+
+ if Quadrant mod 2 = 0 then
+ Asm (Template => "fptan" & NL
+ & "ffree %%st(0)" & NL
+ & "fincstp",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ else
+ Asm (Template => "fsincos" & NL
+ & "fdivp %%st(1)" & NL
+ & "fchs",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ end if;
+
+ else
+ Asm (Template =>
+ "fptan " & NL
+ & "ffree %%st(0) " & NL
+ & "fincstp ",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+ end if;
+
+ 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/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-sestin.ads b/gcc/ada/g-sestin.ads
new file mode 100644
index 00000000000..328436b5dbc
--- /dev/null
+++ b/gcc/ada/g-sestin.ads
@@ -0,0 +1,50 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- G N A T . S E C O N D A R Y _ S T A C K _ I N F O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 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 facilities for obtaining information on secondary
+-- stack usage.
+
+with System.Secondary_Stack;
+
+package GNAT.Secondary_Stack_Info is
+
+ function SS_Get_Max return Long_Long_Integer
+ renames System.Secondary_Stack.SS_Get_Max;
+ -- Return maximum used space in storage units for the current secondary
+ -- stack. For a dynamically allocated secondary stack, the returned
+ -- result is always -1. For a statically allocated secondary stack,
+ -- the returned value shows the largest amount of space allocated so
+ -- far during execution of the program to the current secondary stack,
+ -- i.e. the secondary stack for the current task.
+
+end GNAT.Secondary_Stack_Info;
diff --git a/gcc/ada/g-signal.adb b/gcc/ada/g-signal.adb
new file mode 100644
index 00000000000..605b3e72f91
--- /dev/null
+++ b/gcc/ada/g-signal.adb
@@ -0,0 +1,71 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- G N A T . S I G N A 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. --
+-- --
+-- 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.Interrupts;
+
+package body GNAT.Signals is
+
+ package SI renames System.Interrupts;
+
+ ------------------
+ -- Block_Signal --
+ ------------------
+
+ procedure Block_Signal (Signal : Ada.Interrupts.Interrupt_ID) is
+ begin
+ SI.Block_Interrupt (SI.Interrupt_ID (Signal));
+ end Block_Signal;
+
+ ----------------
+ -- Is_Blocked --
+ ----------------
+
+ function Is_Blocked
+ (Signal : Ada.Interrupts.Interrupt_ID)
+ return Boolean
+ is
+ begin
+ return SI.Is_Blocked (SI.Interrupt_ID (Signal));
+ end Is_Blocked;
+
+ --------------------
+ -- Unblock_Signal --
+ --------------------
+
+ procedure Unblock_Signal (Signal : Ada.Interrupts.Interrupt_ID) is
+ begin
+ SI.Unblock_Interrupt (SI.Interrupt_ID (Signal));
+ end Unblock_Signal;
+
+end GNAT.Signals;
+
diff --git a/gcc/ada/g-signal.ads b/gcc/ada/g-signal.ads
new file mode 100644
index 00000000000..6939fe27386
--- /dev/null
+++ b/gcc/ada/g-signal.ads
@@ -0,0 +1,55 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- G N A T . S I G N A L S --
+-- --
+-- S p e c --
+-- --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Interrupts;
+
+-- This package provides operations for querying and setting the blocked
+-- status of signals.
+
+-- This package is supported only on targets where Ada.Interrupts.Interrupt_ID
+-- corresponds to software signals on the target, and where System.Interrupts
+-- provides the ability to block and unblock signals.
+
+package GNAT.Signals is
+
+ procedure Block_Signal (Signal : Ada.Interrupts.Interrupt_ID);
+ -- Block "Signal" at the process level
+
+ procedure Unblock_Signal (Signal : Ada.Interrupts.Interrupt_ID);
+ -- Unblock "Signal" at the process level
+
+ function Is_Blocked (Signal : Ada.Interrupts.Interrupt_ID)
+ return Boolean;
+ -- "Signal" blocked at the process level?
+
+end GNAT.Signals;
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/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
new file mode 100644
index 00000000000..8c358847036
--- /dev/null
+++ b/gcc/ada/gnat_ugn.texi
@@ -0,0 +1,27811 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+
+@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
+@c o
+@c GNAT DOCUMENTATION o
+@c o
+@c G N A T _ U G N o
+@c o
+@c Copyright (C) 1992-2004 Ada Core Technologies, Inc. o
+@c o
+@c GNAT is free software; you can redistribute it and/or modify it under o
+@c terms of the GNU General Public License as published by the Free Soft- o
+@c ware Foundation; either version 2, or (at your option) any later ver- o
+@c sion. GNAT is distributed in the hope that it will be useful, but WITH- o
+@c OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY o
+@c or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License o
+@c for more details. You should have received a copy of the GNU General o
+@c Public License distributed with GNAT; see file COPYING. If not, write o
+@c to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, o
+@c MA 02111-1307, USA. o
+@c o
+@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
+
+@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
+@c
+@c GNAT_UGN Style Guide
+@c
+@c 1. Always put a @noindent on the line before the first paragraph
+@c after any of these commands:
+@c
+@c @chapter
+@c @section
+@c @subsection
+@c @subsubsection
+@c @subsubsubsection
+@c
+@c @end smallexample
+@c @end itemize
+@c @end enumerate
+@c
+@c 2. DO NOT use @example. Use @smallexample instead.
+@c a) DO NOT use highlighting commands (@b{}, @i{}) inside an @smallexample
+@c context. These can interfere with the readability of the texi
+@c source file. Instead, use one of the following annotated
+@c @smallexample commands, and preprocess the texi file with the
+@c ada2texi tool (which generates appropriate highlighting):
+@c @smallexample @c ada
+@c @smallexample @c adanocomment
+@c @smallexample @c projectfile
+@c b) The "@c ada" markup will result in boldface for reserved words
+@c and italics for comments
+@c c) The "@c adanocomment" markup will result only in boldface for
+@c reserved words (comments are left alone)
+@c d) The "@c projectfile" markup is like "@c ada" except that the set
+@c of reserved words include the new reserved words for project files
+@c
+@c 3. Each @chapter, @section, @subsection, @subsubsection, etc.
+@c command must be preceded by two empty lines
+@c
+@c 4. The @item command should be on a line of its own if it is in an
+@c @itemize or @enumerate command.
+@c
+@c 5. When talking about ALI files use "ALI" (all uppercase), not "Ali"
+@c or "ali".
+@c
+@c 6. DO NOT put trailing spaces at the end of a line. Such spaces will
+@c cause the document build to fail.
+@c
+@c 7. DO NOT use @cartouche for examples that are longer than around 10 lines.
+@c This command inhibits page breaks, so long examples in a @cartouche can
+@c lead to large, ugly patches of empty space on a page.
+@c
+@c NOTE: This file should be submitted to xgnatugn with either the vms flag
+@c or the unw flag set. The unw flag covers topics for both Unix and
+@c Windows.
+@c
+@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
+
+@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
+@dircategory GNU Ada tools
+@direntry
+* GNAT User's Guide (gnat_ugn_vms) for Native Platforms / OpenVMS Alpha
+@end direntry
+@end ifset
+
+@ifset unw
+@settitle GNAT User's Guide for Native Platforms / Unix and Windows
+@direntry
+* GNAT User's Guide (gnat_ugn_unw) for Native Platforms / Unix and Windows
+@end direntry
+@end ifset
+
+@include gcc-common.texi
+
+@setchapternewpage odd
+@syncodeindex fn cp
+@c %**end of header
+
+@copying
+Copyright @copyright{} 1995-2004, Free Software Foundation
+
+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 Free Documentation License'', with the
+Front-Cover Texts being
+@ifset vms
+``GNAT User's Guide for Native Platforms / OpenVMS Alpha'',
+@end ifset
+@ifset unw
+``GNAT User's Guide for Native Platforms / Unix and Windows'',
+@end ifset
+and with no Back-Cover Texts.
+A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+@end copying
+
+@titlepage
+
+@title GNAT User's Guide
+@center @titlefont{for Native Platforms}
+@sp 1
+
+@flushright
+@ifset unw
+@titlefont{@i{Unix and Windows}}
+@end ifset
+@ifset vms
+@titlefont{@i{OpenVMS Alpha}}
+@end ifset
+@end flushright
+@sp 2
+
+@subtitle GNAT, The GNU Ada 95 Compiler
+@subtitle GCC version @value{version-GCC}
+
+@author Ada Core Technologies, Inc.
+
+@page
+@vskip 0pt plus 1filll
+
+@insertcopying
+
+@end titlepage
+
+
+@ifnottex
+@node Top, About This Guide, (dir), (dir)
+@top GNAT User's Guide
+
+@ifset vms
+@noindent
+GNAT User's Guide for Native Platforms / OpenVMS Alpha
+@end ifset
+
+@ifset unw
+@noindent
+GNAT User's Guide for Native Platforms / Unix and Windows
+@end ifset
+
+@noindent
+GNAT, The GNU Ada 95 Compiler@*
+GCC version @value{version-GCC}@*
+
+@noindent
+Ada Core Technologies, Inc.@*
+
+@menu
+* About This Guide::
+* Getting Started with GNAT::
+* The GNAT Compilation Model::
+* Compiling Using gcc::
+* Binding Using gnatbind::
+* Linking Using gnatlink::
+* The GNAT Make Program gnatmake::
+* Improving Performance::
+* Renaming Files Using gnatchop::
+* Configuration Pragmas::
+* Handling Arbitrary File Naming Conventions Using gnatname::
+* GNAT Project Manager::
+* The Cross-Referencing Tools gnatxref and gnatfind::
+* The GNAT Pretty-Printer gnatpp::
+* File Name Krunching Using gnatkr::
+* Preprocessing Using gnatprep::
+@ifset vms
+* The GNAT Run-Time Library Builder gnatlbr::
+@end ifset
+* The GNAT Library Browser gnatls::
+* Cleaning Up Using gnatclean::
+@ifclear vms
+* GNAT and Libraries::
+* Using the GNU make Utility::
+@end ifclear
+* Finding Memory Problems::
+* Creating Sample Bodies Using gnatstub::
+* Other Utility Programs::
+* Running and Debugging Ada Programs::
+@ifset vms
+* Compatibility with DEC Ada::
+@end ifset
+* Platform-Specific Information for the Run-Time Libraries::
+* Example of Binder Output File::
+* Elaboration Order Handling in GNAT::
+* Inline Assembler::
+* Compatibility and Porting Guide::
+@ifset unw
+* Microsoft Windows Topics::
+@end ifset
+* GNU Free Documentation License::
+* Index::
+
+ --- The Detailed Node Listing ---
+
+About This Guide
+
+* What This Guide Contains::
+* What You Should Know before Reading This Guide::
+* Related Information::
+* Conventions::
+
+Getting Started with GNAT
+
+* Running GNAT::
+* Running a Simple Ada Program::
+* Running a Program with Multiple Units::
+* Using the gnatmake Utility::
+@ifset vms
+* Editing with Emacs::
+@end ifset
+@ifclear vms
+* Introduction to GPS::
+* Introduction to Glide and GVD::
+@end ifclear
+
+The GNAT Compilation Model
+
+* Source Representation::
+* Foreign Language Representation::
+* File Naming Rules::
+* Using Other File Names::
+* Alternative File Naming Schemes::
+* Generating Object Files::
+* Source Dependencies::
+* The Ada Library Information Files::
+* Binding an Ada Program::
+* Mixed Language Programming::
+* Building Mixed Ada & C++ Programs::
+* Comparison between GNAT and C/C++ Compilation Models::
+* Comparison between GNAT and Conventional Ada Library Models::
+@ifset vms
+* Placement of temporary files::
+@end ifset
+
+Foreign Language Representation
+
+* Latin-1::
+* Other 8-Bit Codes::
+* Wide Character Encodings::
+
+Compiling Ada Programs With gcc
+
+* Compiling Programs::
+* Switches for gcc::
+* Search Paths and the Run-Time Library (RTL)::
+* Order of Compilation Issues::
+* Examples::
+
+Switches for gcc
+
+* Output and Error Message Control::
+* Warning Message Control::
+* Debugging and Assertion Control::
+* Validity Checking::
+* Style Checking::
+* Run-Time Checks::
+* Stack Overflow Checking::
+* Using gcc for Syntax Checking::
+* Using gcc for Semantic Checking::
+* Compiling Ada 83 Programs::
+* Character Set Control::
+* File Naming Control::
+* Subprogram Inlining Control::
+* Auxiliary Output Control::
+* Debugging Control::
+* Exception Handling Control::
+* Units to Sources Mapping Files::
+* Integrated Preprocessing::
+@ifset vms
+* Return Codes::
+@end ifset
+
+Binding Ada Programs With gnatbind
+
+* Running gnatbind::
+* Switches for gnatbind::
+* Command-Line Access::
+* Search Paths for gnatbind::
+* Examples of gnatbind Usage::
+
+Switches for gnatbind
+
+* Consistency-Checking Modes::
+* Binder Error Message Control::
+* Elaboration Control::
+* Output Control::
+* Binding with Non-Ada Main Programs::
+* Binding Programs with No Main Subprogram::
+
+Linking Using gnatlink
+
+* Running gnatlink::
+* Switches for gnatlink::
+* Setting Stack Size from gnatlink::
+* Setting Heap Size from gnatlink::
+
+The GNAT Make Program gnatmake
+
+* Running gnatmake::
+* Switches for gnatmake::
+* Mode Switches for gnatmake::
+* Notes on the Command Line::
+* How gnatmake Works::
+* Examples of gnatmake Usage::
+
+
+Improving Performance
+* Performance Considerations::
+* Reducing the Size of Ada Executables with gnatelim::
+
+Performance Considerations
+* Controlling Run-Time Checks::
+* Use of Restrictions::
+* Optimization Levels::
+* Debugging Optimized Code::
+* Inlining of Subprograms::
+* Optimization and Strict Aliasing::
+@ifset vms
+* Coverage Analysis::
+@end ifset
+
+Reducing the Size of Ada Executables with gnatelim
+* About gnatelim::
+* Running gnatelim::
+* Correcting the List of Eliminate Pragmas::
+* Making Your Executables Smaller::
+* Summary of the gnatelim Usage Cycle::
+
+Renaming Files Using gnatchop
+
+* Handling Files with Multiple Units::
+* Operating gnatchop in Compilation Mode::
+* Command Line for gnatchop::
+* Switches for gnatchop::
+* Examples of gnatchop Usage::
+
+Configuration Pragmas
+
+* Handling of Configuration Pragmas::
+* The Configuration Pragmas Files::
+
+Handling Arbitrary File Naming Conventions Using gnatname
+
+* Arbitrary File Naming Conventions::
+* Running gnatname::
+* Switches for gnatname::
+* Examples of gnatname Usage::
+
+GNAT Project Manager
+
+* Introduction::
+* Examples of Project Files::
+* Project File Syntax::
+* Objects and Sources in Project Files::
+* Importing Projects::
+* Project Extension::
+* External References in Project Files::
+* Packages in Project Files::
+* Variables from Imported Projects::
+* Naming Schemes::
+* Library Projects::
+* Using Third-Party Libraries through Projects::
+* Stand-alone Library Projects::
+* Switches Related to Project Files::
+* Tools Supporting Project Files::
+* An Extended Example::
+* Project File Complete Syntax::
+
+
+The Cross-Referencing Tools gnatxref and gnatfind
+
+* gnatxref Switches::
+* gnatfind Switches::
+* Project Files for gnatxref and gnatfind::
+* Regular Expressions in gnatfind and gnatxref::
+* Examples of gnatxref Usage::
+* Examples of gnatfind Usage::
+
+
+The GNAT Pretty-Printer gnatpp
+
+* Switches for gnatpp::
+* Formatting Rules::
+
+
+File Name Krunching Using gnatkr
+
+* About gnatkr::
+* Using gnatkr::
+* Krunching Method::
+* Examples of gnatkr Usage::
+
+Preprocessing Using gnatprep
+
+* Using gnatprep::
+* Switches for gnatprep::
+* Form of Definitions File::
+* Form of Input Text for gnatprep::
+
+@ifset vms
+The GNAT Run-Time Library Builder gnatlbr
+
+* Running gnatlbr::
+* Switches for gnatlbr::
+* Examples of gnatlbr Usage::
+@end ifset
+
+The GNAT Library Browser gnatls
+
+* Running gnatls::
+* Switches for gnatls::
+* Examples of gnatls Usage::
+
+Cleaning Up Using gnatclean
+
+* Running gnatclean::
+* Switches for gnatclean::
+* Examples of gnatclean Usage::
+
+@ifclear vms
+
+GNAT and Libraries
+
+* Introduction to Libraries in GNAT::
+* General Ada Libraries::
+* Stand-alone Ada Libraries::
+* Rebuilding the GNAT Run-Time Library::
+
+Using the GNU make Utility
+
+* Using gnatmake in a Makefile::
+* Automatically Creating a List of Directories::
+* Generating the Command Line Switches::
+* Overcoming Command Line Length Limits::
+@end ifclear
+
+Finding Memory Problems
+
+@ifclear vms
+* The gnatmem Tool::
+@end ifclear
+* The GNAT Debug Pool Facility::
+
+@ifclear vms
+The gnatmem Tool
+
+* Running gnatmem::
+* Switches for gnatmem::
+* Example of gnatmem Usage::
+@end ifclear
+
+The GNAT Debug Pool Facility
+
+Creating Sample Bodies Using gnatstub
+
+* Running gnatstub::
+* Switches for gnatstub::
+
+Other Utility Programs
+
+* Using Other Utility Programs with GNAT::
+* The External Symbol Naming Scheme of GNAT::
+@ifclear vms
+* Ada Mode for Glide::
+@end ifclear
+* Converting Ada Files to html with gnathtml::
+
+Running and Debugging Ada Programs
+
+* The GNAT Debugger GDB::
+* Running GDB::
+* Introduction to GDB Commands::
+* Using Ada Expressions::
+* Calling User-Defined Subprograms::
+* Using the Next Command in a Function::
+* Ada Exceptions::
+* Ada Tasks::
+* Debugging Generic Units::
+* GNAT Abnormal Termination or Failure to Terminate::
+* Naming Conventions for GNAT Source Files::
+* Getting Internal Debugging Information::
+* Stack Traceback::
+
+@ifset vms
+* LSE::
+@end ifset
+
+@ifset vms
+Compatibility with DEC Ada
+
+* Ada 95 Compatibility::
+* Differences in the Definition of Package System::
+* Language-Related Features::
+* The Package STANDARD::
+* The Package SYSTEM::
+* Tasking and Task-Related Features::
+* Implementation of Tasks in DEC Ada for OpenVMS Alpha Systems::
+* Pragmas and Pragma-Related Features::
+* Library of Predefined Units::
+* Bindings::
+* Main Program Definition::
+* Implementation-Defined Attributes::
+* Compiler and Run-Time Interfacing::
+* Program Compilation and Library Management::
+* Input-Output::
+* Implementation Limits::
+* Tools::
+
+Language-Related Features
+
+* Integer Types and Representations::
+* Floating-Point Types and Representations::
+* Pragmas Float_Representation and Long_Float::
+* Fixed-Point Types and Representations::
+* Record and Array Component Alignment::
+* Address Clauses::
+* Other Representation Clauses::
+
+Implementation of Tasks in DEC Ada for OpenVMS Alpha Systems
+
+* Assigning Task IDs::
+* Task IDs and Delays::
+* Task-Related Pragmas::
+* Scheduling and Task Priority::
+* The Task Stack::
+* External Interrupts::
+
+Pragmas and Pragma-Related Features
+
+* Restrictions on the Pragma INLINE::
+* Restrictions on the Pragma INTERFACE::
+* Restrictions on the Pragma SYSTEM_NAME::
+
+Library of Predefined Units
+
+* Changes to DECLIB::
+
+Bindings
+
+* Shared Libraries and Options Files::
+* Interfaces to C::
+@end ifset
+
+Platform-Specific Information for the Run-Time Libraries
+
+* Summary of Run-Time Configurations::
+* Specifying a Run-Time Library::
+* Choosing between Native and FSU Threads Libraries::
+* Choosing the Scheduling Policy::
+* Solaris-Specific Considerations::
+* IRIX-Specific Considerations::
+* Linux-Specific Considerations::
+* AIX-Specific Considerations::
+
+Example of Binder Output File
+
+Elaboration Order Handling in GNAT
+
+* Elaboration Code in Ada 95::
+* Checking the Elaboration Order in Ada 95::
+* Controlling the Elaboration Order in Ada 95::
+* Controlling Elaboration in GNAT - Internal Calls::
+* Controlling Elaboration in GNAT - External Calls::
+* Default Behavior in GNAT - Ensuring Safety::
+* Treatment of Pragma Elaborate::
+* Elaboration Issues for Library Tasks::
+* Mixing Elaboration Models::
+* What to Do If the Default Elaboration Behavior Fails::
+* Elaboration for Access-to-Subprogram Values::
+* Summary of Procedures for Elaboration Control::
+* Other Elaboration Order Considerations::
+
+Inline Assembler
+
+* Basic Assembler Syntax::
+* A Simple Example of Inline Assembler::
+* Output Variables in Inline Assembler::
+* Input Variables in Inline Assembler::
+* Inlining Inline Assembler Code::
+* Other Asm Functionality::
+* A Complete Example::
+
+Compatibility and Porting Guide
+
+* Compatibility with Ada 83::
+* Implementation-dependent characteristics::
+* Compatibility with DEC Ada 83::
+* Compatibility with Other Ada 95 Systems::
+* Representation Clauses::
+
+@ifset unw
+Microsoft Windows Topics
+
+* Using GNAT on Windows::
+* CONSOLE and WINDOWS subsystems::
+* Temporary Files::
+* Mixed-Language Programming on Windows::
+* Windows Calling Conventions::
+* Introduction to Dynamic Link Libraries (DLLs)::
+* Using DLLs with GNAT::
+* Building DLLs with GNAT::
+* GNAT and Windows Resources::
+* Debugging a DLL::
+* GNAT and COM/DCOM Objects::
+@end ifset
+
+
+* Index::
+@end menu
+@end ifnottex
+
+@node About This Guide
+@unnumbered About This Guide
+
+@noindent
+@ifset vms
+This guide describes the use of of GNAT, a full language compiler for the Ada
+95 programming language, implemented on HP OpenVMS Alpha platforms.
+@end ifset
+@ifclear vms
+This guide describes the use of GNAT, a compiler and software development
+toolset for the full Ada 95 programming language.
+@end ifclear
+It describes the features of the compiler and tools, and details
+how to use them to build Ada 95 applications.
+
+@menu
+* What This Guide Contains::
+* What You Should Know before Reading This Guide::
+* Related Information::
+* Conventions::
+@end menu
+
+@node What This Guide Contains
+@unnumberedsec What This Guide Contains
+
+@noindent
+This guide contains the following chapters:
+@itemize @bullet
+
+@item
+@ref{Getting Started with GNAT}, describes how to get started compiling
+and running Ada programs with the GNAT Ada programming environment.
+@item
+@ref{The GNAT Compilation Model}, describes the compilation model used
+by GNAT.
+
+@item
+@ref{Compiling Using gcc}, describes how to compile
+Ada programs with @code{gcc}, the Ada compiler.
+
+@item
+@ref{Binding Using gnatbind}, describes how to
+perform binding of Ada programs with @code{gnatbind}, the GNAT binding
+utility.
+
+@item
+@ref{Linking Using gnatlink},
+describes @code{gnatlink}, a
+program that provides for linking using the GNAT run-time library to
+construct a program. @code{gnatlink} can also incorporate foreign language
+object units into the executable.
+
+@item
+@ref{The GNAT Make Program gnatmake}, describes @code{gnatmake}, a
+utility that automatically determines the set of sources
+needed by an Ada compilation unit, and executes the necessary compilations
+binding and link.
+
+@item
+@ref{Improving Performance}, shows various techniques for making your
+Ada program run faster or take less space.
+It discusses the effect of the compiler's optimization switch and
+also describes the @command{gnatelim} tool.
+
+@item
+@ref{Renaming Files Using gnatchop}, describes
+@code{gnatchop}, a utility that allows you to preprocess a file that
+contains Ada source code, and split it into one or more new files, one
+for each compilation unit.
+
+@item
+@ref{Configuration Pragmas}, describes the configuration pragmas
+handled by GNAT.
+
+@item
+@ref{Handling Arbitrary File Naming Conventions Using gnatname},
+shows how to override the default GNAT file naming conventions,
+either for an individual unit or globally.
+
+@item
+@ref{GNAT Project Manager}, describes how to use project files
+to organize large projects.
+
+@item
+@ref{The Cross-Referencing Tools gnatxref and gnatfind}, discusses
+@code{gnatxref} and @code{gnatfind}, two tools that provide an easy
+way to navigate through sources.
+
+@item
+@ref{The GNAT Pretty-Printer gnatpp}, shows how to produce a reformatted
+version of an Ada source file with control over casing, indentation,
+comment placement, and other elements of program presentation style.
+
+
+@item
+@ref{File Name Krunching Using gnatkr}, describes the @code{gnatkr}
+file name krunching utility, used to handle shortened
+file names on operating systems with a limit on the length of names.
+
+@item
+@ref{Preprocessing Using gnatprep}, describes @code{gnatprep}, a
+preprocessor utility that allows a single source file to be used to
+generate multiple or parameterized source files, by means of macro
+substitution.
+
+@ifset vms
+@item
+@ref{The GNAT Run-Time Library Builder gnatlbr}, describes @command{gnatlbr},
+a tool for rebuilding the GNAT run time with user-supplied
+configuration pragmas.
+@end ifset
+
+@item
+@ref{The GNAT Library Browser gnatls}, describes @code{gnatls}, a
+utility that displays information about compiled units, including dependences
+on the corresponding sources files, and consistency of compilations.
+
+@item
+@ref{Cleaning Up Using gnatclean}, describes @code{gnatclean}, a utility
+to delete files that are produced by the compiler, binder and linker.
+
+@ifclear vms
+@item
+@ref{GNAT and Libraries}, describes the process of creating and using
+Libraries with GNAT. It also describes how to recompile the GNAT run-time
+library.
+
+@item
+@ref{Using the GNU make Utility}, describes some techniques for using
+the GNAT toolset in Makefiles.
+@end ifclear
+
+@item
+@ref{Finding Memory Problems}, describes
+@ifclear vms
+@command{gnatmem}, a utility that monitors dynamic allocation and deallocation
+and helps detect ``memory leaks'', and
+@end ifclear
+the GNAT Debug Pool facility, which helps detect incorrect memory references.
+
+@item
+@ref{Creating Sample Bodies Using gnatstub}, discusses @code{gnatstub},
+a utility that generates empty but compilable bodies for library units.
+
+@item
+@ref{Other Utility Programs}, discusses several other GNAT utilities,
+including @code{gnathtml}.
+
+@item
+@ref{Running and Debugging Ada Programs}, describes how to run and debug
+Ada programs.
+
+@ifset vms
+@item
+@ref{Compatibility with DEC Ada}, details the compatibility of GNAT with
+DEC Ada 83 @footnote{``DEC Ada'' refers to the legacy product originally
+developed by Digital Equipment Corporation and currently supported by HP.}
+for OpenVMS Alpha.
+@end ifset
+
+@item
+@ref{Platform-Specific Information for the Run-Time Libraries},
+describes the various run-time
+libraries supported by GNAT on various platforms and explains how to
+choose a particular library.
+
+@item
+@ref{Example of Binder Output File}, shows the source code for the binder
+output file for a sample program.
+
+@item
+@ref{Elaboration Order Handling in GNAT}, describes how GNAT helps
+you deal with elaboration order issues.
+
+@item
+@ref{Inline Assembler}, shows how to use the inline assembly facility
+in an Ada program.
+
+@item
+@ref{Compatibility and Porting Guide}, includes sections on compatibility
+of GNAT with other Ada 83 and Ada 95 compilation systems, to assist
+in porting code from other environments.
+
+@ifset unw
+@item
+@ref{Microsoft Windows Topics}, presents information relevant to the
+Microsoft Windows platform.
+@end ifset
+@end itemize
+
+
+@c *************************************************
+@node What You Should Know before Reading This Guide
+@c *************************************************
+@unnumberedsec What You Should Know before Reading This Guide
+
+@cindex Ada 95 Language Reference Manual
+@noindent
+This user's guide assumes that you are familiar with Ada 95 language, as
+described in the International Standard ANSI/ISO/IEC-8652:1995, January
+1995.
+
+@node Related Information
+@unnumberedsec Related Information
+
+@noindent
+For further information about related tools, refer to the following
+documents:
+
+@itemize @bullet
+@item
+@cite{GNAT Reference Manual}, which contains all reference
+material for the GNAT implementation of Ada 95.
+
+@ifset unw
+@item
+@cite{Using the GNAT Programming System}, which describes the GPS
+integrated development environment.
+
+@item
+@cite{GNAT Programming System Tutorial}, which introduces the
+main GPS features through examples.
+@end ifset
+
+@item
+@cite{Ada 95 Language Reference Manual}, which contains all reference
+material for the Ada 95 programming language.
+
+@item
+@cite{Debugging with GDB}
+@ifset vms
+, located in the GNU:[DOCS] directory,
+@end ifset
+contains all details on the use of the GNU source-level debugger.
+
+@item
+@cite{GNU Emacs Manual}
+@ifset vms
+, located in the GNU:[DOCS] directory if the EMACS kit is installed,
+@end ifset
+contains full information on the extensible editor and programming
+environment Emacs.
+
+@end itemize
+
+@c **************
+@node Conventions
+@unnumberedsec Conventions
+@cindex Conventions
+@cindex Typographical conventions
+
+@noindent
+Following are examples of the typographical and graphic conventions used
+in this guide:
+
+@itemize @bullet
+@item
+@code{Functions}, @code{utility program names}, @code{standard names},
+and @code{classes}.
+
+@item
+@samp{Option flags}
+
+@item
+@file{File Names}, @file{button names}, and @file{field names}.
+
+@item
+@var{Variables}.
+
+@item
+@emph{Emphasis}.
+
+@item
+[optional information or parameters]
+
+@item
+Examples are described by text
+@smallexample
+and then shown this way.
+@end smallexample
+@end itemize
+
+@noindent
+Commands that are entered by the user are preceded in this manual by the
+characters @w{``@code{$ }''} (dollar sign followed by space). If your system
+uses this sequence as a prompt, then the commands will appear exactly as
+you see them in the manual. If your system uses some other prompt, then
+the command will appear with the @code{$} replaced by whatever prompt
+character you are using.
+
+@ifset unw
+Full file names are shown with the ``@code{/}'' character
+as the directory separator; e.g., @file{parent-dir/subdir/myfile.adb}.
+If you are using GNAT on a Windows platform, please note that
+the ``@code{\}'' character should be used instead.
+@end ifset
+
+
+
+@c ****************************
+@node Getting Started with GNAT
+@chapter Getting Started with GNAT
+
+@noindent
+This chapter describes some simple ways of using GNAT to build
+executable Ada programs.
+@ifset unw
+@ref{Running GNAT}, through @ref{Using the gnatmake Utility},
+show how to use the command line environment.
+@ref{Introduction to Glide and GVD}, provides a brief
+introduction to the visually-oriented IDE for GNAT.
+Supplementing Glide on some platforms is GPS, the
+GNAT Programming System, which offers a richer graphical
+``look and feel'', enhanced configurability, support for
+development in other programming language, comprehensive
+browsing features, and many other capabilities.
+For information on GPS please refer to
+@cite{Using the GNAT Programming System}.
+@end ifset
+
+@menu
+* Running GNAT::
+* Running a Simple Ada Program::
+* Running a Program with Multiple Units::
+* Using the gnatmake Utility::
+@ifset vms
+* Editing with Emacs::
+@end ifset
+@ifclear vms
+* Introduction to GPS::
+* Introduction to Glide and GVD::
+@end ifclear
+@end menu
+
+@node Running GNAT
+@section Running GNAT
+
+@noindent
+Three steps are needed to create an executable file from an Ada source
+file:
+
+@enumerate
+@item
+The source file(s) must be compiled.
+@item
+The file(s) must be bound using the GNAT binder.
+@item
+All appropriate object files must be linked to produce an executable.
+@end enumerate
+
+@noindent
+All three steps are most commonly handled by using the @code{gnatmake}
+utility program that, given the name of the main program, automatically
+performs the necessary compilation, binding and linking steps.
+
+
+@node Running a Simple Ada Program
+@section Running a Simple Ada Program
+
+@noindent
+Any text editor may be used to prepare an Ada program.
+@ifclear vms
+If @code{Glide} is
+used, the optional Ada mode may be helpful in laying out the program.
+@end ifclear
+The
+program text is a normal text file. We will suppose in our initial
+example that you have used your editor to prepare the following
+standard format text file:
+
+@smallexample @c ada
+@cartouche
+with Ada.Text_IO; use Ada.Text_IO;
+procedure Hello is
+begin
+ Put_Line ("Hello WORLD!");
+end Hello;
+@end cartouche
+@end smallexample
+
+@noindent
+This file should be named @file{hello.adb}.
+With the normal default file naming conventions, GNAT requires
+that each file
+contain a single compilation unit whose file name is the
+unit name,
+with periods replaced by hyphens; the
+extension is @file{ads} for a
+spec and @file{adb} for a body.
+You can override this default file naming convention by use of the
+special pragma @code{Source_File_Name} (@pxref{Using Other File Names}).
+Alternatively, if you want to rename your files according to this default
+convention, which is probably more convenient if you will be using GNAT
+for all your compilations, then the @code{gnatchop} utility
+can be used to generate correctly-named source files
+(@pxref{Renaming Files Using gnatchop}).
+
+You can compile the program using the following command (@code{$} is used
+as the command prompt in the examples in this document):
+
+@smallexample
+$ gcc -c hello.adb
+@end smallexample
+
+@noindent
+@code{gcc} is the command used to run the compiler. This compiler is
+capable of compiling programs in several languages, including Ada 95 and
+C. It assumes that you have given it an Ada program if the file extension is
+either @file{.ads} or @file{.adb}, and it will then call
+the GNAT compiler to compile the specified file.
+
+@ifclear vms
+The @option{-c} switch is required. It tells @command{gcc} to only do a
+compilation. (For C programs, @command{gcc} can also do linking, but this
+capability is not used directly for Ada programs, so the @option{-c}
+switch must always be present.)
+@end ifclear
+
+This compile command generates a file
+@file{hello.o}, which is the object
+file corresponding to your Ada program. It also generates
+an ``Ada Library Information'' file @file{hello.ali},
+which contains additional information used to check
+that an Ada program is consistent.
+To build an executable file,
+use @code{gnatbind} to bind the program
+and @code{gnatlink} to link it. The
+argument to both @code{gnatbind} and @code{gnatlink} is the name of the
+@file{ALI} file, but the default extension of @file{.ali} can
+be omitted. This means that in the most common case, the argument
+is simply the name of the main program:
+
+@smallexample
+$ gnatbind hello
+$ gnatlink hello
+@end smallexample
+
+@noindent
+A simpler method of carrying out these steps is to use
+@command{gnatmake},
+a master program that invokes all the required
+compilation, binding and linking tools in the correct order. In particular,
+@command{gnatmake} automatically recompiles any sources that have been
+modified since they were last compiled, or sources that depend
+on such modified sources, so that ``version skew'' is avoided.
+@cindex Version skew (avoided by @command{gnatmake})
+
+@smallexample
+$ gnatmake hello.adb
+@end smallexample
+
+@noindent
+The result is an executable program called @file{hello}, which can be
+run by entering:
+
+@c The following should be removed (BMB 2001-01-23)
+@c @smallexample
+@c $ ^./hello^$ RUN HELLO^
+@c @end smallexample
+
+@smallexample
+$ hello
+@end smallexample
+
+@noindent
+assuming that the current directory is on the search path
+for executable programs.
+
+@noindent
+and, if all has gone well, you will see
+
+@smallexample
+Hello WORLD!
+@end smallexample
+
+@noindent
+appear in response to this command.
+
+
+@c ****************************************
+@node Running a Program with Multiple Units
+@section Running a Program with Multiple Units
+
+@noindent
+Consider a slightly more complicated example that has three files: a
+main program, and the spec and body of a package:
+
+@smallexample @c ada
+@cartouche
+@group
+package Greetings is
+ procedure Hello;
+ procedure Goodbye;
+end Greetings;
+
+with Ada.Text_IO; use Ada.Text_IO;
+package body Greetings is
+ procedure Hello is
+ begin
+ Put_Line ("Hello WORLD!");
+ end Hello;
+
+ procedure Goodbye is
+ begin
+ Put_Line ("Goodbye WORLD!");
+ end Goodbye;
+end Greetings;
+@end group
+
+@group
+with Greetings;
+procedure Gmain is
+begin
+ Greetings.Hello;
+ Greetings.Goodbye;
+end Gmain;
+@end group
+@end cartouche
+@end smallexample
+
+@noindent
+Following the one-unit-per-file rule, place this program in the
+following three separate files:
+
+@table @file
+@item greetings.ads
+spec of package @code{Greetings}
+
+@item greetings.adb
+body of package @code{Greetings}
+
+@item gmain.adb
+body of main program
+@end table
+
+@noindent
+To build an executable version of
+this program, we could use four separate steps to compile, bind, and link
+the program, as follows:
+
+@smallexample
+$ gcc -c gmain.adb
+$ gcc -c greetings.adb
+$ gnatbind gmain
+$ gnatlink gmain
+@end smallexample
+
+@noindent
+Note that there is no required order of compilation when using GNAT.
+In particular it is perfectly fine to compile the main program first.
+Also, it is not necessary to compile package specs in the case where
+there is an accompanying body; you only need to compile the body. If you want
+to submit these files to the compiler for semantic checking and not code
+generation, then use the
+@option{-gnatc} switch:
+
+@smallexample
+$ gcc -c greetings.ads -gnatc
+@end smallexample
+
+@noindent
+Although the compilation can be done in separate steps as in the
+above example, in practice it is almost always more convenient
+to use the @code{gnatmake} tool. All you need to know in this case
+is the name of the main program's source file. The effect of the above four
+commands can be achieved with a single one:
+
+@smallexample
+$ gnatmake gmain.adb
+@end smallexample
+
+@noindent
+In the next section we discuss the advantages of using @code{gnatmake} in
+more detail.
+
+@c *****************************
+@node Using the gnatmake Utility
+@section Using the @command{gnatmake} Utility
+
+@noindent
+If you work on a program by compiling single components at a time using
+@code{gcc}, you typically keep track of the units you modify. In order to
+build a consistent system, you compile not only these units, but also any
+units that depend on the units you have modified.
+For example, in the preceding case,
+if you edit @file{gmain.adb}, you only need to recompile that file. But if
+you edit @file{greetings.ads}, you must recompile both
+@file{greetings.adb} and @file{gmain.adb}, because both files contain
+units that depend on @file{greetings.ads}.
+
+@code{gnatbind} will warn you if you forget one of these compilation
+steps, so that it is impossible to generate an inconsistent program as a
+result of forgetting to do a compilation. Nevertheless it is tedious and
+error-prone to keep track of dependencies among units.
+One approach to handle the dependency-bookkeeping is to use a
+makefile. However, makefiles present maintenance problems of their own:
+if the dependencies change as you change the program, you must make
+sure that the makefile is kept up-to-date manually, which is also an
+error-prone process.
+
+The @code{gnatmake} utility takes care of these details automatically.
+Invoke it using either one of the following forms:
+
+@smallexample
+$ gnatmake gmain.adb
+$ gnatmake ^gmain^GMAIN^
+@end smallexample
+
+@noindent
+The argument is the name of the file containing the main program;
+you may omit the extension. @code{gnatmake}
+examines the environment, automatically recompiles any files that need
+recompiling, and binds and links the resulting set of object files,
+generating the executable file, @file{^gmain^GMAIN.EXE^}.
+In a large program, it
+can be extremely helpful to use @code{gnatmake}, because working out by hand
+what needs to be recompiled can be difficult.
+
+Note that @code{gnatmake}
+takes into account all the Ada 95 rules that
+establish dependencies among units. These include dependencies that result
+from inlining subprogram bodies, and from
+generic instantiation. Unlike some other
+Ada make tools, @code{gnatmake} does not rely on the dependencies that were
+found by the compiler on a previous compilation, which may possibly
+be wrong when sources change. @code{gnatmake} determines the exact set of
+dependencies from scratch each time it is run.
+
+@ifset vms
+@node Editing with Emacs
+@section Editing with Emacs
+@cindex Emacs
+
+@noindent
+Emacs is an extensible self-documenting text editor that is available in a
+separate VMSINSTAL kit.
+
+Invoke Emacs by typing @kbd{Emacs} at the command prompt. To get started,
+click on the Emacs Help menu and run the Emacs Tutorial.
+In a character cell terminal, Emacs help is invoked with @kbd{Ctrl-h} (also
+written as @kbd{C-h}), and the tutorial by @kbd{C-h t}.
+
+Documentation on Emacs and other tools is available in Emacs under the
+pull-down menu button: @code{Help - Info}. After selecting @code{Info},
+use the middle mouse button to select a topic (e.g. Emacs).
+
+In a character cell terminal, do @kbd{C-h i} to invoke info, and then @kbd{m}
+(stands for menu) followed by the menu item desired, as in @kbd{m Emacs}, to
+get to the Emacs manual.
+Help on Emacs is also available by typing @kbd{HELP EMACS} at the DCL command
+prompt.
+
+The tutorial is highly recommended in order to learn the intricacies of Emacs,
+which is sufficiently extensible to provide for a complete programming
+environment and shell for the sophisticated user.
+@end ifset
+
+@ifclear vms
+@node Introduction to GPS
+@section Introduction to GPS
+@cindex GPS (GNAT Programming System)
+@cindex GNAT Programming System (GPS)
+@noindent
+Although the command line interface (@command{gnatmake}, etc.) alone
+is sufficient, a graphical Interactive Development
+Environment can make it easier for you to compose, navigate, and debug
+programs. This section describes the main features of GPS
+(``GNAT Programming System''), the GNAT graphical IDE.
+You will see how to use GPS to build and debug an executable, and
+you will also learn some of the basics of the GNAT ``project'' facility.
+
+GPS enables you to do much more than is presented here;
+e.g., you can produce a call graph, interface to a third-party
+Version Control System, and inspect the generated assembly language
+for a program.
+Indeed, GPS also supports languages other than Ada.
+Such additional information, and an explanation of all of the GPS menu
+items. may be found in the on-line help, which includes
+a user's guide and a tutorial (these are also accessible from the GNAT
+startup menu).
+
+@menu
+* Building a New Program with GPS::
+* Simple Debugging with GPS::
+@end menu
+
+
+@node Building a New Program with GPS
+@subsection Building a New Program with GPS
+@noindent
+GPS invokes the GNAT compilation tools using information
+contained in a @emph{project} (also known as a @emph{project file}):
+a collection of properties such
+as source directories, identities of main subprograms, tool switches, etc.,
+and their associated values.
+(See @ref{GNAT Project Manager}, for details.)
+In order to run GPS, you will need to either create a new project
+or else open an existing one.
+
+This section will explain how you can use GPS to create a project,
+to associate Ada source files with a project, and to build and run
+programs.
+
+@enumerate
+@item @emph{Creating a project}
+
+Invoke GPS, either from the command line or the platform's IDE.
+After it starts, GPS will display a ``Welcome'' screen with three
+radio buttons:
+
+@itemize @bullet
+@item
+@code{Start with default project in directory}
+
+@item
+@code{Create new project with wizard}
+
+@item
+@code{Open existing project}
+@end itemize
+
+@noindent
+Select @code{Create new project with wizard} and press @code{OK}.
+A new window will appear. In the text box labeled with
+@code{Enter the name of the project to create}, type @file{sample}
+as the project name.
+In the next box, browse to choose the directory in which you
+would like to create the project file.
+After selecting an appropriate directory, press @code{Forward}.
+
+A window will appear with the title
+@code{Version Control System Configuration}.
+Simply press @code{Forward}.
+
+A window will appear with the title
+@code{Please select the source directories for this project}.
+The directory that you specified for the project file will be selected
+by default as the one to use for sources; simply press @code{Forward}.
+
+A window will appear with the title
+@code{Please select the build directory for this project}.
+The directory that you specified for the project file will be selected
+by default for object files and executables;
+simply press @code{Forward}.
+
+A window will appear with the title
+@code{Please select the main units for this project}.
+You will supply this information later, after creating the source file.
+Simply press @code{Forward} for now.
+
+A window will appear with the title
+@code{Please select the switches to build the project}.
+Press @code{Apply}. This will create a project file named
+@file{sample.prj} in the directory that you had specified.
+
+@item @emph{Creating and saving the source file}
+
+After you create the new project, a GPS window will appear, which is
+partitioned into two main sections:
+
+@itemize @bullet
+@item
+A @emph{Workspace area}, initially greyed out, which you will use for
+creating and editing source files
+
+@item
+Directly below, a @emph{Messages area}, which initially displays a
+``Welcome'' message.
+(If the Messages area is not visible, drag its border upward to expand it.)
+@end itemize
+
+@noindent
+Select @code{File} on the menu bar, and then the @code{New} command.
+The Workspace area will become white, and you can now
+enter the source program explicitly.
+Type the following text
+
+@smallexample @c ada
+@group
+with Ada.Text_IO; use Ada.Text_IO;
+procedure Hello is
+begin
+ Put_Line("Hello from GPS!");
+end Hello;
+@end group
+@end smallexample
+
+@noindent
+Select @code{File}, then @code{Save As}, and enter the source file name
+@file{hello.adb}.
+The file will be saved in the same directory you specified as the
+location of the default project file.
+
+
+@item @emph{Updating the project file}
+
+You need to add the new source file to the project.
+To do this, select
+the @code{Project} menu and then @code{Edit project properties}.
+Click the @code{Main files} tab on the left, and then the
+@code{Add} button.
+Choose @file{hello.adb} from the list, and press @code{Open}.
+The project settings window will reflect this action.
+Click @code{OK}.
+
+@item @emph{Building and running the program}
+
+In the main GPS window, now choose the @code{Build} menu, then @code{Make},
+and select @file{hello.adb}.
+The Messages window will display the resulting invocations of @command{gcc},
+@command{gnatbind}, and @command{gnatlink}
+(reflecting the default switch settings from the
+project file that you created) and then a ``successful compilation/build''
+message.
+
+To run the program, choose the @code{Build} menu, then @code{Run}, and
+select @command{hello}.
+An @emph{Arguments Selection} window will appear.
+There are no command line arguments, so just click @code{OK}.
+
+The Messages window will now display the program's output (the string
+@code{Hello from GPS}), and at the bottom of the GPS window a status
+update is displayed (@code{Run: hello}).
+Close the GPS window (or select @code{File}, then @code{Exit}) to
+terminate this GPS session.
+@end enumerate
+
+
+
+@node Simple Debugging with GPS
+@subsection Simple Debugging with GPS
+@noindent
+This section illustrates basic debugging techniques (setting breakpoints,
+examining/modifying variables, single stepping).
+
+@enumerate
+@item @emph{Opening a project}
+
+Start GPS and select @code{Open existing project}; browse to
+specify the project file @file{sample.prj} that you had created in the
+earlier example.
+
+@item @emph{Creating a source file}
+
+Select @code{File}, then @code{New}, and type in the following program:
+
+@smallexample @c ada
+@group
+with Ada.Text_IO; use Ada.Text_IO;
+procedure Example is
+ Line : String (1..80);
+ N : Natural;
+begin
+ Put_Line("Type a line of text at each prompt; an empty line to exit");
+ loop
+ Put(": ");
+ Get_Line (Line, N);
+ Put_Line (Line (1..N) );
+ exit when N=0;
+ end loop;
+end Example;
+@end group
+@end smallexample
+
+@noindent
+Select @code{File}, then @code{Save as}, and enter the file name
+@file{example.adb}.
+
+@item @emph{Updating the project file}
+
+Add @code{Example} as a new main unit for the project:
+@enumerate a
+@item
+Select @code{Project}, then @code{Edit Project Properties}.
+
+@item
+Select the @code{Main files} tab, click @code{Add}, then
+select the file @file{example.adb} from the list, and
+click @code{Open}.
+You will see the file name appear in the list of main units
+
+@item
+Click @code{OK}
+@end enumerate
+
+@item @emph{Building/running the executable}
+
+To build the executable
+select @code{Build}, then @code{Make}, and then choose @file{example.adb}.
+
+Run the program to see its effect (in the Messages area).
+Each line that you enter is displayed; an empty line will
+cause the loop to exit and the program to terminate.
+
+@item @emph{Debugging the program}
+
+Note that the @option{-g} switches to @command{gcc} and @command{gnatlink},
+which are required for debugging, are on by default when you create
+a new project.
+Thus unless you intentionally remove these settings, you will be able
+to debug any program that you develop using GPS.
+
+@enumerate a
+@item @emph{Initializing}
+
+Select @code{Debug}, then @code{Initialize}, then @file{example}
+
+@item @emph{Setting a breakpoint}
+
+After performing the initialization step, you will observe a small
+icon to the right of each line number.
+This serves as a toggle for breakpoints; clicking the icon will
+set a breakpoint at the corresponding line (the icon will change to
+a red circle with an ``x''), and clicking it again
+will remove the breakpoint / reset the icon.
+
+For purposes of this example, set a breakpoint at line 10 (the
+statement @code{Put_Line@ (Line@ (1..N));}
+
+@item @emph{Starting program execution}
+
+Select @code{Debug}, then @code{Run}. When the
+@code{Program Arguments} window appears, click @code{OK}.
+A console window will appear; enter some line of text,
+e.g. @code{abcde}, at the prompt.
+The program will pause execution when it gets to the
+breakpoint, and the corresponding line is highlighted.
+
+@item @emph{Examining a variable}
+
+Move the mouse over one of the occurrences of the variable @code{N}.
+You will see the value (5) displayed, in ``tool tip'' fashion.
+Right click on @code{N}, select @code{Debug}, then select @code{Display N}.
+You will see information about @code{N} appear in the @code{Debugger Data}
+pane, showing the value as 5.
+
+
+@item @emph{Assigning a new value to a variable}
+
+Right click on the @code{N} in the @code{Debugger Data} pane, and
+select @code{Set value of N}.
+When the input window appears, enter the value @code{4} and click
+@code{OK}.
+This value does not automatically appear in the @code{Debugger Data}
+pane; to see it, right click again on the @code{N} in the
+@code{Debugger Data} pane and select @code{Update value}.
+The new value, 4, will appear in red.
+
+@item @emph{Single stepping}
+
+Select @code{Debug}, then @code{Next}.
+This will cause the next statement to be executed, in this case the
+call of @code{Put_Line} with the string slice.
+Notice in the console window that the displayed string is simply
+@code{abcd} and not @code{abcde} which you had entered.
+This is because the upper bound of the slice is now 4 rather than 5.
+
+@item @emph{Removing a breakpoint}
+
+Toggle the breakpoint icon at line 10.
+
+@item @emph{Resuming execution from a breakpoint}
+
+Select @code{Debug}, then @code{Continue}.
+The program will reach the next iteration of the loop, and
+wait for input after displaying the prompt.
+This time, just hit the @kbd{Enter} key.
+The value of @code{N} will be 0, and the program will terminate.
+The console window will disappear.
+@end enumerate
+@end enumerate
+
+
+@node Introduction to Glide and GVD
+@section Introduction to Glide and GVD
+@cindex Glide
+@cindex GVD
+@noindent
+This section describes the main features of Glide,
+a GNAT graphical IDE, and also shows how to use the basic commands in GVD,
+the GNU Visual Debugger.
+These tools may be present in addition to, or in place of, GPS on some
+platforms.
+Additional information on Glide and GVD may be found
+in the on-line help for these tools.
+
+@menu
+* Building a New Program with Glide::
+* Simple Debugging with GVD::
+* Other Glide Features::
+@end menu
+
+@node Building a New Program with Glide
+@subsection Building a New Program with Glide
+@noindent
+The simplest way to invoke Glide is to enter @command{glide}
+at the command prompt. It will generally be useful to issue this
+as a background command, thus allowing you to continue using
+your command window for other purposes while Glide is running:
+
+@smallexample
+$ glide&
+@end smallexample
+
+@noindent
+Glide will start up with an initial screen displaying the top-level menu items
+as well as some other information. The menu selections are as follows
+@itemize @bullet
+@item @code{Buffers}
+@item @code{Files}
+@item @code{Tools}
+@item @code{Edit}
+@item @code{Search}
+@item @code{Mule}
+@item @code{Glide}
+@item @code{Help}
+@end itemize
+
+@noindent
+For this introductory example, you will need to create a new Ada source file.
+First, select the @code{Files} menu. This will pop open a menu with around
+a dozen or so items. To create a file, select the @code{Open file...} choice.
+Depending on the platform, you may see a pop-up window where you can browse
+to an appropriate directory and then enter the file name, or else simply
+see a line at the bottom of the Glide window where you can likewise enter
+the file name. Note that in Glide, when you attempt to open a non-existent
+file, the effect is to create a file with that name. For this example enter
+@file{hello.adb} as the name of the file.
+
+A new buffer will now appear, occupying the entire Glide window,
+with the file name at the top. The menu selections are slightly different
+from the ones you saw on the opening screen; there is an @code{Entities} item,
+and in place of @code{Glide} there is now an @code{Ada} item. Glide uses
+the file extension to identify the source language, so @file{adb} indicates
+an Ada source file.
+
+You will enter some of the source program lines explicitly,
+and use the syntax-oriented template mechanism to enter other lines.
+First, type the following text:
+@smallexample
+with Ada.Text_IO; use Ada.Text_IO;
+procedure Hello is
+begin
+@end smallexample
+
+@noindent
+Observe that Glide uses different colors to distinguish reserved words from
+identifiers. Also, after the @code{procedure Hello is} line, the cursor is
+automatically indented in anticipation of declarations. When you enter
+@code{begin}, Glide recognizes that there are no declarations and thus places
+@code{begin} flush left. But after the @code{begin} line the cursor is again
+indented, where the statement(s) will be placed.
+
+The main part of the program will be a @code{for} loop. Instead of entering
+the text explicitly, however, use a statement template. Select the @code{Ada}
+item on the top menu bar, move the mouse to the @code{Statements} item,
+and you will see a large selection of alternatives. Choose @code{for loop}.
+You will be prompted (at the bottom of the buffer) for a loop name;
+simply press the @key{Enter} key since a loop name is not needed.
+You should see the beginning of a @code{for} loop appear in the source
+program window. You will now be prompted for the name of the loop variable;
+enter a line with the identifier @code{ind} (lower case). Note that,
+by default, Glide capitalizes the name (you can override such behavior
+if you wish, although this is outside the scope of this introduction).
+Next, Glide prompts you for the loop range; enter a line containing
+@code{1..5} and you will see this also appear in the source program,
+together with the remaining elements of the @code{for} loop syntax.
+
+Next enter the statement (with an intentional error, a missing semicolon)
+that will form the body of the loop:
+@smallexample
+Put_Line("Hello, World" & Integer'Image(I))
+@end smallexample
+
+@noindent
+Finally, type @code{end Hello;} as the last line in the program.
+Now save the file: choose the @code{File} menu item, and then the
+@code{Save buffer} selection. You will see a message at the bottom
+of the buffer confirming that the file has been saved.
+
+You are now ready to attempt to build the program. Select the @code{Ada}
+item from the top menu bar. Although we could choose simply to compile
+the file, we will instead attempt to do a build (which invokes
+@command{gnatmake}) since, if the compile is successful, we want to build
+an executable. Thus select @code{Ada build}. This will fail because of the
+compilation error, and you will notice that the Glide window has been split:
+the top window contains the source file, and the bottom window contains the
+output from the GNAT tools. Glide allows you to navigate from a compilation
+error to the source file position corresponding to the error: click the
+middle mouse button (or simultaneously press the left and right buttons,
+on a two-button mouse) on the diagnostic line in the tool window. The
+focus will shift to the source window, and the cursor will be positioned
+on the character at which the error was detected.
+
+Correct the error: type in a semicolon to terminate the statement.
+Although you can again save the file explicitly, you can also simply invoke
+@code{Ada} @result{} @code{Build} and you will be prompted to save the file.
+This time the build will succeed; the tool output window shows you the
+options that are supplied by default. The GNAT tools' output (e.g.
+object and ALI files, executable) will go in the directory from which
+Glide was launched.
+
+To execute the program, choose @code{Ada} and then @code{Run}.
+You should see the program's output displayed in the bottom window:
+
+@smallexample
+Hello, world 1
+Hello, world 2
+Hello, world 3
+Hello, world 4
+Hello, world 5
+@end smallexample
+
+@node Simple Debugging with GVD
+@subsection Simple Debugging with GVD
+
+@noindent
+This section describes how to set breakpoints, examine/modify variables,
+and step through execution.
+
+In order to enable debugging, you need to pass the @option{-g} switch
+to both the compiler and to @command{gnatlink}. If you are using
+the command line, passing @option{-g} to @command{gnatmake} will have
+this effect. You can then launch GVD, e.g. on the @code{hello} program,
+by issuing the command:
+
+@smallexample
+$ gvd hello
+@end smallexample
+
+@noindent
+If you are using Glide, then @option{-g} is passed to the relevant tools
+by default when you do a build. Start the debugger by selecting the
+@code{Ada} menu item, and then @code{Debug}.
+
+GVD comes up in a multi-part window. One pane shows the names of files
+comprising your executable; another pane shows the source code of the current
+unit (initially your main subprogram), another pane shows the debugger output
+and user interactions, and the fourth pane (the data canvas at the top
+of the window) displays data objects that you have selected.
+
+To the left of the source file pane, you will notice green dots adjacent
+to some lines. These are lines for which object code exists and where
+breakpoints can thus be set. You set/reset a breakpoint by clicking
+the green dot. When a breakpoint is set, the dot is replaced by an @code{X}
+in a red circle. Clicking the circle toggles the breakpoint off,
+and the red circle is replaced by the green dot.
+
+For this example, set a breakpoint at the statement where @code{Put_Line}
+is invoked.
+
+Start program execution by selecting the @code{Run} button on the top menu bar.
+(The @code{Start} button will also start your program, but it will
+cause program execution to break at the entry to your main subprogram.)
+Evidence of reaching the breakpoint will appear: the source file line will be
+highlighted, and the debugger interactions pane will display
+a relevant message.
+
+You can examine the values of variables in several ways. Move the mouse
+over an occurrence of @code{Ind} in the @code{for} loop, and you will see
+the value (now @code{1}) displayed. Alternatively, right-click on @code{Ind}
+and select @code{Display Ind}; a box showing the variable's name and value
+will appear in the data canvas.
+
+Although a loop index is a constant with respect to Ada semantics,
+you can change its value in the debugger. Right-click in the box
+for @code{Ind}, and select the @code{Set Value of Ind} item.
+Enter @code{2} as the new value, and press @command{OK}.
+The box for @code{Ind} shows the update.
+
+Press the @code{Step} button on the top menu bar; this will step through
+one line of program text (the invocation of @code{Put_Line}), and you can
+observe the effect of having modified @code{Ind} since the value displayed
+is @code{2}.
+
+Remove the breakpoint, and resume execution by selecting the @code{Cont}
+button. You will see the remaining output lines displayed in the debugger
+interaction window, along with a message confirming normal program
+termination.
+
+@node Other Glide Features
+@subsection Other Glide Features
+
+@noindent
+You may have observed that some of the menu selections contain abbreviations;
+e.g., @code{(C-x C-f)} for @code{Open file...} in the @code{Files} menu.
+These are @emph{shortcut keys} that you can use instead of selecting
+menu items. The @key{C} stands for @key{Ctrl}; thus @code{(C-x C-f)} means
+@key{Ctrl-x} followed by @key{Ctrl-f}, and this sequence can be used instead
+of selecting @code{Files} and then @code{Open file...}.
+
+To abort a Glide command, type @key{Ctrl-g}.
+
+If you want Glide to start with an existing source file, you can either
+launch Glide as above and then open the file via @code{Files} @result{}
+@code{Open file...}, or else simply pass the name of the source file
+on the command line:
+
+@smallexample
+$ glide hello.adb&
+@end smallexample
+
+@noindent
+While you are using Glide, a number of @emph{buffers} exist.
+You create some explicitly; e.g., when you open/create a file.
+Others arise as an effect of the commands that you issue; e.g., the buffer
+containing the output of the tools invoked during a build. If a buffer
+is hidden, you can bring it into a visible window by first opening
+the @code{Buffers} menu and then selecting the desired entry.
+
+If a buffer occupies only part of the Glide screen and you want to expand it
+to fill the entire screen, then click in the buffer and then select
+@code{Files} @result{} @code{One Window}.
+
+If a window is occupied by one buffer and you want to split the window
+to bring up a second buffer, perform the following steps:
+@itemize @bullet
+@item Select @code{Files} @result{} @code{Split Window};
+this will produce two windows each of which holds the original buffer
+(these are not copies, but rather different views of the same buffer contents)
+
+@item With the focus in one of the windows,
+select the desired buffer from the @code{Buffers} menu
+@end itemize
+
+@noindent
+To exit from Glide, choose @code{Files} @result{} @code{Exit}.
+@end ifclear
+
+@node The GNAT Compilation Model
+@chapter The GNAT Compilation Model
+@cindex GNAT compilation model
+@cindex Compilation model
+
+@menu
+* Source Representation::
+* Foreign Language Representation::
+* File Naming Rules::
+* Using Other File Names::
+* Alternative File Naming Schemes::
+* Generating Object Files::
+* Source Dependencies::
+* The Ada Library Information Files::
+* Binding an Ada Program::
+* Mixed Language Programming::
+* Building Mixed Ada & C++ Programs::
+* Comparison between GNAT and C/C++ Compilation Models::
+* Comparison between GNAT and Conventional Ada Library Models::
+@ifset vms
+* Placement of temporary files::
+@end ifset
+@end menu
+
+@noindent
+This chapter describes the compilation model used by GNAT. Although
+similar to that used by other languages, such as C and C++, this model
+is substantially different from the traditional Ada compilation models,
+which are based on a library. The model is initially described without
+reference to the library-based model. If you have not previously used an
+Ada compiler, you need only read the first part of this chapter. The
+last section describes and discusses the differences between the GNAT
+model and the traditional Ada compiler models. If you have used other
+Ada compilers, this section will help you to understand those
+differences, and the advantages of the GNAT model.
+
+@node Source Representation
+@section Source Representation
+@cindex Latin-1
+
+@noindent
+Ada source programs are represented in standard text files, using
+Latin-1 coding. Latin-1 is an 8-bit code that includes the familiar
+7-bit ASCII set, plus additional characters used for
+representing foreign languages (@pxref{Foreign Language Representation}
+for support of non-USA character sets). The format effector characters
+are represented using their standard ASCII encodings, as follows:
+
+@table @code
+@item VT
+@findex VT
+Vertical tab, @code{16#0B#}
+
+@item HT
+@findex HT
+Horizontal tab, @code{16#09#}
+
+@item CR
+@findex CR
+Carriage return, @code{16#0D#}
+
+@item LF
+@findex LF
+Line feed, @code{16#0A#}
+
+@item FF
+@findex FF
+Form feed, @code{16#0C#}
+@end table
+
+@noindent
+Source files are in standard text file format. In addition, GNAT will
+recognize a wide variety of stream formats, in which the end of physical
+physical lines is marked by any of the following sequences:
+@code{LF}, @code{CR}, @code{CR-LF}, or @code{LF-CR}. This is useful
+in accommodating files that are imported from other operating systems.
+
+@cindex End of source file
+@cindex Source file, end
+@findex SUB
+The end of a source file is normally represented by the physical end of
+file. However, the control character @code{16#1A#} (@code{SUB}) is also
+recognized as signalling the end of the source file. Again, this is
+provided for compatibility with other operating systems where this
+code is used to represent the end of file.
+
+Each file contains a single Ada compilation unit, including any pragmas
+associated with the unit. For example, this means you must place a
+package declaration (a package @dfn{spec}) and the corresponding body in
+separate files. An Ada @dfn{compilation} (which is a sequence of
+compilation units) is represented using a sequence of files. Similarly,
+you will place each subunit or child unit in a separate file.
+
+@node Foreign Language Representation
+@section Foreign Language Representation
+
+@noindent
+GNAT supports the standard character sets defined in Ada 95 as well as
+several other non-standard character sets for use in localized versions
+of the compiler (@pxref{Character Set Control}).
+@menu
+* Latin-1::
+* Other 8-Bit Codes::
+* Wide Character Encodings::
+@end menu
+
+@node Latin-1
+@subsection Latin-1
+@cindex Latin-1
+
+@noindent
+The basic character set is Latin-1. This character set is defined by ISO
+standard 8859, part 1. The lower half (character codes @code{16#00#}
+... @code{16#7F#)} is identical to standard ASCII coding, but the upper half
+is used to represent additional characters. These include extended letters
+used by European languages, such as French accents, the vowels with umlauts
+used in German, and the extra letter A-ring used in Swedish.
+
+@findex Ada.Characters.Latin_1
+For a complete list of Latin-1 codes and their encodings, see the source
+file of library unit @code{Ada.Characters.Latin_1} in file
+@file{a-chlat1.ads}.
+You may use any of these extended characters freely in character or
+string literals. In addition, the extended characters that represent
+letters can be used in identifiers.
+
+@node Other 8-Bit Codes
+@subsection Other 8-Bit Codes
+
+@noindent
+GNAT also supports several other 8-bit coding schemes:
+
+@table @asis
+@item ISO 8859-2 (Latin-2)
+@cindex Latin-2
+@cindex ISO 8859-2
+Latin-2 letters allowed in identifiers, with uppercase and lowercase
+equivalence.
+
+@item ISO 8859-3 (Latin-3)
+@cindex Latin-3
+@cindex ISO 8859-3
+Latin-3 letters allowed in identifiers, with uppercase and lowercase
+equivalence.
+
+@item ISO 8859-4 (Latin-4)
+@cindex Latin-4
+@cindex ISO 8859-4
+Latin-4 letters allowed in identifiers, with uppercase and lowercase
+equivalence.
+
+@item ISO 8859-5 (Cyrillic)
+@cindex ISO 8859-5
+@cindex Cyrillic
+ISO 8859-5 letters (Cyrillic) allowed in identifiers, with uppercase and
+lowercase equivalence.
+
+@item ISO 8859-15 (Latin-9)
+@cindex ISO 8859-15
+@cindex Latin-9
+ISO 8859-15 (Latin-9) letters allowed in identifiers, with uppercase and
+lowercase equivalence
+
+@item IBM PC (code page 437)
+@cindex code page 437
+This code page is the normal default for PCs in the U.S. It corresponds
+to the original IBM PC character set. This set has some, but not all, of
+the extended Latin-1 letters, but these letters do not have the same
+encoding as Latin-1. In this mode, these letters are allowed in
+identifiers with uppercase and lowercase equivalence.
+
+@item IBM PC (code page 850)
+@cindex code page 850
+This code page is a modification of 437 extended to include all the
+Latin-1 letters, but still not with the usual Latin-1 encoding. In this
+mode, all these letters are allowed in identifiers with uppercase and
+lowercase equivalence.
+
+@item Full Upper 8-bit
+Any character in the range 80-FF allowed in identifiers, and all are
+considered distinct. In other words, there are no uppercase and lowercase
+equivalences in this range. This is useful in conjunction with
+certain encoding schemes used for some foreign character sets (e.g.
+the typical method of representing Chinese characters on the PC).
+
+@item No Upper-Half
+No upper-half characters in the range 80-FF are allowed in identifiers.
+This gives Ada 83 compatibility for identifier names.
+@end table
+
+@noindent
+For precise data on the encodings permitted, and the uppercase and lowercase
+equivalences that are recognized, see the file @file{csets.adb} in
+the GNAT compiler sources. You will need to obtain a full source release
+of GNAT to obtain this file.
+
+@node Wide Character Encodings
+@subsection Wide Character Encodings
+
+@noindent
+GNAT allows wide character codes to appear in character and string
+literals, and also optionally in identifiers, by means of the following
+possible encoding schemes:
+
+@table @asis
+
+@item Hex Coding
+In this encoding, a wide character is represented by the following five
+character sequence:
+
+@smallexample
+ESC a b c d
+@end smallexample
+
+@noindent
+Where @code{a}, @code{b}, @code{c}, @code{d} are the four hexadecimal
+characters (using uppercase letters) of the wide character code. For
+example, ESC A345 is used to represent the wide character with code
+@code{16#A345#}.
+This scheme is compatible with use of the full Wide_Character set.
+
+@item Upper-Half Coding
+@cindex Upper-Half Coding
+The wide character with encoding @code{16#abcd#} where the upper bit is on
+(in other words, ``a'' is in the range 8-F) is represented as two bytes,
+@code{16#ab#} and @code{16#cd#}. The second byte cannot be a format control
+character, but is not required to be in the upper half. This method can
+be also used for shift-JIS or EUC, where the internal coding matches the
+external coding.
+
+@item Shift JIS Coding
+@cindex Shift JIS Coding
+A wide character is represented by a two-character sequence,
+@code{16#ab#} and
+@code{16#cd#}, with the restrictions described for upper-half encoding as
+described above. The internal character code is the corresponding JIS
+character according to the standard algorithm for Shift-JIS
+conversion. Only characters defined in the JIS code set table can be
+used with this encoding method.
+
+@item EUC Coding
+@cindex EUC Coding
+A wide character is represented by a two-character sequence
+@code{16#ab#} and
+@code{16#cd#}, with both characters being in the upper half. The internal
+character code is the corresponding JIS character according to the EUC
+encoding algorithm. Only characters defined in the JIS code set table
+can be used with this encoding method.
+
+@item UTF-8 Coding
+A wide character is represented using
+UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
+10646-1/Am.2. Depending on the character value, the representation
+is a one, two, or three byte sequence:
+@smallexample
+@iftex
+@leftskip=.7cm
+@end iftex
+16#0000#-16#007f#: 2#0xxxxxxx#
+16#0080#-16#07ff#: 2#110xxxxx# 2#10xxxxxx#
+16#0800#-16#ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx#
+
+@end smallexample
+
+@noindent
+where the xxx bits correspond to the left-padded bits of the
+16-bit character value. Note that all lower half ASCII characters
+are represented as ASCII bytes and all upper half characters and
+other wide characters are represented as sequences of upper-half
+(The full UTF-8 scheme allows for encoding 31-bit characters as
+6-byte sequences, but in this implementation, all UTF-8 sequences
+of four or more bytes length will be treated as illegal).
+@item Brackets Coding
+In this encoding, a wide character is represented by the following eight
+character sequence:
+
+@smallexample
+[ " a b c d " ]
+@end smallexample
+
+@noindent
+Where @code{a}, @code{b}, @code{c}, @code{d} are the four hexadecimal
+characters (using uppercase letters) of the wide character code. For
+example, [``A345''] is used to represent the wide character with code
+@code{16#A345#}. It is also possible (though not required) to use the
+Brackets coding for upper half characters. For example, the code
+@code{16#A3#} can be represented as @code{[``A3'']}.
+
+This scheme is compatible with use of the full Wide_Character set,
+and is also the method used for wide character encoding in the standard
+ACVC (Ada Compiler Validation Capability) test suite distributions.
+
+@end table
+
+@noindent
+Note: Some of these coding schemes do not permit the full use of the
+Ada 95 character set. For example, neither Shift JIS, nor EUC allow the
+use of the upper half of the Latin-1 set.
+
+@node File Naming Rules
+@section File Naming Rules
+
+@noindent
+The default file name is determined by the name of the unit that the
+file contains. The name is formed by taking the full expanded name of
+the unit and replacing the separating dots with hyphens and using
+^lowercase^uppercase^ for all letters.
+
+An exception arises if the file name generated by the above rules starts
+with one of the characters
+@ifset vms
+A,G,I, or S,
+@end ifset
+@ifclear vms
+a,g,i, or s,
+@end ifclear
+and the second character is a
+minus. In this case, the character ^tilde^dollar sign^ is used in place
+of the minus. The reason for this special rule is to avoid clashes with
+the standard names for child units of the packages System, Ada,
+Interfaces, and GNAT, which use the prefixes
+@ifset vms
+S- A- I- and G-
+@end ifset
+@ifclear vms
+s- a- i- and g-
+@end ifclear
+respectively.
+
+The file extension is @file{.ads} for a spec and
+@file{.adb} for a body. The following list shows some
+examples of these rules.
+
+@table @file
+@item main.ads
+Main (spec)
+@item main.adb
+Main (body)
+@item arith_functions.ads
+Arith_Functions (package spec)
+@item arith_functions.adb
+Arith_Functions (package body)
+@item func-spec.ads
+Func.Spec (child package spec)
+@item func-spec.adb
+Func.Spec (child package body)
+@item main-sub.adb
+Sub (subunit of Main)
+@item ^a~bad.adb^A$BAD.ADB^
+A.Bad (child package body)
+@end table
+
+@noindent
+Following these rules can result in excessively long
+file names if corresponding
+unit names are long (for example, if child units or subunits are
+heavily nested). An option is available to shorten such long file names
+(called file name ``krunching''). This may be particularly useful when
+programs being developed with GNAT are to be used on operating systems
+with limited file name lengths. @xref{Using gnatkr}.
+
+Of course, no file shortening algorithm can guarantee uniqueness over
+all possible unit names; if file name krunching is used, it is your
+responsibility to ensure no name clashes occur. Alternatively you
+can specify the exact file names that you want used, as described
+in the next section. Finally, if your Ada programs are migrating from a
+compiler with a different naming convention, you can use the gnatchop
+utility to produce source files that follow the GNAT naming conventions.
+(For details @pxref{Renaming Files Using gnatchop}.)
+
+Note: in the case of @code{Windows NT/XP} or @code{OpenVMS} operating
+systems, case is not significant. So for example on @code{Windows XP}
+if the canonical name is @code{main-sub.adb}, you can use the file name
+@code{Main-Sub.adb} instead. However, case is significant for other
+operating systems, so for example, if you want to use other than
+canonically cased file names on a Unix system, you need to follow
+the procedures described in the next section.
+
+@node Using Other File Names
+@section Using Other File Names
+@cindex File names
+
+@noindent
+In the previous section, we have described the default rules used by
+GNAT to determine the file name in which a given unit resides. It is
+often convenient to follow these default rules, and if you follow them,
+the compiler knows without being explicitly told where to find all
+the files it needs.
+
+However, in some cases, particularly when a program is imported from
+another Ada compiler environment, it may be more convenient for the
+programmer to specify which file names contain which units. GNAT allows
+arbitrary file names to be used by means of the Source_File_Name pragma.
+The form of this pragma is as shown in the following examples:
+@cindex Source_File_Name pragma
+
+@smallexample @c ada
+@cartouche
+pragma Source_File_Name (My_Utilities.Stacks,
+ Spec_File_Name => "myutilst_a.ada");
+pragma Source_File_name (My_Utilities.Stacks,
+ Body_File_Name => "myutilst.ada");
+@end cartouche
+@end smallexample
+
+@noindent
+As shown in this example, the first argument for the pragma is the unit
+name (in this example a child unit). The second argument has the form
+of a named association. The identifier
+indicates whether the file name is for a spec or a body;
+the file name itself is given by a string literal.
+
+The source file name pragma is a configuration pragma, which means that
+normally it will be placed in the @file{gnat.adc}
+file used to hold configuration
+pragmas that apply to a complete compilation environment.
+For more details on how the @file{gnat.adc} file is created and used
+@pxref{Handling of Configuration Pragmas}
+@cindex @file{gnat.adc}
+
+@ifclear vms
+GNAT allows completely arbitrary file names to be specified using the
+source file name pragma. However, if the file name specified has an
+extension other than @file{.ads} or @file{.adb} it is necessary to use
+a special syntax when compiling the file. The name in this case must be
+preceded by the special sequence @code{-x} followed by a space and the name
+of the language, here @code{ada}, as in:
+
+@smallexample
+$ gcc -c -x ada peculiar_file_name.sim
+@end smallexample
+@end ifclear
+
+@noindent
+@code{gnatmake} handles non-standard file names in the usual manner (the
+non-standard file name for the main program is simply used as the
+argument to gnatmake). Note that if the extension is also non-standard,
+then it must be included in the gnatmake command, it may not be omitted.
+
+@node Alternative File Naming Schemes
+@section Alternative File Naming Schemes
+@cindex File naming schemes, alternative
+@cindex File names
+
+In the previous section, we described the use of the @code{Source_File_Name}
+pragma to allow arbitrary names to be assigned to individual source files.
+However, this approach requires one pragma for each file, and especially in
+large systems can result in very long @file{gnat.adc} files, and also create
+a maintenance problem.
+
+GNAT also provides a facility for specifying systematic file naming schemes
+other than the standard default naming scheme previously described. An
+alternative scheme for naming is specified by the use of
+@code{Source_File_Name} pragmas having the following format:
+@cindex Source_File_Name pragma
+
+@smallexample @c ada
+pragma Source_File_Name (
+ Spec_File_Name => FILE_NAME_PATTERN
+ [,Casing => CASING_SPEC]
+ [,Dot_Replacement => STRING_LITERAL]);
+
+pragma Source_File_Name (
+ Body_File_Name => FILE_NAME_PATTERN
+ [,Casing => CASING_SPEC]
+ [,Dot_Replacement => STRING_LITERAL]);
+
+pragma Source_File_Name (
+ Subunit_File_Name => FILE_NAME_PATTERN
+ [,Casing => CASING_SPEC]
+ [,Dot_Replacement => STRING_LITERAL]);
+
+FILE_NAME_PATTERN ::= STRING_LITERAL
+CASING_SPEC ::= Lowercase | Uppercase | Mixedcase
+@end smallexample
+
+@noindent
+The @code{FILE_NAME_PATTERN} string shows how the file name is constructed.
+It contains a single asterisk character, and the unit name is substituted
+systematically for this asterisk. The optional parameter
+@code{Casing} indicates
+whether the unit name is to be all upper-case letters, all lower-case letters,
+or mixed-case. If no
+@code{Casing} parameter is used, then the default is all
+^lower-case^upper-case^.
+
+The optional @code{Dot_Replacement} string is used to replace any periods
+that occur in subunit or child unit names. If no @code{Dot_Replacement}
+argument is used then separating dots appear unchanged in the resulting
+file name.
+Although the above syntax indicates that the
+@code{Casing} argument must appear
+before the @code{Dot_Replacement} argument, but it
+is also permissible to write these arguments in the opposite order.
+
+As indicated, it is possible to specify different naming schemes for
+bodies, specs, and subunits. Quite often the rule for subunits is the
+same as the rule for bodies, in which case, there is no need to give
+a separate @code{Subunit_File_Name} rule, and in this case the
+@code{Body_File_name} rule is used for subunits as well.
+
+The separate rule for subunits can also be used to implement the rather
+unusual case of a compilation environment (e.g. a single directory) which
+contains a subunit and a child unit with the same unit name. Although
+both units cannot appear in the same partition, the Ada Reference Manual
+allows (but does not require) the possibility of the two units coexisting
+in the same environment.
+
+The file name translation works in the following steps:
+
+@itemize @bullet
+
+@item
+If there is a specific @code{Source_File_Name} pragma for the given unit,
+then this is always used, and any general pattern rules are ignored.
+
+@item
+If there is a pattern type @code{Source_File_Name} pragma that applies to
+the unit, then the resulting file name will be used if the file exists. If
+more than one pattern matches, the latest one will be tried first, and the
+first attempt resulting in a reference to a file that exists will be used.
+
+@item
+If no pattern type @code{Source_File_Name} pragma that applies to the unit
+for which the corresponding file exists, then the standard GNAT default
+naming rules are used.
+
+@end itemize
+
+@noindent
+As an example of the use of this mechanism, consider a commonly used scheme
+in which file names are all lower case, with separating periods copied
+unchanged to the resulting file name, and specs end with @file{.1.ada}, and
+bodies end with @file{.2.ada}. GNAT will follow this scheme if the following
+two pragmas appear:
+
+@smallexample @c ada
+pragma Source_File_Name
+ (Spec_File_Name => "*.1.ada");
+pragma Source_File_Name
+ (Body_File_Name => "*.2.ada");
+@end smallexample
+
+@noindent
+The default GNAT scheme is actually implemented by providing the following
+default pragmas internally:
+
+@smallexample @c ada
+pragma Source_File_Name
+ (Spec_File_Name => "*.ads", Dot_Replacement => "-");
+pragma Source_File_Name
+ (Body_File_Name => "*.adb", Dot_Replacement => "-");
+@end smallexample
+
+@noindent
+Our final example implements a scheme typically used with one of the
+Ada 83 compilers, where the separator character for subunits was ``__''
+(two underscores), specs were identified by adding @file{_.ADA}, bodies
+by adding @file{.ADA}, and subunits by
+adding @file{.SEP}. All file names were
+upper case. Child units were not present of course since this was an
+Ada 83 compiler, but it seems reasonable to extend this scheme to use
+the same double underscore separator for child units.
+
+@smallexample @c ada
+pragma Source_File_Name
+ (Spec_File_Name => "*_.ADA",
+ Dot_Replacement => "__",
+ Casing = Uppercase);
+pragma Source_File_Name
+ (Body_File_Name => "*.ADA",
+ Dot_Replacement => "__",
+ Casing = Uppercase);
+pragma Source_File_Name
+ (Subunit_File_Name => "*.SEP",
+ Dot_Replacement => "__",
+ Casing = Uppercase);
+@end smallexample
+
+@node Generating Object Files
+@section Generating Object Files
+
+@noindent
+An Ada program consists of a set of source files, and the first step in
+compiling the program is to generate the corresponding object files.
+These are generated by compiling a subset of these source files.
+The files you need to compile are the following:
+
+@itemize @bullet
+@item
+If a package spec has no body, compile the package spec to produce the
+object file for the package.
+
+@item
+If a package has both a spec and a body, compile the body to produce the
+object file for the package. The source file for the package spec need
+not be compiled in this case because there is only one object file, which
+contains the code for both the spec and body of the package.
+
+@item
+For a subprogram, compile the subprogram body to produce the object file
+for the subprogram. The spec, if one is present, is as usual in a
+separate file, and need not be compiled.
+
+@item
+@cindex Subunits
+In the case of subunits, only compile the parent unit. A single object
+file is generated for the entire subunit tree, which includes all the
+subunits.
+
+@item
+Compile child units independently of their parent units
+(though, of course, the spec of all the ancestor unit must be present in order
+to compile a child unit).
+
+@item
+@cindex Generics
+Compile generic units in the same manner as any other units. The object
+files in this case are small dummy files that contain at most the
+flag used for elaboration checking. This is because GNAT always handles generic
+instantiation by means of macro expansion. However, it is still necessary to
+compile generic units, for dependency checking and elaboration purposes.
+@end itemize
+
+@noindent
+The preceding rules describe the set of files that must be compiled to
+generate the object files for a program. Each object file has the same
+name as the corresponding source file, except that the extension is
+@file{.o} as usual.
+
+You may wish to compile other files for the purpose of checking their
+syntactic and semantic correctness. For example, in the case where a
+package has a separate spec and body, you would not normally compile the
+spec. However, it is convenient in practice to compile the spec to make
+sure it is error-free before compiling clients of this spec, because such
+compilations will fail if there is an error in the spec.
+
+GNAT provides an option for compiling such files purely for the
+purposes of checking correctness; such compilations are not required as
+part of the process of building a program. To compile a file in this
+checking mode, use the @option{-gnatc} switch.
+
+@node Source Dependencies
+@section Source Dependencies
+
+@noindent
+A given object file clearly depends on the source file which is compiled
+to produce it. Here we are using @dfn{depends} in the sense of a typical
+@code{make} utility; in other words, an object file depends on a source
+file if changes to the source file require the object file to be
+recompiled.
+In addition to this basic dependency, a given object may depend on
+additional source files as follows:
+
+@itemize @bullet
+@item
+If a file being compiled @code{with}'s a unit @var{X}, the object file
+depends on the file containing the spec of unit @var{X}. This includes
+files that are @code{with}'ed implicitly either because they are parents
+of @code{with}'ed child units or they are run-time units required by the
+language constructs used in a particular unit.
+
+@item
+If a file being compiled instantiates a library level generic unit, the
+object file depends on both the spec and body files for this generic
+unit.
+
+@item
+If a file being compiled instantiates a generic unit defined within a
+package, the object file depends on the body file for the package as
+well as the spec file.
+
+@item
+@findex Inline
+@cindex @option{-gnatn} switch
+If a file being compiled contains a call to a subprogram for which
+pragma @code{Inline} applies and inlining is activated with the
+@option{-gnatn} switch, the object file depends on the file containing the
+body of this subprogram as well as on the file containing the spec. Note
+that for inlining to actually occur as a result of the use of this switch,
+it is necessary to compile in optimizing mode.
+
+@cindex @option{-gnatN} switch
+The use of @option{-gnatN} activates a more extensive inlining optimization
+that is performed by the front end of the compiler. This inlining does
+not require that the code generation be optimized. Like @option{-gnatn},
+the use of this switch generates additional dependencies.
+Note that
+@option{-gnatN} automatically implies @option{-gnatn} so it is not necessary
+to specify both options.
+
+@item
+If an object file O depends on the proper body of a subunit through inlining
+or instantiation, it depends on the parent unit of the subunit. This means that
+any modification of the parent unit or one of its subunits affects the
+compilation of O.
+
+@item
+The object file for a parent unit depends on all its subunit body files.
+
+@item
+The previous two rules meant that for purposes of computing dependencies and
+recompilation, a body and all its subunits are treated as an indivisible whole.
+
+@noindent
+These rules are applied transitively: if unit @code{A} @code{with}'s
+unit @code{B}, whose elaboration calls an inlined procedure in package
+@code{C}, the object file for unit @code{A} will depend on the body of
+@code{C}, in file @file{c.adb}.
+
+The set of dependent files described by these rules includes all the
+files on which the unit is semantically dependent, as described in the
+Ada 95 Language Reference Manual. However, it is a superset of what the
+ARM describes, because it includes generic, inline, and subunit dependencies.
+
+An object file must be recreated by recompiling the corresponding source
+file if any of the source files on which it depends are modified. For
+example, if the @code{make} utility is used to control compilation,
+the rule for an Ada object file must mention all the source files on
+which the object file depends, according to the above definition.
+The determination of the necessary
+recompilations is done automatically when one uses @code{gnatmake}.
+@end itemize
+
+@node The Ada Library Information Files
+@section The Ada Library Information Files
+@cindex Ada Library Information files
+@cindex @file{ALI} files
+
+@noindent
+Each compilation actually generates two output files. The first of these
+is the normal object file that has a @file{.o} extension. The second is a
+text file containing full dependency information. It has the same
+name as the source file, but an @file{.ali} extension.
+This file is known as the Ada Library Information (@file{ALI}) file.
+The following information is contained in the @file{ALI} file.
+
+@itemize @bullet
+@item
+Version information (indicates which version of GNAT was used to compile
+the unit(s) in question)
+
+@item
+Main program information (including priority and time slice settings,
+as well as the wide character encoding used during compilation).
+
+@item
+List of arguments used in the @code{gcc} command for the compilation
+
+@item
+Attributes of the unit, including configuration pragmas used, an indication
+of whether the compilation was successful, exception model used etc.
+
+@item
+A list of relevant restrictions applying to the unit (used for consistency)
+checking.
+
+@item
+Categorization information (e.g. use of pragma @code{Pure}).
+
+@item
+Information on all @code{with}'ed units, including presence of
+@code{Elaborate} or @code{Elaborate_All} pragmas.
+
+@item
+Information from any @code{Linker_Options} pragmas used in the unit
+
+@item
+Information on the use of @code{Body_Version} or @code{Version}
+attributes in the unit.
+
+@item
+Dependency information. This is a list of files, together with
+time stamp and checksum information. These are files on which
+the unit depends in the sense that recompilation is required
+if any of these units are modified.
+
+@item
+Cross-reference data. Contains information on all entities referenced
+in the unit. Used by tools like @code{gnatxref} and @code{gnatfind} to
+provide cross-reference information.
+
+@end itemize
+
+@noindent
+For a full detailed description of the format of the @file{ALI} file,
+see the source of the body of unit @code{Lib.Writ}, contained in file
+@file{lib-writ.adb} in the GNAT compiler sources.
+
+@node Binding an Ada Program
+@section Binding an Ada Program
+
+@noindent
+When using languages such as C and C++, once the source files have been
+compiled the only remaining step in building an executable program
+is linking the object modules together. This means that it is possible to
+link an inconsistent version of a program, in which two units have
+included different versions of the same header.
+
+The rules of Ada do not permit such an inconsistent program to be built.
+For example, if two clients have different versions of the same package,
+it is illegal to build a program containing these two clients.
+These rules are enforced by the GNAT binder, which also determines an
+elaboration order consistent with the Ada rules.
+
+The GNAT binder is run after all the object files for a program have
+been created. It is given the name of the main program unit, and from
+this it determines the set of units required by the program, by reading the
+corresponding ALI files. It generates error messages if the program is
+inconsistent or if no valid order of elaboration exists.
+
+If no errors are detected, the binder produces a main program, in Ada by
+default, that contains calls to the elaboration procedures of those
+compilation unit that require them, followed by
+a call to the main program. This Ada program is compiled to generate the
+object file for the main program. The name of
+the Ada file is @file{b~@var{xxx}.adb} (with the corresponding spec
+@file{b~@var{xxx}.ads}) where @var{xxx} is the name of the
+main program unit.
+
+Finally, the linker is used to build the resulting executable program,
+using the object from the main program from the bind step as well as the
+object files for the Ada units of the program.
+
+@node Mixed Language Programming
+@section Mixed Language Programming
+@cindex Mixed Language Programming
+
+@noindent
+This section describes how to develop a mixed-language program,
+specifically one that comprises units in both Ada and C.
+
+@menu
+* Interfacing to C::
+* Calling Conventions::
+@end menu
+
+@node Interfacing to C
+@subsection Interfacing to C
+@noindent
+Interfacing Ada with a foreign language such as C involves using
+compiler directives to import and/or export entity definitions in each
+language---using @code{extern} statements in C, for instance, and the
+@code{Import}, @code{Export}, and @code{Convention} pragmas in Ada. For
+a full treatment of these topics, read Appendix B, section 1 of the Ada
+95 Language Reference Manual.
+
+There are two ways to build a program using GNAT that contains some Ada
+sources and some foreign language sources, depending on whether or not
+the main subprogram is written in Ada. Here is a source example with
+the main subprogram in Ada:
+
+@smallexample
+/* file1.c */
+#include <stdio.h>
+
+void print_num (int num)
+@{
+ printf ("num is %d.\n", num);
+ return;
+@}
+
+/* file2.c */
+
+/* num_from_Ada is declared in my_main.adb */
+extern int num_from_Ada;
+
+int get_num (void)
+@{
+ return num_from_Ada;
+@}
+@end smallexample
+
+@smallexample @c ada
+-- my_main.adb
+procedure My_Main is
+
+ -- Declare then export an Integer entity called num_from_Ada
+ My_Num : Integer := 10;
+ pragma Export (C, My_Num, "num_from_Ada");
+
+ -- Declare an Ada function spec for Get_Num, then use
+ -- C function get_num for the implementation.
+ function Get_Num return Integer;
+ pragma Import (C, Get_Num, "get_num");
+
+ -- Declare an Ada procedure spec for Print_Num, then use
+ -- C function print_num for the implementation.
+ procedure Print_Num (Num : Integer);
+ pragma Import (C, Print_Num, "print_num");
+
+begin
+ Print_Num (Get_Num);
+end My_Main;
+@end smallexample
+
+@enumerate
+@item
+To build this example, first compile the foreign language files to
+generate object files:
+@smallexample
+gcc -c file1.c
+gcc -c file2.c
+@end smallexample
+
+@item
+Then, compile the Ada units to produce a set of object files and ALI
+files:
+@smallexample
+gnatmake ^-c^/ACTIONS=COMPILE^ my_main.adb
+@end smallexample
+
+@item
+Run the Ada binder on the Ada main program:
+@smallexample
+gnatbind my_main.ali
+@end smallexample
+
+@item
+Link the Ada main program, the Ada objects and the other language
+objects:
+@smallexample
+gnatlink my_main.ali file1.o file2.o
+@end smallexample
+@end enumerate
+
+The last three steps can be grouped in a single command:
+@smallexample
+gnatmake my_main.adb -largs file1.o file2.o
+@end smallexample
+
+@cindex Binder output file
+@noindent
+If the main program is in a language other than Ada, then you may have
+more than one entry point into the Ada subsystem. You must use a special
+binder option to generate callable routines that initialize and
+finalize the Ada units (@pxref{Binding with Non-Ada Main Programs}).
+Calls to the initialization and finalization routines must be inserted
+in the main program, or some other appropriate point in the code. The
+call to initialize the Ada units must occur before the first Ada
+subprogram is called, and the call to finalize the Ada units must occur
+after the last Ada subprogram returns. The binder will place the
+initialization and finalization subprograms into the
+@file{b~@var{xxx}.adb} file where they can be accessed by your C
+sources. To illustrate, we have the following example:
+
+@smallexample
+/* main.c */
+extern void adainit (void);
+extern void adafinal (void);
+extern int add (int, int);
+extern int sub (int, int);
+
+int main (int argc, char *argv[])
+@{
+ int a = 21, b = 7;
+
+ adainit();
+
+ /* Should print "21 + 7 = 28" */
+ printf ("%d + %d = %d\n", a, b, add (a, b));
+ /* Should print "21 - 7 = 14" */
+ printf ("%d - %d = %d\n", a, b, sub (a, b));
+
+ adafinal();
+@}
+@end smallexample
+
+@smallexample @c ada
+-- unit1.ads
+package Unit1 is
+ function Add (A, B : Integer) return Integer;
+ pragma Export (C, Add, "add");
+end Unit1;
+
+-- unit1.adb
+package body Unit1 is
+ function Add (A, B : Integer) return Integer is
+ begin
+ return A + B;
+ end Add;
+end Unit1;
+
+-- unit2.ads
+package Unit2 is
+ function Sub (A, B : Integer) return Integer;
+ pragma Export (C, Sub, "sub");
+end Unit2;
+
+-- unit2.adb
+package body Unit2 is
+ function Sub (A, B : Integer) return Integer is
+ begin
+ return A - B;
+ end Sub;
+end Unit2;
+@end smallexample
+
+@enumerate
+@item
+The build procedure for this application is similar to the last
+example's. First, compile the foreign language files to generate object
+files:
+@smallexample
+gcc -c main.c
+@end smallexample
+
+@item
+Next, compile the Ada units to produce a set of object files and ALI
+files:
+@smallexample
+gnatmake ^-c^/ACTIONS=COMPILE^ unit1.adb
+gnatmake ^-c^/ACTIONS=COMPILE^ unit2.adb
+@end smallexample
+
+@item
+Run the Ada binder on every generated ALI file. Make sure to use the
+@option{-n} option to specify a foreign main program:
+@smallexample
+gnatbind ^-n^/NOMAIN^ unit1.ali unit2.ali
+@end smallexample
+
+@item
+Link the Ada main program, the Ada objects and the foreign language
+objects. You need only list the last ALI file here:
+@smallexample
+gnatlink unit2.ali main.o -o exec_file
+@end smallexample
+
+This procedure yields a binary executable called @file{exec_file}.
+@end enumerate
+
+@node Calling Conventions
+@subsection Calling Conventions
+@cindex Foreign Languages
+@cindex Calling Conventions
+GNAT follows standard calling sequence conventions and will thus interface
+to any other language that also follows these conventions. The following
+Convention identifiers are recognized by GNAT:
+
+@table @code
+@cindex Interfacing to Ada
+@cindex Other Ada compilers
+@cindex Convention Ada
+@item Ada
+This indicates that the standard Ada calling sequence will be
+used and all Ada data items may be passed without any limitations in the
+case where GNAT is used to generate both the caller and callee. It is also
+possible to mix GNAT generated code and code generated by another Ada
+compiler. In this case, the data types should be restricted to simple
+cases, including primitive types. Whether complex data types can be passed
+depends on the situation. Probably it is safe to pass simple arrays, such
+as arrays of integers or floats. Records may or may not work, depending
+on whether both compilers lay them out identically. Complex structures
+involving variant records, access parameters, tasks, or protected types,
+are unlikely to be able to be passed.
+
+Note that in the case of GNAT running
+on a platform that supports DEC Ada 83, a higher degree of compatibility
+can be guaranteed, and in particular records are layed out in an identical
+manner in the two compilers. Note also that if output from two different
+compilers is mixed, the program is responsible for dealing with elaboration
+issues. Probably the safest approach is to write the main program in the
+version of Ada other than GNAT, so that it takes care of its own elaboration
+requirements, and then call the GNAT-generated adainit procedure to ensure
+elaboration of the GNAT components. Consult the documentation of the other
+Ada compiler for further details on elaboration.
+
+However, it is not possible to mix the tasking run time of GNAT and
+DEC Ada 83, All the tasking operations must either be entirely within
+GNAT compiled sections of the program, or entirely within DEC Ada 83
+compiled sections of the program.
+
+@cindex Interfacing to Assembly
+@cindex Convention Assembler
+@item Assembler
+Specifies assembler as the convention. In practice this has the
+same effect as convention Ada (but is not equivalent in the sense of being
+considered the same convention).
+
+@cindex Convention Asm
+@findex Asm
+@item Asm
+Equivalent to Assembler.
+
+@cindex Interfacing to COBOL
+@cindex Convention COBOL
+@findex COBOL
+@item COBOL
+Data will be passed according to the conventions described
+in section B.4 of the Ada 95 Reference Manual.
+
+@findex C
+@cindex Interfacing to C
+@cindex Convention C
+@item C
+Data will be passed according to the conventions described
+in section B.3 of the Ada 95 Reference Manual.
+
+@findex C varargs function
+@cindex Intefacing to C varargs function
+@cindex varargs function intefacs
+@item C varargs function
+In C, @code{varargs} allows a function to take a variable number of
+arguments. There is no direct equivalent in this to Ada. One
+approach that can be used is to create a C wrapper for each
+different profile and then interface to this C wrapper. For
+example, to print an @code{int} value using @code{printf},
+create a C function @code{printfi} that takes two arguments, a
+pointer to a string and an int, and calls @code{printf}.
+Then in the Ada program, use pragma @code{Import} to
+interface to printfi.
+
+It may work on some platforms to directly interface to
+a @code{varargs} function by providing a specific Ada profile
+for a a particular call. However, this does not work on
+all platforms, since there is no guarantee that the
+calling sequence for a two argument normal C function
+is the same as for calling a @code{varargs} C function with
+the same two arguments.
+
+@cindex Convention Default
+@findex Default
+@item Default
+Equivalent to C.
+
+@cindex Convention External
+@findex External
+@item External
+Equivalent to C.
+
+@findex C++
+@cindex Interfacing to C++
+@cindex Convention C++
+@item CPP
+This stands for C++. For most purposes this is identical to C.
+See the separate description of the specialized GNAT pragmas relating to
+C++ interfacing for further details.
+
+@findex Fortran
+@cindex Interfacing to Fortran
+@cindex Convention Fortran
+@item Fortran
+Data will be passed according to the conventions described
+in section B.5 of the Ada 95 Reference Manual.
+
+@item Intrinsic
+This applies to an intrinsic operation, as defined in the Ada 95
+Reference Manual. If a a pragma Import (Intrinsic) applies to a subprogram,
+this means that the body of the subprogram is provided by the compiler itself,
+usually by means of an efficient code sequence, and that the user does not
+supply an explicit body for it. In an application program, the pragma can
+only be applied to the following two sets of names, which the GNAT compiler
+recognizes.
+
+@itemize @bullet
+@item
+Rotate_Left, Rotate_Right, Shift_Left, Shift_Right, Shift_Right_-
+Arithmetic. The corresponding subprogram declaration must have
+two formal parameters. The
+first one must be a signed integer type or a modular type with a binary
+modulus, and the second parameter must be of type Natural.
+The return type must be the same as the type of the first argument. The size
+of this type can only be 8, 16, 32, or 64.
+@item binary arithmetic operators: ``+'', ``-'', ``*'', ``/''
+The corresponding operator declaration must have parameters and result type
+that have the same root numeric type (for example, all three are long_float
+types). This simplifies the definition of operations that use type checking
+to perform dimensional checks:
+
+@smallexample @c ada
+type Distance is new Long_Float;
+type Time is new Long_Float;
+type Velocity is new Long_Float;
+function "/" (D : Distance; T : Time)
+ return Velocity;
+pragma Import (Intrinsic, "/");
+@end smallexample
+
+@noindent
+This common idiom is often programmed with a generic definition and an
+explicit body. The pragma makes it simpler to introduce such declarations.
+It incurs no overhead in compilation time or code size, because it is
+implemented as a single machine instruction.
+@end itemize
+@noindent
+
+@ifset unw
+@findex Stdcall
+@cindex Convention Stdcall
+@item Stdcall
+This is relevant only to NT/Win95 implementations of GNAT,
+and specifies that the Stdcall calling sequence will be used, as defined
+by the NT API.
+
+@findex DLL
+@cindex Convention DLL
+@item DLL
+This is equivalent to Stdcall.
+
+@findex Win32
+@cindex Convention Win32
+@item Win32
+This is equivalent to Stdcall.
+@end ifset
+
+@findex Stubbed
+@cindex Convention Stubbed
+@item Stubbed
+This is a special convention that indicates that the compiler
+should provide a stub body that raises @code{Program_Error}.
+@end table
+
+@noindent
+GNAT additionally provides a useful pragma @code{Convention_Identifier}
+that can be used to parametrize conventions and allow additional synonyms
+to be specified. For example if you have legacy code in which the convention
+identifier Fortran77 was used for Fortran, you can use the configuration
+pragma:
+
+@smallexample @c ada
+pragma Convention_Identifier (Fortran77, Fortran);
+@end smallexample
+
+@noindent
+And from now on the identifier Fortran77 may be used as a convention
+identifier (for example in an @code{Import} pragma) with the same
+meaning as Fortran.
+
+@node Building Mixed Ada & C++ Programs
+@section Building Mixed Ada & C++ Programs
+
+@noindent
+A programmer inexperienced with mixed-language development may find that
+building an application containing both Ada and C++ code can be a
+challenge. As a matter of fact, interfacing with C++ has not been
+standardized in the Ada 95 Reference Manual due to the immaturity of --
+and lack of standards for -- C++ at the time. This section gives a few
+hints that should make this task easier. The first section addresses
+the differences regarding interfacing with C. The second section
+looks into the delicate problem of linking the complete application from
+its Ada and C++ parts. The last section gives some hints on how the GNAT
+run time can be adapted in order to allow inter-language dispatching
+with a new C++ compiler.
+
+@menu
+* Interfacing to C++::
+* Linking a Mixed C++ & Ada Program::
+* A Simple Example::
+* Adapting the Run Time to a New C++ Compiler::
+@end menu
+
+@node Interfacing to C++
+@subsection Interfacing to C++
+
+@noindent
+GNAT supports interfacing with C++ compilers generating code that is
+compatible with the standard Application Binary Interface of the given
+platform.
+
+@noindent
+Interfacing can be done at 3 levels: simple data, subprograms, and
+classes. In the first two cases, GNAT offers a specific @var{Convention
+CPP} that behaves exactly like @var{Convention C}. Usually, C++ mangles
+the names of subprograms, and currently, GNAT does not provide any help
+to solve the demangling problem. This problem can be addressed in two
+ways:
+@itemize @bullet
+@item
+by modifying the C++ code in order to force a C convention using
+the @code{extern "C"} syntax.
+
+@item
+by figuring out the mangled name and use it as the Link_Name argument of
+the pragma import.
+@end itemize
+
+@noindent
+Interfacing at the class level can be achieved by using the GNAT specific
+pragmas such as @code{CPP_Class} and @code{CPP_Virtual}. See the GNAT
+Reference Manual for additional information.
+
+@node Linking a Mixed C++ & Ada Program
+@subsection Linking a Mixed C++ & Ada Program
+
+@noindent
+Usually the linker of the C++ development system must be used to link
+mixed applications because most C++ systems will resolve elaboration
+issues (such as calling constructors on global class instances)
+transparently during the link phase. GNAT has been adapted to ease the
+use of a foreign linker for the last phase. Three cases can be
+considered:
+@enumerate
+
+@item
+Using GNAT and G++ (GNU C++ compiler) from the same GCC installation:
+The C++ linker can simply be called by using the C++ specific driver
+called @code{c++}. Note that this setup is not very common because it
+may involve recompiling the whole GCC tree from sources, which makes it
+harder to upgrade the compilation system for one language without
+destabilizing the other.
+
+@smallexample
+$ c++ -c file1.C
+$ c++ -c file2.C
+$ gnatmake ada_unit -largs file1.o file2.o --LINK=c++
+@end smallexample
+
+@item
+Using GNAT and G++ from two different GCC installations: If both
+compilers are on the PATH, the previous method may be used. It is
+important to note that environment variables such as C_INCLUDE_PATH,
+GCC_EXEC_PREFIX, BINUTILS_ROOT, and GCC_ROOT will affect both compilers
+at the same time and may make one of the two compilers operate
+improperly if set during invocation of the wrong compiler. It is also
+very important that the linker uses the proper @file{libgcc.a} GCC
+library -- that is, the one from the C++ compiler installation. The
+implicit link command as suggested in the gnatmake command from the
+former example can be replaced by an explicit link command with the
+full-verbosity option in order to verify which library is used:
+@smallexample
+$ gnatbind ada_unit
+$ gnatlink -v -v ada_unit file1.o file2.o --LINK=c++
+@end smallexample
+If there is a problem due to interfering environment variables, it can
+be worked around by using an intermediate script. The following example
+shows the proper script to use when GNAT has not been installed at its
+default location and g++ has been installed at its default location:
+
+@smallexample
+$ cat ./my_script
+#!/bin/sh
+unset BINUTILS_ROOT
+unset GCC_ROOT
+c++ $*
+$ gnatlink -v -v ada_unit file1.o file2.o --LINK=./my_script
+@end smallexample
+
+@item
+Using a non-GNU C++ compiler: The commands previously described can be
+used to insure that the C++ linker is used. Nonetheless, you need to add
+the path to libgcc explicitly, since some libraries needed by GNAT are
+located in this directory:
+
+@smallexample
+$ cat ./my_script
+#!/bin/sh
+CC $* `gcc -print-libgcc-file-name`
+$ gnatlink ada_unit file1.o file2.o --LINK=./my_script
+@end smallexample
+
+Where CC is the name of the non-GNU C++ compiler.
+
+@end enumerate
+
+@node A Simple Example
+@subsection A Simple Example
+@noindent
+The following example, provided as part of the GNAT examples, shows how
+to achieve procedural interfacing between Ada and C++ in both
+directions. The C++ class A has two methods. The first method is exported
+to Ada by the means of an extern C wrapper function. The second method
+calls an Ada subprogram. On the Ada side, The C++ calls are modelled by
+a limited record with a layout comparable to the C++ class. The Ada
+subprogram, in turn, calls the C++ method. So, starting from the C++
+main program, the process passes back and forth between the two
+languages.
+
+@noindent
+Here are the compilation commands:
+@smallexample
+$ gnatmake -c simple_cpp_interface
+$ c++ -c cpp_main.C
+$ c++ -c ex7.C
+$ gnatbind -n simple_cpp_interface
+$ gnatlink simple_cpp_interface -o cpp_main --LINK=$(CPLUSPLUS)
+ -lstdc++ ex7.o cpp_main.o
+@end smallexample
+
+@noindent
+Here are the corresponding sources:
+@smallexample
+
+//cpp_main.C
+
+#include "ex7.h"
+
+extern "C" @{
+ void adainit (void);
+ void adafinal (void);
+ void method1 (A *t);
+@}
+
+void method1 (A *t)
+@{
+ t->method1 ();
+@}
+
+int main ()
+@{
+ A obj;
+ adainit ();
+ obj.method2 (3030);
+ adafinal ();
+@}
+
+//ex7.h
+
+class Origin @{
+ public:
+ int o_value;
+@};
+class A : public Origin @{
+ public:
+ void method1 (void);
+ virtual void method2 (int v);
+ A();
+ int a_value;
+@};
+
+//ex7.C
+
+#include "ex7.h"
+#include <stdio.h>
+
+extern "C" @{ void ada_method2 (A *t, int v);@}
+
+void A::method1 (void)
+@{
+ a_value = 2020;
+ printf ("in A::method1, a_value = %d \n",a_value);
+
+@}
+
+void A::method2 (int v)
+@{
+ ada_method2 (this, v);
+ printf ("in A::method2, a_value = %d \n",a_value);
+
+@}
+
+A::A(void)
+@{
+ a_value = 1010;
+ printf ("in A::A, a_value = %d \n",a_value);
+@}
+
+-- Ada sources
+@b{package} @b{body} Simple_Cpp_Interface @b{is}
+
+ @b{procedure} Ada_Method2 (This : @b{in} @b{out} A; V : Integer) @b{is}
+ @b{begin}
+ Method1 (This);
+ This.A_Value := V;
+ @b{end} Ada_Method2;
+
+@b{end} Simple_Cpp_Interface;
+
+@b{package} Simple_Cpp_Interface @b{is}
+ @b{type} A @b{is} @b{limited}
+ @b{record}
+ O_Value : Integer;
+ A_Value : Integer;
+ @b{end} @b{record};
+ @b{pragma} Convention (C, A);
+
+ @b{procedure} Method1 (This : @b{in} @b{out} A);
+ @b{pragma} Import (C, Method1);
+
+ @b{procedure} Ada_Method2 (This : @b{in} @b{out} A; V : Integer);
+ @b{pragma} Export (C, Ada_Method2);
+
+@b{end} Simple_Cpp_Interface;
+@end smallexample
+
+@node Adapting the Run Time to a New C++ Compiler
+@subsection Adapting the Run Time to a New C++ Compiler
+@noindent
+GNAT offers the capability to derive Ada 95 tagged types directly from
+preexisting C++ classes and . See ``Interfacing with C++'' in the
+@cite{GNAT Reference Manual}. The mechanism used by GNAT for achieving
+such a goal
+has been made user configurable through a GNAT library unit
+@code{Interfaces.CPP}. The default version of this file is adapted to
+the GNU C++ compiler. Internal knowledge of the virtual
+table layout used by the new C++ compiler is needed to configure
+properly this unit. The Interface of this unit is known by the compiler
+and cannot be changed except for the value of the constants defining the
+characteristics of the virtual table: CPP_DT_Prologue_Size, CPP_DT_Entry_Size,
+CPP_TSD_Prologue_Size, CPP_TSD_Entry_Size. Read comments in the source
+of this unit for more details.
+
+@node Comparison between GNAT and C/C++ Compilation Models
+@section Comparison between GNAT and C/C++ Compilation Models
+
+@noindent
+The GNAT model of compilation is close to the C and C++ models. You can
+think of Ada specs as corresponding to header files in C. As in C, you
+don't need to compile specs; they are compiled when they are used. The
+Ada @code{with} is similar in effect to the @code{#include} of a C
+header.
+
+One notable difference is that, in Ada, you may compile specs separately
+to check them for semantic and syntactic accuracy. This is not always
+possible with C headers because they are fragments of programs that have
+less specific syntactic or semantic rules.
+
+The other major difference is the requirement for running the binder,
+which performs two important functions. First, it checks for
+consistency. In C or C++, the only defense against assembling
+inconsistent programs lies outside the compiler, in a makefile, for
+example. The binder satisfies the Ada requirement that it be impossible
+to construct an inconsistent program when the compiler is used in normal
+mode.
+
+@cindex Elaboration order control
+The other important function of the binder is to deal with elaboration
+issues. There are also elaboration issues in C++ that are handled
+automatically. This automatic handling has the advantage of being
+simpler to use, but the C++ programmer has no control over elaboration.
+Where @code{gnatbind} might complain there was no valid order of
+elaboration, a C++ compiler would simply construct a program that
+malfunctioned at run time.
+
+@node Comparison between GNAT and Conventional Ada Library Models
+@section Comparison between GNAT and Conventional Ada Library Models
+
+@noindent
+This section is intended to be useful to Ada programmers who have
+previously used an Ada compiler implementing the traditional Ada library
+model, as described in the Ada 95 Language Reference Manual. If you
+have not used such a system, please go on to the next section.
+
+@cindex GNAT library
+In GNAT, there is no @dfn{library} in the normal sense. Instead, the set of
+source files themselves acts as the library. Compiling Ada programs does
+not generate any centralized information, but rather an object file and
+a ALI file, which are of interest only to the binder and linker.
+In a traditional system, the compiler reads information not only from
+the source file being compiled, but also from the centralized library.
+This means that the effect of a compilation depends on what has been
+previously compiled. In particular:
+
+@itemize @bullet
+@item
+When a unit is @code{with}'ed, the unit seen by the compiler corresponds
+to the version of the unit most recently compiled into the library.
+
+@item
+Inlining is effective only if the necessary body has already been
+compiled into the library.
+
+@item
+Compiling a unit may obsolete other units in the library.
+@end itemize
+
+@noindent
+In GNAT, compiling one unit never affects the compilation of any other
+units because the compiler reads only source files. Only changes to source
+files can affect the results of a compilation. In particular:
+
+@itemize @bullet
+@item
+When a unit is @code{with}'ed, the unit seen by the compiler corresponds
+to the source version of the unit that is currently accessible to the
+compiler.
+
+@item
+@cindex Inlining
+Inlining requires the appropriate source files for the package or
+subprogram bodies to be available to the compiler. Inlining is always
+effective, independent of the order in which units are complied.
+
+@item
+Compiling a unit never affects any other compilations. The editing of
+sources may cause previous compilations to be out of date if they
+depended on the source file being modified.
+@end itemize
+
+@noindent
+The most important result of these differences is that order of compilation
+is never significant in GNAT. There is no situation in which one is
+required to do one compilation before another. What shows up as order of
+compilation requirements in the traditional Ada library becomes, in
+GNAT, simple source dependencies; in other words, there is only a set
+of rules saying what source files must be present when a file is
+compiled.
+
+@ifset vms
+@node Placement of temporary files
+@section Placement of temporary files
+@cindex Temporary files (user control over placement)
+
+@noindent
+GNAT creates temporary files in the directory designated by the environment
+variable @env{TMPDIR}.
+(See the HP @emph{C RTL Reference Manual} on the function @code{getenv()}
+for detailed information on how environment variables are resolved.
+For most users the easiest way to make use of this feature is to simply
+define @env{TMPDIR} as a job level logical name).
+For example, if you wish to use a Ramdisk (assuming DECRAM is installed)
+for compiler temporary files, then you can include something like the
+following command in your @file{LOGIN.COM} file:
+
+@smallexample
+$ define/job TMPDIR "/disk$scratchram/000000/temp/"
+@end smallexample
+
+@noindent
+If @env{TMPDIR} is not defined, then GNAT uses the directory designated by
+@env{TMP}; if @env{TMP} is not defined, then GNAT uses the directory
+designated by @env{TEMP}.
+If none of these environment variables are defined then GNAT uses the
+directory designated by the logical name @code{SYS$SCRATCH:}
+(by default the user's home directory). If all else fails
+GNAT uses the current directory for temporary files.
+@end ifset
+
+
+@c *************************
+@node Compiling Using gcc
+@chapter Compiling Using @code{gcc}
+
+@noindent
+This chapter discusses how to compile Ada programs using the @code{gcc}
+command. It also describes the set of switches
+that can be used to control the behavior of the compiler.
+@menu
+* Compiling Programs::
+* Switches for gcc::
+* Search Paths and the Run-Time Library (RTL)::
+* Order of Compilation Issues::
+* Examples::
+@end menu
+
+@node Compiling Programs
+@section Compiling Programs
+
+@noindent
+The first step in creating an executable program is to compile the units
+of the program using the @code{gcc} command. You must compile the
+following files:
+
+@itemize @bullet
+@item
+the body file (@file{.adb}) for a library level subprogram or generic
+subprogram
+
+@item
+the spec file (@file{.ads}) for a library level package or generic
+package that has no body
+
+@item
+the body file (@file{.adb}) for a library level package
+or generic package that has a body
+
+@end itemize
+
+@noindent
+You need @emph{not} compile the following files
+
+@itemize @bullet
+
+@item
+the spec of a library unit which has a body
+
+@item
+subunits
+@end itemize
+
+@noindent
+because they are compiled as part of compiling related units. GNAT
+package specs
+when the corresponding body is compiled, and subunits when the parent is
+compiled.
+
+@cindex cannot generate code
+If you attempt to compile any of these files, you will get one of the
+following error messages (where fff is the name of the file you compiled):
+
+@smallexample
+cannot generate code for file @var{fff} (package spec)
+to check package spec, use -gnatc
+
+cannot generate code for file @var{fff} (missing subunits)
+to check parent unit, use -gnatc
+
+cannot generate code for file @var{fff} (subprogram spec)
+to check subprogram spec, use -gnatc
+
+cannot generate code for file @var{fff} (subunit)
+to check subunit, use -gnatc
+@end smallexample
+
+@noindent
+As indicated by the above error messages, if you want to submit
+one of these files to the compiler to check for correct semantics
+without generating code, then use the @option{-gnatc} switch.
+
+The basic command for compiling a file containing an Ada unit is
+
+@smallexample
+$ gcc -c [@var{switches}] @file{file name}
+@end smallexample
+
+@noindent
+where @var{file name} is the name of the Ada file (usually
+having an extension
+@file{.ads} for a spec or @file{.adb} for a body).
+@ifclear vms
+You specify the
+@option{-c} switch to tell @code{gcc} to compile, but not link, the file.
+@end ifclear
+The result of a successful compilation is an object file, which has the
+same name as the source file but an extension of @file{.o} and an Ada
+Library Information (ALI) file, which also has the same name as the
+source file, but with @file{.ali} as the extension. GNAT creates these
+two output files in the current directory, but you may specify a source
+file in any directory using an absolute or relative path specification
+containing the directory information.
+
+@findex gnat1
+@code{gcc} is actually a driver program that looks at the extensions of
+the file arguments and loads the appropriate compiler. For example, the
+GNU C compiler is @file{cc1}, and the Ada compiler is @file{gnat1}.
+These programs are in directories known to the driver program (in some
+configurations via environment variables you set), but need not be in
+your path. The @code{gcc} driver also calls the assembler and any other
+utilities needed to complete the generation of the required object
+files.
+
+It is possible to supply several file names on the same @code{gcc}
+command. This causes @code{gcc} to call the appropriate compiler for
+each file. For example, the following command lists three separate
+files to be compiled:
+
+@smallexample
+$ gcc -c x.adb y.adb z.c
+@end smallexample
+
+@noindent
+calls @code{gnat1} (the Ada compiler) twice to compile @file{x.adb} and
+@file{y.adb}, and @code{cc1} (the C compiler) once to compile @file{z.c}.
+The compiler generates three object files @file{x.o}, @file{y.o} and
+@file{z.o} and the two ALI files @file{x.ali} and @file{y.ali} from the
+Ada compilations. Any switches apply to all the files ^listed,^listed.^
+@ifclear vms
+except for
+@option{-gnat@var{x}} switches, which apply only to Ada compilations.
+@end ifclear
+
+@node Switches for gcc
+@section Switches for @code{gcc}
+
+@noindent
+The @code{gcc} command accepts switches that control the
+compilation process. These switches are fully described in this section.
+First we briefly list all the switches, in alphabetical order, then we
+describe the switches in more detail in functionally grouped sections.
+
+@menu
+* Output and Error Message Control::
+* Warning Message Control::
+* Debugging and Assertion Control::
+* Validity Checking::
+* Style Checking::
+* Run-Time Checks::
+* Stack Overflow Checking::
+* Using gcc for Syntax Checking::
+* Using gcc for Semantic Checking::
+* Compiling Ada 83 Programs::
+* Character Set Control::
+* File Naming Control::
+* Subprogram Inlining Control::
+* Auxiliary Output Control::
+* Debugging Control::
+* Exception Handling Control::
+* Units to Sources Mapping Files::
+* Integrated Preprocessing::
+* Code Generation Control::
+@ifset vms
+* Return Codes::
+@end ifset
+@end menu
+
+@table @option
+@c !sort!
+@ifclear vms
+@cindex @option{-b} (@code{gcc})
+@item -b @var{target}
+Compile your program to run on @var{target}, which is the name of a
+system configuration. You must have a GNAT cross-compiler built if
+@var{target} is not the same as your host system.
+
+@item -B@var{dir}
+@cindex @option{-B} (@code{gcc})
+Load compiler executables (for example, @code{gnat1}, the Ada compiler)
+from @var{dir} instead of the default location. Only use this switch
+when multiple versions of the GNAT compiler are available. See the
+@code{gcc} manual page for further details. You would normally use the
+@option{-b} or @option{-V} switch instead.
+
+@item -c
+@cindex @option{-c} (@code{gcc})
+Compile. Always use this switch when compiling Ada programs.
+
+Note: for some other languages when using @code{gcc}, notably in
+the case of C and C++, it is possible to use
+use @code{gcc} without a @option{-c} switch to
+compile and link in one step. In the case of GNAT, you
+cannot use this approach, because the binder must be run
+and @code{gcc} cannot be used to run the GNAT binder.
+@end ifclear
+
+@item -fno-inline
+@cindex @option{-fno-inline} (@code{gcc})
+Suppresses all back-end inlining, even if other optimization or inlining
+switches are set.
+This includes suppression of inlining that results
+from the use of the pragma @code{Inline_Always}.
+See also @option{-gnatn} and @option{-gnatN}.
+
+@item -fno-strict-aliasing
+@cindex @option{-fno-strict-aliasing} (@code{gcc})
+Causes the compiler to avoid assumptions regarding non-aliasing
+of objects of different types. See section
+@pxref{Optimization and Strict Aliasing} for details.
+
+@item -fstack-check
+@cindex @option{-fstack-check} (@code{gcc})
+Activates stack checking.
+See @ref{Stack Overflow Checking} for details of the use of this option.
+
+@item ^-g^/DEBUG^
+@cindex @option{^-g^/DEBUG^} (@code{gcc})
+Generate debugging information. This information is stored in the object
+file and copied from there to the final executable file by the linker,
+where it can be read by the debugger. You must use the
+@option{^-g^/DEBUG^} switch if you plan on using the debugger.
+
+@item -gnat83
+@cindex @option{-gnat83} (@code{gcc})
+Enforce Ada 83 restrictions.
+
+@item -gnata
+@cindex @option{-gnata} (@code{gcc})
+Assertions enabled. @code{Pragma Assert} and @code{pragma Debug} to be
+activated.
+
+@item -gnatA
+@cindex @option{-gnatA} (@code{gcc})
+Avoid processing @file{gnat.adc}. If a gnat.adc file is present,
+it will be ignored.
+
+@item -gnatb
+@cindex @option{-gnatb} (@code{gcc})
+Generate brief messages to @file{stderr} even if verbose mode set.
+
+@item -gnatc
+@cindex @option{-gnatc} (@code{gcc})
+Check syntax and semantics only (no code generation attempted).
+
+@item -gnatd
+@cindex @option{-gnatd} (@code{gcc})
+Specify debug options for the compiler. The string of characters after
+the @option{-gnatd} specify the specific debug options. The possible
+characters are 0-9, a-z, A-Z, optionally preceded by a dot. See
+compiler source file @file{debug.adb} for details of the implemented
+debug options. Certain debug options are relevant to applications
+programmers, and these are documented at appropriate points in this
+users guide.
+
+@item -gnatD
+@cindex @option{-gnatD} (@code{gcc})
+Create expanded source files for source level debugging. This switch
+also suppress generation of cross-reference information
+(see @option{-gnatx}).
+
+@item -gnatec=@var{path}
+@cindex @option{-gnatec} (@code{gcc})
+Specify a configuration pragma file
+@ifclear vms
+(the equal sign is optional)
+@end ifclear
+(see @ref{The Configuration Pragmas Files}).
+
+@item ^-gnateD^/DATA_PREPROCESSING=^symbol[=value]
+@cindex @option{-gnateD} (@code{gcc})
+Defines a symbol, associated with value, for preprocessing.
+(see @ref{Integrated Preprocessing})
+
+@item -gnatef
+@cindex @option{-gnatef} (@code{gcc})
+Display full source path name in brief error messages.
+
+@item -gnatem=@var{path}
+@cindex @option{-gnatem} (@code{gcc})
+Specify a mapping file
+@ifclear vms
+(the equal sign is optional)
+@end ifclear
+(see @ref{Units to Sources Mapping Files}).
+
+@item -gnatep=@var{file}
+@cindex @option{-gnatep} (@code{gcc})
+Specify a preprocessing data file
+@ifclear vms
+(the equal sign is optional)
+@end ifclear
+(see @ref{Integrated Preprocessing}).
+
+@item -gnatE
+@cindex @option{-gnatE} (@code{gcc})
+Full dynamic elaboration checks.
+
+@item -gnatf
+@cindex @option{-gnatf} (@code{gcc})
+Full errors. Multiple errors per line, all undefined references, do not
+attempt to suppress cascaded errors.
+
+@item -gnatF
+@cindex @option{-gnatF} (@code{gcc})
+Externals names are folded to all uppercase.
+
+@item -gnatg
+@cindex @option{-gnatg} (@code{gcc})
+Internal GNAT implementation mode. This should not be used for
+applications programs, it is intended only for use by the compiler
+and its run-time library. For documentation, see the GNAT sources.
+Note that @option{-gnatg} implies @option{-gnatwu} so that warnings
+are generated on unreferenced entities, and all warnings are treated
+as errors.
+
+@item -gnatG
+@cindex @option{-gnatG} (@code{gcc})
+List generated expanded code in source form.
+
+@item ^-gnath^/HELP^
+@cindex @option{^-gnath^/HELP^} (@code{gcc})
+Output usage information. The output is written to @file{stdout}.
+
+@item ^-gnati^/IDENTIFIER_CHARACTER_SET=^@var{c}
+@cindex @option{^-gnati^/IDENTIFIER_CHARACTER_SET^} (@code{gcc})
+Identifier character set
+@ifclear vms
+(@var{c}=1/2/3/4/8/9/p/f/n/w).
+@end ifclear
+@ifset vms
+For details of the possible selections for @var{c},
+see @xref{Character Set Control}.
+@end ifset
+
+@item -gnatk=@var{n}
+@cindex @option{-gnatk} (@code{gcc})
+Limit file names to @var{n} (1-999) characters ^(@code{k} = krunch)^^.
+
+@item -gnatl
+@cindex @option{-gnatl} (@code{gcc})
+Output full source listing with embedded error messages.
+
+@item -gnatL
+@cindex @option{-gnatL} (@code{gcc})
+Use the longjmp/setjmp method for exception handling
+
+@item -gnatm=@var{n}
+@cindex @option{-gnatm} (@code{gcc})
+Limit number of detected error or warning messages to @var{n}
+where @var{n} is in the range 1..999_999. The default setting if
+no switch is given is 9999. Compilation is terminated if this
+limit is exceeded.
+
+@item -gnatn
+@cindex @option{-gnatn} (@code{gcc})
+Activate inlining for subprograms for which
+pragma @code{inline} is specified. This inlining is performed
+by the GCC back-end.
+
+@item -gnatN
+@cindex @option{-gnatN} (@code{gcc})
+Activate front end inlining for subprograms for which
+pragma @code{Inline} is specified. This inlining is performed
+by the front end and will be visible in the
+@option{-gnatG} output.
+In some cases, this has proved more effective than the back end
+inlining resulting from the use of
+@option{-gnatn}.
+Note that
+@option{-gnatN} automatically implies
+@option{-gnatn} so it is not necessary
+to specify both options. There are a few cases that the back-end inlining
+catches that cannot be dealt with in the front-end.
+
+@item -gnato
+@cindex @option{-gnato} (@code{gcc})
+Enable numeric overflow checking (which is not normally enabled by
+default). Not that division by zero is a separate check that is not
+controlled by this switch (division by zero checking is on by default).
+
+@item -gnatp
+@cindex @option{-gnatp} (@code{gcc})
+Suppress all checks.
+
+@item -gnatP
+@cindex @option{-gnatP} (@code{gcc})
+Enable polling. This is required on some systems (notably Windows NT) to
+obtain asynchronous abort and asynchronous transfer of control capability.
+See the description of pragma Polling in the GNAT Reference Manual for
+full details.
+
+@item -gnatq
+@cindex @option{-gnatq} (@code{gcc})
+Don't quit; try semantics, even if parse errors.
+
+@item -gnatQ
+@cindex @option{-gnatQ} (@code{gcc})
+Don't quit; generate @file{ALI} and tree files even if illegalities.
+
+@item ^-gnatR[0/1/2/3[s]]^/REPRESENTATION_INFO^
+@cindex @option{-gnatR} (@code{gcc})
+Output representation information for declared types and objects.
+
+@item -gnats
+@cindex @option{-gnats} (@code{gcc})
+Syntax check only.
+
+@item -gnatS
+@cindex @option{-gnatS} (@code{gcc})
+Print package Standard.
+
+@item -gnatt
+@cindex @option{-gnatt} (@code{gcc})
+Generate tree output file.
+
+@item ^-gnatT^/TABLE_MULTIPLIER=^@var{nnn}
+@cindex @option{^-gnatT^/TABLE_MULTIPLIER^} (@code{gcc})
+All compiler tables start at @var{nnn} times usual starting size.
+
+@item -gnatu
+@cindex @option{-gnatu} (@code{gcc})
+List units for this compilation.
+
+@item -gnatU
+@cindex @option{-gnatU} (@code{gcc})
+Tag all error messages with the unique string ``error:''
+
+@item -gnatv
+@cindex @option{-gnatv} (@code{gcc})
+Verbose mode. Full error output with source lines to @file{stdout}.
+
+@item -gnatV
+@cindex @option{-gnatV} (@code{gcc})
+Control level of validity checking. See separate section describing
+this feature.
+
+@item ^-gnatw@var{xxx}^/WARNINGS=(@var{option}[,...])^
+@cindex @option{^-gnatw^/WARNINGS^} (@code{gcc})
+Warning mode where
+^@var{xxx} is a string of option letters that^the list of options^ denotes
+the exact warnings that
+are enabled or disabled. (see @ref{Warning Message Control})
+
+@item ^-gnatW^/WIDE_CHARACTER_ENCODING=^@var{e}
+@cindex @option{^-gnatW^/WIDE_CHARACTER_ENCODING^} (@code{gcc})
+Wide character encoding method
+@ifclear vms
+(@var{e}=n/h/u/s/e/8).
+@end ifclear
+@ifset vms
+(@var{e}=@code{BRACKETS, NONE, HEX, UPPER, SHIFT_JIS, EUC, UTF8})
+@end ifset
+
+@item -gnatx
+@cindex @option{-gnatx} (@code{gcc})
+Suppress generation of cross-reference information.
+
+@item ^-gnaty^/STYLE_CHECKS=(option,option..)^
+@cindex @option{^-gnaty^/STYLE_CHECKS^} (@code{gcc})
+Enable built-in style checks. (see @ref{Style Checking})
+
+@item ^-gnatz^/DISTRIBUTION_STUBS=^@var{m}
+@cindex @option{^-gnatz^/DISTRIBUTION_STUBS^} (@code{gcc})
+Distribution stub generation and compilation
+@ifclear vms
+(@var{m}=r/c for receiver/caller stubs).
+@end ifclear
+@ifset vms
+(@var{m}=@code{RECEIVER} or @code{CALLER} to specify the type of stubs
+to be generated and compiled).
+@end ifset
+
+@item -gnatZ
+Use the zero cost method for exception handling
+
+@item ^-I^/SEARCH=^@var{dir}
+@cindex @option{^-I^/SEARCH^} (@code{gcc})
+@cindex RTL
+Direct GNAT to search the @var{dir} directory for source files needed by
+the current compilation
+(@pxref{Search Paths and the Run-Time Library (RTL)}).
+
+@item ^-I-^/NOCURRENT_DIRECTORY^
+@cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gcc})
+@cindex RTL
+Except for the source file named in the command line, do not look for source
+files in the directory containing the source file named in the command line
+(@pxref{Search Paths and the Run-Time Library (RTL)}).
+
+@ifclear vms
+@item -mbig-switch
+@cindex @option{-mbig-switch} (@command{gcc})
+@cindex @code{case} statement (effect of @option{-mbig-switch} option)
+This standard gcc switch causes the compiler to use larger offsets in its
+jump table representation for @code{case} statements.
+This may result in less efficient code, but is sometimes necessary
+(for example on HP-UX targets)
+@cindex HP-UX and @option{-mbig-switch} option
+in order to compile large and/or nested @code{case} statements.
+
+@item -o @var{file}
+@cindex @option{-o} (@code{gcc})
+This switch is used in @code{gcc} to redirect the generated object file
+and its associated ALI file. Beware of this switch with GNAT, because it may
+cause the object file and ALI file to have different names which in turn
+may confuse the binder and the linker.
+@end ifclear
+
+@item -nostdinc
+@cindex @option{-nostdinc} (@command{gcc})
+Inhibit the search of the default location for the GNAT Run Time
+Library (RTL) source files.
+
+@item -nostdlib
+@cindex @option{-nostdlib} (@command{gcc})
+Inhibit the search of the default location for the GNAT Run Time
+Library (RTL) ALI files.
+
+@ifclear vms
+@item -O[@var{n}]
+@cindex @option{-O} (@code{gcc})
+@var{n} controls the optimization level.
+
+@table @asis
+@item n = 0
+No optimization, the default setting if no @option{-O} appears
+
+@item n = 1
+Normal optimization, the default if you specify @option{-O} without
+an operand.
+
+@item n = 2
+Extensive optimization
+
+@item n = 3
+Extensive optimization with automatic inlining of subprograms not
+specified by pragma @code{Inline}. This applies only to
+inlining within a unit. For details on control of inlining
+see @xref{Subprogram Inlining Control}.
+@end table
+@end ifclear
+
+@ifset vms
+@item /NOOPTIMIZE
+@cindex @option{/NOOPTIMIZE} (@code{GNAT COMPILE})
+Equivalent to @option{/OPTIMIZE=NONE}.
+This is the default behavior in the absence of an @option{/OPTMIZE}
+qualifier.
+
+@item /OPTIMIZE[=(keyword[,...])]
+@cindex @option{/OPTIMIZE} (@code{GNAT COMPILE})
+Selects the level of optimization for your program. The supported
+keywords are as follows:
+@table @code
+@item ALL
+Perform most optimizations, including those that
+are expensive.
+This is the default if the @option{/OPTMIZE} qualifier is supplied
+without keyword options.
+
+@item NONE
+Do not do any optimizations. Same as @code{/NOOPTIMIZE}.
+
+@item SOME
+Perform some optimizations, but omit ones that are costly.
+
+@item DEVELOPMENT
+Same as @code{SOME}.
+
+@item INLINING
+Full optimization, and also attempt automatic inlining of small
+subprograms within a unit even when pragma @code{Inline}
+is not specified (@pxref{Inlining of Subprograms}).
+
+@item UNROLL_LOOPS
+Try to unroll loops. This keyword may be specified together with
+any keyword above other than @code{NONE}. Loop unrolling
+usually, but not always, improves the performance of programs.
+@end table
+@end ifset
+
+@ifclear vms
+@item -pass-exit-codes
+@cindex @option{-pass-exit-codes} (@code{gcc})
+Catch exit codes from the compiler and use the most meaningful as
+exit status.
+@end ifclear
+
+@item --RTS=@var{rts-path}
+@cindex @option{--RTS} (@code{gcc})
+Specifies the default location of the runtime library. Same meaning as the
+equivalent @code{gnatmake} flag (see @ref{Switches for gnatmake}).
+
+@item ^-S^/ASM^
+@cindex @option{^-S^/ASM^} (@code{gcc})
+^Used in place of @option{-c} to^Used to^
+cause the assembler source file to be
+generated, using @file{^.s^.S^} as the extension,
+instead of the object file.
+This may be useful if you need to examine the generated assembly code.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@code{gcc})
+Show commands generated by the @code{gcc} driver. Normally used only for
+debugging purposes or if you need to be sure what version of the
+compiler you are executing.
+
+@ifclear vms
+@item -V @var{ver}
+@cindex @option{-V} (@code{gcc})
+Execute @var{ver} version of the compiler. This is the @code{gcc}
+version, not the GNAT version.
+@end ifclear
+
+@end table
+
+@ifclear vms
+You may combine a sequence of GNAT switches into a single switch. For
+example, the combined switch
+
+@cindex Combining GNAT switches
+@smallexample
+-gnatofi3
+@end smallexample
+
+@noindent
+is equivalent to specifying the following sequence of switches:
+
+@smallexample
+-gnato -gnatf -gnati3
+@end smallexample
+@end ifclear
+
+
+@c NEED TO CHECK THIS FOR VMS
+
+@noindent
+The following restrictions apply to the combination of switches
+in this manner:
+
+@itemize @bullet
+@item
+The switch @option{-gnatc} if combined with other switches must come
+first in the string.
+
+@item
+The switch @option{-gnats} if combined with other switches must come
+first in the string.
+
+@item
+The switches
+@option{^-gnatz^/DISTRIBUTION_STUBS^}, @option{-gnatzc}, and @option{-gnatzr}
+may not be combined with any other switches.
+
+@ifclear vms
+@item
+Once a ``y'' appears in the string (that is a use of the @option{-gnaty}
+switch), then all further characters in the switch are interpreted
+as style modifiers (see description of @option{-gnaty}).
+
+@item
+Once a ``d'' appears in the string (that is a use of the @option{-gnatd}
+switch), then all further characters in the switch are interpreted
+as debug flags (see description of @option{-gnatd}).
+
+@item
+Once a ``w'' appears in the string (that is a use of the @option{-gnatw}
+switch), then all further characters in the switch are interpreted
+as warning mode modifiers (see description of @option{-gnatw}).
+
+@item
+Once a ``V'' appears in the string (that is a use of the @option{-gnatV}
+switch), then all further characters in the switch are interpreted
+as validity checking options (see description of @option{-gnatV}).
+@end ifclear
+@end itemize
+
+
+@node Output and Error Message Control
+@subsection Output and Error Message Control
+@findex stderr
+
+@noindent
+The standard default format for error messages is called ``brief format''.
+Brief format messages are written to @file{stderr} (the standard error
+file) and have the following form:
+
+@smallexample
+e.adb:3:04: Incorrect spelling of keyword "function"
+e.adb:4:20: ";" should be "is"
+@end smallexample
+
+@noindent
+The first integer after the file name is the line number in the file,
+and the second integer is the column number within the line.
+@code{glide} can parse the error messages
+and point to the referenced character.
+The following switches provide control over the error message
+format:
+
+@table @option
+@c !sort!
+@item -gnatv
+@cindex @option{-gnatv} (@code{gcc})
+@findex stdout
+@ifclear vms
+The v stands for verbose.
+@end ifclear
+The effect of this setting is to write long-format error
+messages to @file{stdout} (the standard output file.
+The same program compiled with the
+@option{-gnatv} switch would generate:
+
+@smallexample
+@cartouche
+3. funcion X (Q : Integer)
+ |
+>>> Incorrect spelling of keyword "function"
+4. return Integer;
+ |
+>>> ";" should be "is"
+@end cartouche
+@end smallexample
+
+@noindent
+The vertical bar indicates the location of the error, and the @samp{>>>}
+prefix can be used to search for error messages. When this switch is
+used the only source lines output are those with errors.
+
+@item -gnatl
+@cindex @option{-gnatl} (@code{gcc})
+@ifclear vms
+The @code{l} stands for list.
+@end ifclear
+This switch causes a full listing of
+the file to be generated. The output might look as follows:
+
+@smallexample
+@cartouche
+ 1. procedure E is
+ 2. V : Integer;
+ 3. funcion X (Q : Integer)
+ |
+ >>> Incorrect spelling of keyword "function"
+ 4. return Integer;
+ |
+ >>> ";" should be "is"
+ 5. begin
+ 6. return Q + Q;
+ 7. end;
+ 8. begin
+ 9. V := X + X;
+10.end E;
+@end cartouche
+@end smallexample
+
+@noindent
+@findex stderr
+When you specify the @option{-gnatv} or @option{-gnatl} switches and
+standard output is redirected, a brief summary is written to
+@file{stderr} (standard error) giving the number of error messages and
+warning messages generated.
+
+@item -gnatU
+@cindex @option{-gnatU} (@code{gcc})
+This switch forces all error messages to be preceded by the unique
+string ``error:''. This means that error messages take a few more
+characters in space, but allows easy searching for and identification
+of error messages.
+
+@item -gnatb
+@cindex @option{-gnatb} (@code{gcc})
+@ifclear vms
+The @code{b} stands for brief.
+@end ifclear
+This switch causes GNAT to generate the
+brief format error messages to @file{stderr} (the standard error
+file) as well as the verbose
+format message or full listing (which as usual is written to
+@file{stdout} (the standard output file).
+
+@item -gnatm^^=^@var{n}
+@cindex @option{-gnatm} (@code{gcc})
+@ifclear vms
+The @code{m} stands for maximum.
+@end ifclear
+@var{n} is a decimal integer in the
+range of 1 to 999 and limits the number of error messages to be
+generated. For example, using @option{-gnatm2} might yield
+
+@smallexample
+e.adb:3:04: Incorrect spelling of keyword "function"
+e.adb:5:35: missing ".."
+fatal error: maximum errors reached
+compilation abandoned
+@end smallexample
+
+@item -gnatf
+@cindex @option{-gnatf} (@code{gcc})
+@cindex Error messages, suppressing
+@ifclear vms
+The @code{f} stands for full.
+@end ifclear
+Normally, the compiler suppresses error messages that are likely to be
+redundant. This switch causes all error
+messages to be generated. In particular, in the case of
+references to undefined variables. If a given variable is referenced
+several times, the normal format of messages is
+@smallexample
+e.adb:7:07: "V" is undefined (more references follow)
+@end smallexample
+
+@noindent
+where the parenthetical comment warns that there are additional
+references to the variable @code{V}. Compiling the same program with the
+@option{-gnatf} switch yields
+
+@smallexample
+e.adb:7:07: "V" is undefined
+e.adb:8:07: "V" is undefined
+e.adb:8:12: "V" is undefined
+e.adb:8:16: "V" is undefined
+e.adb:9:07: "V" is undefined
+e.adb:9:12: "V" is undefined
+@end smallexample
+
+@noindent
+The @option{-gnatf} switch also generates additional information for
+some error messages. Some examples are:
+
+@itemize @bullet
+@item
+Full details on entities not available in high integrity mode
+@item
+Details on possibly non-portable unchecked conversion
+@item
+List possible interpretations for ambiguous calls
+@item
+Additional details on incorrect parameters
+@end itemize
+
+
+@item -gnatq
+@cindex @option{-gnatq} (@code{gcc})
+@ifclear vms
+The @code{q} stands for quit (really ``don't quit'').
+@end ifclear
+In normal operation mode, the compiler first parses the program and
+determines if there are any syntax errors. If there are, appropriate
+error messages are generated and compilation is immediately terminated.
+This switch tells
+GNAT to continue with semantic analysis even if syntax errors have been
+found. This may enable the detection of more errors in a single run. On
+the other hand, the semantic analyzer is more likely to encounter some
+internal fatal error when given a syntactically invalid tree.
+
+@item -gnatQ
+@cindex @option{-gnatQ} (@code{gcc})
+In normal operation mode, the @file{ALI} file is not generated if any
+illegalities are detected in the program. The use of @option{-gnatQ} forces
+generation of the @file{ALI} file. This file is marked as being in
+error, so it cannot be used for binding purposes, but it does contain
+reasonably complete cross-reference information, and thus may be useful
+for use by tools (e.g. semantic browsing tools or integrated development
+environments) that are driven from the @file{ALI} file. This switch
+implies @option{-gnatq}, since the semantic phase must be run to get a
+meaningful ALI file.
+
+In addition, if @option{-gnatt} is also specified, then the tree file is
+generated even if there are illegalities. It may be useful in this case
+to also specify @option{-gnatq} to ensure that full semantic processing
+occurs. The resulting tree file can be processed by ASIS, for the purpose
+of providing partial information about illegal units, but if the error
+causes the tree to be badly malformed, then ASIS may crash during the
+analysis.
+
+When @option{-gnatQ} is used and the generated @file{ALI} file is marked as
+being in error, @code{gnatmake} will attempt to recompile the source when it
+finds such an @file{ALI} file, including with switch @option{-gnatc}.
+
+Note that @option{-gnatQ} has no effect if @option{-gnats} is specified,
+since ALI files are never generated if @option{-gnats} is set.
+
+@end table
+
+
+@node Warning Message Control
+@subsection Warning Message Control
+@cindex Warning messages
+@noindent
+In addition to error messages, which correspond to illegalities as defined
+in the Ada 95 Reference Manual, the compiler detects two kinds of warning
+situations.
+
+First, the compiler considers some constructs suspicious and generates a
+warning message to alert you to a possible error. Second, if the
+compiler detects a situation that is sure to raise an exception at
+run time, it generates a warning message. The following shows an example
+of warning messages:
+@smallexample
+e.adb:4:24: warning: creation of object may raise Storage_Error
+e.adb:10:17: warning: static value out of range
+e.adb:10:17: warning: "Constraint_Error" will be raised at run time
+@end smallexample
+
+@noindent
+GNAT considers a large number of situations as appropriate
+for the generation of warning messages. As always, warnings are not
+definite indications of errors. For example, if you do an out-of-range
+assignment with the deliberate intention of raising a
+@code{Constraint_Error} exception, then the warning that may be
+issued does not indicate an error. Some of the situations for which GNAT
+issues warnings (at least some of the time) are given in the following
+list. This list is not complete, and new warnings are often added to
+subsequent versions of GNAT. The list is intended to give a general idea
+of the kinds of warnings that are generated.
+
+@itemize @bullet
+@item
+Possible infinitely recursive calls
+
+@item
+Out-of-range values being assigned
+
+@item
+Possible order of elaboration problems
+
+@item
+Unreachable code
+
+@item
+Fixed-point type declarations with a null range
+
+@item
+Variables that are never assigned a value
+
+@item
+Variables that are referenced before being initialized
+
+@item
+Task entries with no corresponding @code{accept} statement
+
+@item
+Duplicate accepts for the same task entry in a @code{select}
+
+@item
+Objects that take too much storage
+
+@item
+Unchecked conversion between types of differing sizes
+
+@item
+Missing @code{return} statement along some execution path in a function
+
+@item
+Incorrect (unrecognized) pragmas
+
+@item
+Incorrect external names
+
+@item
+Allocation from empty storage pool
+
+@item
+Potentially blocking operation in protected type
+
+@item
+Suspicious parenthesization of expressions
+
+@item
+Mismatching bounds in an aggregate
+
+@item
+Attempt to return local value by reference
+
+
+@item
+Premature instantiation of a generic body
+
+@item
+Attempt to pack aliased components
+
+@item
+Out of bounds array subscripts
+
+@item
+Wrong length on string assignment
+
+@item
+Violations of style rules if style checking is enabled
+
+@item
+Unused @code{with} clauses
+
+@item
+@code{Bit_Order} usage that does not have any effect
+
+@item
+@code{Standard.Duration} used to resolve universal fixed expression
+
+@item
+Dereference of possibly null value
+
+@item
+Declaration that is likely to cause storage error
+
+@item
+Internal GNAT unit @code{with}'ed by application unit
+
+@item
+Values known to be out of range at compile time
+
+@item
+Unreferenced labels and variables
+
+@item
+Address overlays that could clobber memory
+
+@item
+Unexpected initialization when address clause present
+
+@item
+Bad alignment for address clause
+
+@item
+Useless type conversions
+
+@item
+Redundant assignment statements and other redundant constructs
+
+@item
+Useless exception handlers
+
+@item
+Accidental hiding of name by child unit
+
+
+@item
+Access before elaboration detected at compile time
+
+@item
+A range in a @code{for} loop that is known to be null or might be null
+
+@end itemize
+
+@noindent
+The following switches are available to control the handling of
+warning messages:
+
+@table @option
+@c !sort!
+@item -gnatwa
+@emph{Activate all optional errors.}
+@cindex @option{-gnatwa} (@code{gcc})
+This switch activates most optional warning messages, see remaining list
+in this section for details on optional warning messages that can be
+individually controlled. The warnings that are not turned on by this
+switch are
+@option{-gnatwd} (implicit dereferencing),
+@option{-gnatwh} (hiding),
+and @option{-gnatwl} (elaboration warnings).
+All other optional warnings are turned on.
+
+@item -gnatwA
+@emph{Suppress all optional errors.}
+@cindex @option{-gnatwA} (@code{gcc})
+This switch suppresses all optional warning messages, see remaining list
+in this section for details on optional warning messages that can be
+individually controlled.
+
+@item -gnatwc
+@emph{Activate warnings on conditionals.}
+@cindex @option{-gnatwc} (@code{gcc})
+@cindex Conditionals, constant
+This switch activates warnings for conditional expressions used in
+tests that are known to be True or False at compile time. The default
+is that such warnings are not generated.
+Note that this warning does
+not get issued for the use of boolean variables or constants whose
+values are known at compile time, since this is a standard technique
+for conditional compilation in Ada, and this would generate too many
+``false positive'' warnings.
+This warning can also be turned on using @option{-gnatwa}.
+
+@item -gnatwC
+@emph{Suppress warnings on conditionals.}
+@cindex @option{-gnatwC} (@code{gcc})
+This switch suppresses warnings for conditional expressions used in
+tests that are known to be True or False at compile time.
+
+@item -gnatwd
+@emph{Activate warnings on implicit dereferencing.}
+@cindex @option{-gnatwd} (@code{gcc})
+If this switch is set, then the use of a prefix of an access type
+in an indexed component, slice, or selected component without an
+explicit @code{.all} will generate a warning. With this warning
+enabled, access checks occur only at points where an explicit
+@code{.all} appears in the source code (assuming no warnings are
+generated as a result of this switch). The default is that such
+warnings are not generated.
+Note that @option{-gnatwa} does not affect the setting of
+this warning option.
+
+@item -gnatwD
+@emph{Suppress warnings on implicit dereferencing.}
+@cindex @option{-gnatwD} (@code{gcc})
+@cindex Implicit dereferencing
+@cindex Dereferencing, implicit
+This switch suppresses warnings for implicit dereferences in
+indexed components, slices, and selected components.
+
+@item -gnatwe
+@emph{Treat warnings as errors.}
+@cindex @option{-gnatwe} (@code{gcc})
+@cindex Warnings, treat as error
+This switch causes warning messages to be treated as errors.
+The warning string still appears, but the warning messages are counted
+as errors, and prevent the generation of an object file.
+
+@item -gnatwf
+@emph{Activate warnings on unreferenced formals.}
+@cindex @option{-gnatwf} (@code{gcc})
+@cindex Formals, unreferenced
+This switch causes a warning to be generated if a formal parameter
+is not referenced in the body of the subprogram. This warning can
+also be turned on using @option{-gnatwa} or @option{-gnatwu}.
+
+@item -gnatwF
+@emph{Suppress warnings on unreferenced formals.}
+@cindex @option{-gnatwF} (@code{gcc})
+This switch suppresses warnings for unreferenced formal
+parameters. Note that the
+combination @option{-gnatwu} followed by @option{-gnatwF} has the
+effect of warning on unreferenced entities other than subprogram
+formals.
+
+@item -gnatwg
+@emph{Activate warnings on unrecognized pragmas.}
+@cindex @option{-gnatwg} (@code{gcc})
+@cindex Pragmas, unrecognized
+This switch causes a warning to be generated if an unrecognized
+pragma is encountered. Apart from issuing this warning, the
+pragma is ignored and has no effect. This warning can
+also be turned on using @option{-gnatwa}. The default
+is that such warnings are issued (satisfying the Ada Reference
+Manual requirement that such warnings appear).
+
+@item -gnatwG
+@emph{Suppress warnings on unrecognized pragmas.}
+@cindex @option{-gnatwG} (@code{gcc})
+This switch suppresses warnings for unrecognized pragmas.
+
+@item -gnatwh
+@emph{Activate warnings on hiding.}
+@cindex @option{-gnatwh} (@code{gcc})
+@cindex Hiding of Declarations
+This switch activates warnings on hiding declarations.
+A declaration is considered hiding
+if it is for a non-overloadable entity, and it declares an entity with the
+same name as some other entity that is directly or use-visible. The default
+is that such warnings are not generated.
+Note that @option{-gnatwa} does not affect the setting of this warning option.
+
+@item -gnatwH
+@emph{Suppress warnings on hiding.}
+@cindex @option{-gnatwH} (@code{gcc})
+This switch suppresses warnings on hiding declarations.
+
+@item -gnatwi
+@emph{Activate warnings on implementation units.}
+@cindex @option{-gnatwi} (@code{gcc})
+This switch activates warnings for a @code{with} of an internal GNAT
+implementation unit, defined as any unit from the @code{Ada},
+@code{Interfaces}, @code{GNAT},
+^^@code{DEC},^ or @code{System}
+hierarchies that is not
+documented in either the Ada Reference Manual or the GNAT
+Programmer's Reference Manual. Such units are intended only
+for internal implementation purposes and should not be @code{with}'ed
+by user programs. The default is that such warnings are generated
+This warning can also be turned on using @option{-gnatwa}.
+
+@item -gnatwI
+@emph{Disable warnings on implementation units.}
+@cindex @option{-gnatwI} (@code{gcc})
+This switch disables warnings for a @code{with} of an internal GNAT
+implementation unit.
+
+@item -gnatwj
+@emph{Activate warnings on obsolescent features (Annex J).}
+@cindex @option{-gnatwj} (@code{gcc})
+@cindex Features, obsolescent
+@cindex Obsolescent features
+If this warning option is activated, then warnings are generated for
+calls to subprograms marked with @code{pragma Obsolescent} and
+for use of features in Annex J of the Ada Reference Manual. In the
+case of Annex J, not all features are flagged. In particular use
+of the renamed packages (like @code{Text_IO}) and use of package
+@code{ASCII} are not flagged, since these are very common and
+would generate many annoying positive warnings. The default is that
+such warnings are not generated.
+
+@item -gnatwJ
+@emph{Suppress warnings on obsolescent features (Annex J).}
+@cindex @option{-gnatwJ} (@code{gcc})
+This switch disables warnings on use of obsolescent features.
+
+@item -gnatwk
+@emph{Activate warnings on variables that could be constants.}
+@cindex @option{-gnatwk} (@code{gcc})
+This switch activates warnings for variables that are initialized but
+never modified, and then could be declared constants.
+
+@item -gnatwK
+@emph{Suppress warnings on variables that could be constants.}
+@cindex @option{-gnatwK} (@code{gcc})
+This switch disables warnings on variables that could be declared constants.
+
+@item -gnatwl
+@emph{Activate warnings for missing elaboration pragmas.}
+@cindex @option{-gnatwl} (@code{gcc})
+@cindex Elaboration, warnings
+This switch activates warnings on missing
+@code{pragma Elaborate_All} statements.
+See the section in this guide on elaboration checking for details on
+when such pragma should be used. Warnings are also generated if you
+are using the static mode of elaboration, and a @code{pragma Elaborate}
+is encountered. The default is that such warnings
+are not generated.
+This warning is not automatically turned on by the use of @option{-gnatwa}.
+
+@item -gnatwL
+@emph{Suppress warnings for missing elaboration pragmas.}
+@cindex @option{-gnatwL} (@code{gcc})
+This switch suppresses warnings on missing pragma Elaborate_All statements.
+See the section in this guide on elaboration checking for details on
+when such pragma should be used.
+
+@item -gnatwm
+@emph{Activate warnings on modified but unreferenced variables.}
+@cindex @option{-gnatwm} (@code{gcc})
+This switch activates warnings for variables that are assigned (using
+an initialization value or with one or more assignment statements) but
+whose value is never read. The warning is suppressed for volatile
+variables and also for variables that are renamings of other variables
+or for which an address clause is given.
+This warning can also be turned on using @option{-gnatwa}.
+
+@item -gnatwM
+@emph{Disable warnings on modified but unreferenced variables.}
+@cindex @option{-gnatwM} (@code{gcc})
+This switch disables warnings for variables that are assigned or
+initialized, but never read.
+
+@item -gnatwn
+@emph{Set normal warnings mode.}
+@cindex @option{-gnatwn} (@code{gcc})
+This switch sets normal warning mode, in which enabled warnings are
+issued and treated as warnings rather than errors. This is the default
+mode. the switch @option{-gnatwn} can be used to cancel the effect of
+an explicit @option{-gnatws} or
+@option{-gnatwe}. It also cancels the effect of the
+implicit @option{-gnatwe} that is activated by the
+use of @option{-gnatg}.
+
+@item -gnatwo
+@emph{Activate warnings on address clause overlays.}
+@cindex @option{-gnatwo} (@code{gcc})
+@cindex Address Clauses, warnings
+This switch activates warnings for possibly unintended initialization
+effects of defining address clauses that cause one variable to overlap
+another. The default is that such warnings are generated.
+This warning can also be turned on using @option{-gnatwa}.
+
+@item -gnatwO
+@emph{Suppress warnings on address clause overlays.}
+@cindex @option{-gnatwO} (@code{gcc})
+This switch suppresses warnings on possibly unintended initialization
+effects of defining address clauses that cause one variable to overlap
+another.
+
+@item -gnatwp
+@emph{Activate warnings on ineffective pragma Inlines.}
+@cindex @option{-gnatwp} (@code{gcc})
+@cindex Inlining, warnings
+This switch activates warnings for failure of front end inlining
+(activated by @option{-gnatN}) to inline a particular call. There are
+many reasons for not being able to inline a call, including most
+commonly that the call is too complex to inline.
+This warning can also be turned on using @option{-gnatwa}.
+
+@item -gnatwP
+@emph{Suppress warnings on ineffective pragma Inlines.}
+@cindex @option{-gnatwP} (@code{gcc})
+This switch suppresses warnings on ineffective pragma Inlines. If the
+inlining mechanism cannot inline a call, it will simply ignore the
+request silently.
+
+@item -gnatwr
+@emph{Activate warnings on redundant constructs.}
+@cindex @option{-gnatwr} (@code{gcc})
+This switch activates warnings for redundant constructs. The following
+is the current list of constructs regarded as redundant:
+This warning can also be turned on using @option{-gnatwa}.
+
+@itemize @bullet
+@item
+Assignment of an item to itself.
+@item
+Type conversion that converts an expression to its own type.
+@item
+Use of the attribute @code{Base} where @code{typ'Base} is the same
+as @code{typ}.
+@item
+Use of pragma @code{Pack} when all components are placed by a record
+representation clause.
+@item
+Exception handler containing only a reraise statement (raise with no
+operand) which has no effect.
+@item
+Use of the operator abs on an operand that is known at compile time
+to be non-negative
+@item
+Use of an unnecessary extra level of parentheses (C-style) around conditions
+in @code{if} statements, @code{while} statements and @code{exit} statements.
+@item
+Comparison of boolean expressions to an explicit True value.
+@end itemize
+
+@item -gnatwR
+@emph{Suppress warnings on redundant constructs.}
+@cindex @option{-gnatwR} (@code{gcc})
+This switch suppresses warnings for redundant constructs.
+
+@item -gnatws
+@emph{Suppress all warnings.}
+@cindex @option{-gnatws} (@code{gcc})
+This switch completely suppresses the
+output of all warning messages from the GNAT front end.
+Note that it does not suppress warnings from the @code{gcc} back end.
+To suppress these back end warnings as well, use the switch @option{-w}
+in addition to @option{-gnatws}.
+
+@item -gnatwu
+@emph{Activate warnings on unused entities.}
+@cindex @option{-gnatwu} (@code{gcc})
+This switch activates warnings to be generated for entities that
+are declared but not referenced, and for units that are @code{with}'ed
+and not
+referenced. In the case of packages, a warning is also generated if
+no entities in the package are referenced. This means that if the package
+is referenced but the only references are in @code{use}
+clauses or @code{renames}
+declarations, a warning is still generated. A warning is also generated
+for a generic package that is @code{with}'ed but never instantiated.
+In the case where a package or subprogram body is compiled, and there
+is a @code{with} on the corresponding spec
+that is only referenced in the body,
+a warning is also generated, noting that the
+@code{with} can be moved to the body. The default is that
+such warnings are not generated.
+This switch also activates warnings on unreferenced formals
+(it is includes the effect of @option{-gnatwf}).
+This warning can also be turned on using @option{-gnatwa}.
+
+@item -gnatwU
+@emph{Suppress warnings on unused entities.}
+@cindex @option{-gnatwU} (@code{gcc})
+This switch suppresses warnings for unused entities and packages.
+It also turns off warnings on unreferenced formals (and thus includes
+the effect of @option{-gnatwF}).
+
+@item -gnatwv
+@emph{Activate warnings on unassigned variables.}
+@cindex @option{-gnatwv} (@code{gcc})
+@cindex Unassigned variable warnings
+This switch activates warnings for access to variables which
+may not be properly initialized. The default is that
+such warnings are generated.
+
+@item -gnatwV
+@emph{Suppress warnings on unassigned variables.}
+@cindex @option{-gnatwV} (@code{gcc})
+This switch suppresses warnings for access to variables which
+may not be properly initialized.
+
+@item -gnatwx
+@emph{Activate warnings on Export/Import pragmas.}
+@cindex @option{-gnatwx} (@code{gcc})
+@cindex Export/Import pragma warnings
+This switch activates warnings on Export/Import pragmas when
+the compiler detects a possible conflict between the Ada and
+foreign language calling sequences. For example, the use of
+default parameters in a convention C procedure is dubious
+because the C compiler cannot supply the proper default, so
+a warning is issued. The default is that such warnings are
+generated.
+
+@item -gnatwX
+@emph{Suppress warnings on Export/Import pragmas.}
+@cindex @option{-gnatwX} (@code{gcc})
+This switch suppresses warnings on Export/Import pragmas.
+The sense of this is that you are telling the compiler that
+you know what you are doing in writing the pragma, and it
+should not complain at you.
+
+@item -gnatwz
+@emph{Activate warnings on unchecked conversions.}
+@cindex @option{-gnatwz} (@code{gcc})
+@cindex Unchecked_Conversion warnings
+This switch activates warnings for unchecked conversions
+where the types are known at compile time to have different
+sizes. The default
+is that such warnings are generated.
+
+@item -gnatwZ
+@emph{Suppress warnings on unchecked conversions.}
+@cindex @option{-gnatwZ} (@code{gcc})
+This switch suppresses warnings for unchecked conversions
+where the types are known at compile time to have different
+sizes.
+
+@item ^-Wuninitialized^WARNINGS=UNINITIALIZED^
+@cindex @option{-Wuninitialized}
+The warnings controlled by the @option{-gnatw} switch are generated by the
+front end of the compiler. In some cases, the @option{^gcc^GCC^} back end
+can provide additional warnings. One such useful warning is provided by
+@option{^-Wuninitialized^WARNINGS=UNINITIALIZED^}. This must be used in
+conjunction with tunrning on optimization mode. This causes the flow
+analysis circuits of the back end optimizer to output additional
+warnings about uninitialized variables.
+
+@item ^-w^/NO_BACK_END_WARNINGS^
+@cindex @option{-w}
+This switch suppresses warnings from the @option{^gcc^GCC^} back end. It may
+be used in conjunction with @option{-gnatws} to ensure that all warnings
+are suppressed during the entire compilation process.
+
+@end table
+
+@noindent
+@ifclear vms
+A string of warning parameters can be used in the same parameter. For example:
+
+@smallexample
+-gnatwaLe
+@end smallexample
+
+@noindent
+will turn on all optional warnings except for elaboration pragma warnings,
+and also specify that warnings should be treated as errors.
+@end ifclear
+When no switch @option{^-gnatw^/WARNINGS^} is used, this is equivalent to:
+
+@table @option
+@c !sort!
+@item -gnatwC
+@item -gnatwD
+@item -gnatwF
+@item -gnatwg
+@item -gnatwH
+@item -gnatwi
+@item -gnatwJ
+@item -gnatwK
+@item -gnatwL
+@item -gnatwM
+@item -gnatwn
+@item -gnatwo
+@item -gnatwP
+@item -gnatwR
+@item -gnatwU
+@item -gnatwv
+@item -gnatwz
+@item -gnatwx
+
+@end table
+
+
+@node Debugging and Assertion Control
+@subsection Debugging and Assertion Control
+
+@table @option
+@item -gnata
+@cindex @option{-gnata} (@code{gcc})
+@findex Assert
+@findex Debug
+@cindex Assertions
+
+@noindent
+The pragmas @code{Assert} and @code{Debug} normally have no effect and
+are ignored. This switch, where @samp{a} stands for assert, causes
+@code{Assert} and @code{Debug} pragmas to be activated.
+
+The pragmas have the form:
+
+@smallexample
+@cartouche
+ @b{pragma} Assert (@var{Boolean-expression} [,
+ @var{static-string-expression}])
+ @b{pragma} Debug (@var{procedure call})
+@end cartouche
+@end smallexample
+
+@noindent
+The @code{Assert} pragma causes @var{Boolean-expression} to be tested.
+If the result is @code{True}, the pragma has no effect (other than
+possible side effects from evaluating the expression). If the result is
+@code{False}, the exception @code{Assert_Failure} declared in the package
+@code{System.Assertions} is
+raised (passing @var{static-string-expression}, if present, as the
+message associated with the exception). If no string expression is
+given the default is a string giving the file name and line number
+of the pragma.
+
+The @code{Debug} pragma causes @var{procedure} to be called. Note that
+@code{pragma Debug} may appear within a declaration sequence, allowing
+debugging procedures to be called between declarations.
+
+@ifset vms
+@item /DEBUG[=debug-level]
+@itemx /NODEBUG
+Specifies how much debugging information is to be included in
+the resulting object file where 'debug-level' is one of the following:
+@table @code
+@item TRACEBACK
+Include both debugger symbol records and traceback
+the object file.
+This is the default setting.
+@item ALL
+Include both debugger symbol records and traceback in
+object file.
+@item NONE
+Excludes both debugger symbol records and traceback
+the object file. Same as /NODEBUG.
+@item SYMBOLS
+Includes only debugger symbol records in the object
+file. Note that this doesn't include traceback information.
+@end table
+@end ifset
+@end table
+
+@node Validity Checking
+@subsection Validity Checking
+@findex Validity Checking
+
+@noindent
+The Ada 95 Reference Manual has specific requirements for checking
+for invalid values. In particular, RM 13.9.1 requires that the
+evaluation of invalid values (for example from unchecked conversions),
+not result in erroneous execution. In GNAT, the result of such an
+evaluation in normal default mode is to either use the value
+unmodified, or to raise Constraint_Error in those cases where use
+of the unmodified value would cause erroneous execution. The cases
+where unmodified values might lead to erroneous execution are case
+statements (where a wild jump might result from an invalid value),
+and subscripts on the left hand side (where memory corruption could
+occur as a result of an invalid value).
+
+The @option{-gnatV^@var{x}^^} switch allows more control over the validity
+checking mode.
+@ifclear vms
+The @code{x} argument is a string of letters that
+indicate validity checks that are performed or not performed in addition
+to the default checks described above.
+@end ifclear
+@ifset vms
+The options allowed for this qualifier
+indicate validity checks that are performed or not performed in addition
+to the default checks described above.
+@end ifset
+
+
+@table @option
+@c !sort!
+@item -gnatVa
+@emph{All validity checks.}
+@cindex @option{-gnatVa} (@code{gcc})
+All validity checks are turned on.
+@ifclear vms
+That is, @option{-gnatVa} is
+equivalent to @option{gnatVcdfimorst}.
+@end ifclear
+
+@item -gnatVc
+@emph{Validity checks for copies.}
+@cindex @option{-gnatVc} (@code{gcc})
+The right hand side of assignments, and the initializing values of
+object declarations are validity checked.
+
+@item -gnatVd
+@emph{Default (RM) validity checks.}
+@cindex @option{-gnatVd} (@code{gcc})
+Some validity checks are done by default following normal Ada semantics
+(RM 13.9.1 (9-11)).
+A check is done in case statements that the expression is within the range
+of the subtype. If it is not, Constraint_Error is raised.
+For assignments to array components, a check is done that the expression used
+as index is within the range. If it is not, Constraint_Error is raised.
+Both these validity checks may be turned off using switch @option{-gnatVD}.
+They are turned on by default. If @option{-gnatVD} is specified, a subsequent
+switch @option{-gnatVd} will leave the checks turned on.
+Switch @option{-gnatVD} should be used only if you are sure that all such
+expressions have valid values. If you use this switch and invalid values
+are present, then the program is erroneous, and wild jumps or memory
+overwriting may occur.
+
+@item -gnatVf
+@emph{Validity checks for floating-point values.}
+@cindex @option{-gnatVf} (@code{gcc})
+In the absence of this switch, validity checking occurs only for discrete
+values. If @option{-gnatVf} is specified, then validity checking also applies
+for floating-point values, and NaN's and infinities are considered invalid,
+as well as out of range values for constrained types. Note that this means
+that standard @code{IEEE} infinity mode is not allowed. The exact contexts
+in which floating-point values are checked depends on the setting of other
+options. For example,
+@option{^-gnatVif^VALIDITY_CHECKING=(IN_PARAMS,FLOATS)^} or
+@option{^-gnatVfi^VALIDITY_CHECKING=(FLOATS,IN_PARAMS)^}
+(the order does not matter) specifies that floating-point parameters of mode
+@code{in} should be validity checked.
+
+@item -gnatVi
+@emph{Validity checks for @code{in} mode parameters}
+@cindex @option{-gnatVi} (@code{gcc})
+Arguments for parameters of mode @code{in} are validity checked in function
+and procedure calls at the point of call.
+
+@item -gnatVm
+@emph{Validity checks for @code{in out} mode parameters.}
+@cindex @option{-gnatVm} (@code{gcc})
+Arguments for parameters of mode @code{in out} are validity checked in
+procedure calls at the point of call. The @code{'m'} here stands for
+modify, since this concerns parameters that can be modified by the call.
+Note that there is no specific option to test @code{out} parameters,
+but any reference within the subprogram will be tested in the usual
+manner, and if an invalid value is copied back, any reference to it
+will be subject to validity checking.
+
+@item -gnatVn
+@emph{No validity checks.}
+@cindex @option{-gnatVn} (@code{gcc})
+This switch turns off all validity checking, including the default checking
+for case statements and left hand side subscripts. Note that the use of
+the switch @option{-gnatp} suppresses all run-time checks, including
+validity checks, and thus implies @option{-gnatVn}. When this switch
+is used, it cancels any other @option{-gnatV} previously issued.
+
+@item -gnatVo
+@emph{Validity checks for operator and attribute operands.}
+@cindex @option{-gnatVo} (@code{gcc})
+Arguments for predefined operators and attributes are validity checked.
+This includes all operators in package @code{Standard},
+the shift operators defined as intrinsic in package @code{Interfaces}
+and operands for attributes such as @code{Pos}. Checks are also made
+on individual component values for composite comparisons.
+
+@item -gnatVp
+@emph{Validity checks for parameters.}
+@cindex @option{-gnatVp} (@code{gcc})
+This controls the treatment of parameters within a subprogram (as opposed
+to @option{-gnatVi} and @option{-gnatVm} which control validity testing
+of parameters on a call. If either of these call options is used, then
+normally an assumption is made within a subprogram that the input arguments
+have been validity checking at the point of call, and do not need checking
+again within a subprogram). If @option{-gnatVp} is set, then this assumption
+is not made, and parameters are not assumed to be valid, so their validity
+will be checked (or rechecked) within the subprogram.
+
+@item -gnatVr
+@emph{Validity checks for function returns.}
+@cindex @option{-gnatVr} (@code{gcc})
+The expression in @code{return} statements in functions is validity
+checked.
+
+@item -gnatVs
+@emph{Validity checks for subscripts.}
+@cindex @option{-gnatVs} (@code{gcc})
+All subscripts expressions are checked for validity, whether they appear
+on the right side or left side (in default mode only left side subscripts
+are validity checked).
+
+@item -gnatVt
+@emph{Validity checks for tests.}
+@cindex @option{-gnatVt} (@code{gcc})
+Expressions used as conditions in @code{if}, @code{while} or @code{exit}
+statements are checked, as well as guard expressions in entry calls.
+
+@end table
+
+@noindent
+The @option{-gnatV} switch may be followed by
+^a string of letters^a list of options^
+to turn on a series of validity checking options.
+For example,
+@option{^-gnatVcr^/VALIDITY_CHECKING=(COPIES, RETURNS)^}
+specifies that in addition to the default validity checking, copies and
+function return expressions are to be validity checked.
+In order to make it easier
+to specify the desired combination of effects,
+@ifclear vms
+the upper case letters @code{CDFIMORST} may
+be used to turn off the corresponding lower case option.
+@end ifclear
+@ifset vms
+the prefix @code{NO} on an option turns off the corresponding validity
+checking:
+@itemize @bullet
+@item @code{NOCOPIES}
+@item @code{NODEFAULT}
+@item @code{NOFLOATS}
+@item @code{NOIN_PARAMS}
+@item @code{NOMOD_PARAMS}
+@item @code{NOOPERANDS}
+@item @code{NORETURNS}
+@item @code{NOSUBSCRIPTS}
+@item @code{NOTESTS}
+@end itemize
+@end ifset
+Thus
+@option{^-gnatVaM^/VALIDITY_CHECKING=(ALL, NOMOD_PARAMS)^}
+turns on all validity checking options except for
+checking of @code{@b{in out}} procedure arguments.
+
+The specification of additional validity checking generates extra code (and
+in the case of @option{-gnatVa} the code expansion can be substantial.
+However, these additional checks can be very useful in detecting
+uninitialized variables, incorrect use of unchecked conversion, and other
+errors leading to invalid values. The use of pragma @code{Initialize_Scalars}
+is useful in conjunction with the extra validity checking, since this
+ensures that wherever possible uninitialized variables have invalid values.
+
+See also the pragma @code{Validity_Checks} which allows modification of
+the validity checking mode at the program source level, and also allows for
+temporary disabling of validity checks.
+
+
+@node Style Checking
+@subsection Style Checking
+@findex Style checking
+
+@noindent
+The @option{-gnaty^x^(option,option,...)^} switch
+@cindex @option{-gnaty} (@code{gcc})
+causes the compiler to
+enforce specified style rules. A limited set of style rules has been used
+in writing the GNAT sources themselves. This switch allows user programs
+to activate all or some of these checks. If the source program fails a
+specified style check, an appropriate warning message is given, preceded by
+the character sequence ``(style)''.
+@ifset vms
+@code{(option,option,...)} is a sequence of keywords
+@end ifset
+@ifclear vms
+The string @var{x} is a sequence of letters or digits
+@end ifclear
+indicating the particular style
+checks to be performed. The following checks are defined:
+
+@table @option
+@c !sort!
+@item 1-9
+@emph{Specify indentation level.}
+If a digit from 1-9 appears
+^in the string after @option{-gnaty}^as an option for /STYLE_CHECKS^
+then proper indentation is checked, with the digit indicating the
+indentation level required.
+The general style of required indentation is as specified by
+the examples in the Ada Reference Manual. Full line comments must be
+aligned with the @code{--} starting on a column that is a multiple of
+the alignment level.
+
+@item ^a^ATTRIBUTE^
+@emph{Check attribute casing.}
+If the ^letter a^word ATTRIBUTE^ appears in the string after @option{-gnaty}
+then attribute names, including the case of keywords such as @code{digits}
+used as attributes names, must be written in mixed case, that is, the
+initial letter and any letter following an underscore must be uppercase.
+All other letters must be lowercase.
+
+@item ^b^BLANKS^
+@emph{Blanks not allowed at statement end.}
+If the ^letter b^word BLANKS^ appears in the string after @option{-gnaty} then
+trailing blanks are not allowed at the end of statements. The purpose of this
+rule, together with h (no horizontal tabs), is to enforce a canonical format
+for the use of blanks to separate source tokens.
+
+@item ^c^COMMENTS^
+@emph{Check comments.}
+If the ^letter c^word COMMENTS^ appears in the string after @option{-gnaty}
+then comments must meet the following set of rules:
+
+@itemize @bullet
+
+@item
+The ``@code{--}'' that starts the column must either start in column one,
+or else at least one blank must precede this sequence.
+
+@item
+Comments that follow other tokens on a line must have at least one blank
+following the ``@code{--}'' at the start of the comment.
+
+@item
+Full line comments must have two blanks following the ``@code{--}'' that
+starts the comment, with the following exceptions.
+
+@item
+A line consisting only of the ``@code{--}'' characters, possibly preceded
+by blanks is permitted.
+
+@item
+A comment starting with ``@code{--x}'' where @code{x} is a special character
+is permitted.
+This allows proper processing of the output generated by specialized tools
+including @command{gnatprep} (where ``@code{--!}'' is used) and the SPARK
+annotation
+language (where ``@code{--#}'' is used). For the purposes of this rule, a
+special character is defined as being in one of the ASCII ranges
+@code{16#21#..16#2F#} or @code{16#3A#..16#3F#}.
+Note that this usage is not permitted
+in GNAT implementation units (i.e. when @option{-gnatg} is used).
+
+@item
+A line consisting entirely of minus signs, possibly preceded by blanks, is
+permitted. This allows the construction of box comments where lines of minus
+signs are used to form the top and bottom of the box.
+
+@item
+If a comment starts and ends with ``@code{--}'' is permitted as long as at
+least one blank follows the initial ``@code{--}''. Together with the preceding
+rule, this allows the construction of box comments, as shown in the following
+example:
+@smallexample
+---------------------------
+-- This is a box comment --
+-- with two text lines. --
+---------------------------
+@end smallexample
+@end itemize
+
+@item ^e^END^
+@emph{Check end/exit labels.}
+If the ^letter e^word END^ appears in the string after @option{-gnaty} then
+optional labels on @code{end} statements ending subprograms and on
+@code{exit} statements exiting named loops, are required to be present.
+
+@item ^f^VTABS^
+@emph{No form feeds or vertical tabs.}
+If the ^letter f^word VTABS^ appears in the string after @option{-gnaty} then
+neither form feeds nor vertical tab characters are not permitted
+in the source text.
+
+@item ^h^HTABS^
+@emph{No horizontal tabs.}
+If the ^letter h^word HTABS^ appears in the string after @option{-gnaty} then
+horizontal tab characters are not permitted in the source text.
+Together with the b (no blanks at end of line) check, this
+enforces a canonical form for the use of blanks to separate
+source tokens.
+
+@item ^i^IF_THEN^
+@emph{Check if-then layout.}
+If the ^letter i^word IF_THEN^ appears in the string after @option{-gnaty},
+then the keyword @code{then} must appear either on the same
+line as corresponding @code{if}, or on a line on its own, lined
+up under the @code{if} with at least one non-blank line in between
+containing all or part of the condition to be tested.
+
+@item ^k^KEYWORD^
+@emph{Check keyword casing.}
+If the ^letter k^word KEYWORD^ appears in the string after @option{-gnaty} then
+all keywords must be in lower case (with the exception of keywords
+such as @code{digits} used as attribute names to which this check
+does not apply).
+
+@item ^l^LAYOUT^
+@emph{Check layout.}
+If the ^letter l^word LAYOUT^ appears in the string after @option{-gnaty} then
+layout of statement and declaration constructs must follow the
+recommendations in the Ada Reference Manual, as indicated by the
+form of the syntax rules. For example an @code{else} keyword must
+be lined up with the corresponding @code{if} keyword.
+
+There are two respects in which the style rule enforced by this check
+option are more liberal than those in the Ada Reference Manual. First
+in the case of record declarations, it is permissible to put the
+@code{record} keyword on the same line as the @code{type} keyword, and
+then the @code{end} in @code{end record} must line up under @code{type}.
+For example, either of the following two layouts is acceptable:
+
+@smallexample @c ada
+@cartouche
+type q is record
+ a : integer;
+ b : integer;
+end record;
+
+type q is
+ record
+ a : integer;
+ b : integer;
+ end record;
+@end cartouche
+@end smallexample
+
+@noindent
+Second, in the case of a block statement, a permitted alternative
+is to put the block label on the same line as the @code{declare} or
+@code{begin} keyword, and then line the @code{end} keyword up under
+the block label. For example both the following are permitted:
+
+@smallexample @c ada
+@cartouche
+Block : declare
+ A : Integer := 3;
+begin
+ Proc (A, A);
+end Block;
+
+Block :
+ declare
+ A : Integer := 3;
+ begin
+ Proc (A, A);
+ end Block;
+@end cartouche
+@end smallexample
+
+@noindent
+The same alternative format is allowed for loops. For example, both of
+the following are permitted:
+
+@smallexample @c ada
+@cartouche
+Clear : while J < 10 loop
+ A (J) := 0;
+end loop Clear;
+
+Clear :
+ while J < 10 loop
+ A (J) := 0;
+ end loop Clear;
+@end cartouche
+@end smallexample
+
+@item ^Lnnn^MAX_NESTING=nnn^
+@emph{Set maximum nesting level}
+If the sequence ^Lnnn^MAX_NESTING=nnn^, where nnn is a decimal number in
+the range 0-999, appears in the string after @option{-gnaty} then the
+maximum level of nesting of constructs (including subprograms, loops,
+blocks, packages, and conditionals) may not exceed the given value. A
+value of zero disconnects this style check.
+
+@item ^m^LINE_LENGTH^
+@emph{Check maximum line length.}
+If the ^letter m^word LINE_LENGTH^ appears in the string after @option{-gnaty}
+then the length of source lines must not exceed 79 characters, including
+any trailing blanks. The value of 79 allows convenient display on an
+80 character wide device or window, allowing for possible special
+treatment of 80 character lines. Note that this count is of raw
+characters in the source text. This means that a tab character counts
+as one character in this count and a wide character sequence counts as
+several characters (however many are needed in the encoding).
+
+@item ^Mnnn^MAX_LENGTH=nnn^
+@emph{Set maximum line length.}
+If the sequence ^M^MAX_LENGTH=^nnn, where nnn is a decimal number, appears in
+the string after @option{-gnaty} then the length of lines must not exceed the
+given value.
+
+@item ^n^STANDARD_CASING^
+@emph{Check casing of entities in Standard.}
+If the ^letter n^word STANDARD_CASING^ appears in the string
+after @option{-gnaty} then any identifier from Standard must be cased
+to match the presentation in the Ada Reference Manual (for example,
+@code{Integer} and @code{ASCII.NUL}).
+
+@item ^o^ORDERED_SUBPROGRAMS^
+@emph{Check order of subprogram bodies.}
+If the ^letter o^word ORDERED_SUBPROGRAMS^ appears in the string
+after @option{-gnaty} then all subprogram bodies in a given scope
+(e.g. a package body) must be in alphabetical order. The ordering
+rule uses normal Ada rules for comparing strings, ignoring casing
+of letters, except that if there is a trailing numeric suffix, then
+the value of this suffix is used in the ordering (e.g. Junk2 comes
+before Junk10).
+
+@item ^p^PRAGMA^
+@emph{Check pragma casing.}
+If the ^letter p^word PRAGMA^ appears in the string after @option{-gnaty} then
+pragma names must be written in mixed case, that is, the
+initial letter and any letter following an underscore must be uppercase.
+All other letters must be lowercase.
+
+@item ^r^REFERENCES^
+@emph{Check references.}
+If the ^letter r^word REFERENCES^ appears in the string after @option{-gnaty}
+then all identifier references must be cased in the same way as the
+corresponding declaration. No specific casing style is imposed on
+identifiers. The only requirement is for consistency of references
+with declarations.
+
+@item ^s^SPECS^
+@emph{Check separate specs.}
+If the ^letter s^word SPECS^ appears in the string after @option{-gnaty} then
+separate declarations (``specs'') are required for subprograms (a
+body is not allowed to serve as its own declaration). The only
+exception is that parameterless library level procedures are
+not required to have a separate declaration. This exception covers
+the most frequent form of main program procedures.
+
+@item ^t^TOKEN^
+@emph{Check token spacing.}
+If the ^letter t^word TOKEN^ appears in the string after @option{-gnaty} then
+the following token spacing rules are enforced:
+
+@itemize @bullet
+
+@item
+The keywords @code{@b{abs}} and @code{@b{not}} must be followed by a space.
+
+@item
+The token @code{=>} must be surrounded by spaces.
+
+@item
+The token @code{<>} must be preceded by a space or a left parenthesis.
+
+@item
+Binary operators other than @code{**} must be surrounded by spaces.
+There is no restriction on the layout of the @code{**} binary operator.
+
+@item
+Colon must be surrounded by spaces.
+
+@item
+Colon-equal (assignment, initialization) must be surrounded by spaces.
+
+@item
+Comma must be the first non-blank character on the line, or be
+immediately preceded by a non-blank character, and must be followed
+by a space.
+
+@item
+If the token preceding a left parenthesis ends with a letter or digit, then
+a space must separate the two tokens.
+
+@item
+A right parenthesis must either be the first non-blank character on
+a line, or it must be preceded by a non-blank character.
+
+@item
+A semicolon must not be preceded by a space, and must not be followed by
+a non-blank character.
+
+@item
+A unary plus or minus may not be followed by a space.
+
+@item
+A vertical bar must be surrounded by spaces.
+@end itemize
+
+@noindent
+In the above rules, appearing in column one is always permitted, that is,
+counts as meeting either a requirement for a required preceding space,
+or as meeting a requirement for no preceding space.
+
+Appearing at the end of a line is also always permitted, that is, counts
+as meeting either a requirement for a following space, or as meeting
+a requirement for no following space.
+
+@end table
+
+@noindent
+If any of these style rules is violated, a message is generated giving
+details on the violation. The initial characters of such messages are
+always ``@code{(style)}''. Note that these messages are treated as warning
+messages, so they normally do not prevent the generation of an object
+file. The @option{-gnatwe} switch can be used to treat warning messages,
+including style messages, as fatal errors.
+
+The switch
+@ifclear vms
+@option{-gnaty} on its own (that is not
+followed by any letters or digits),
+is equivalent to @code{gnaty3abcefhiklmprst}, that is all checking
+options enabled with the exception of -gnatyo,
+@end ifclear
+@ifset vms
+/STYLE_CHECKS=ALL_BUILTIN enables all checking options with
+the exception of ORDERED_SUBPROGRAMS,
+@end ifset
+with an indentation level of 3. This is the standard
+checking option that is used for the GNAT sources.
+
+The switch
+@ifclear vms
+@option{-gnatyN}
+@end ifclear
+@ifset vms
+/STYLE_CHECKS=NONE
+@end ifset
+clears any previously set style checks.
+
+@node Run-Time Checks
+@subsection Run-Time Checks
+@cindex Division by zero
+@cindex Access before elaboration
+@cindex Checks, division by zero
+@cindex Checks, access before elaboration
+
+@noindent
+If you compile with the default options, GNAT will insert many run-time
+checks into the compiled code, including code that performs range
+checking against constraints, but not arithmetic overflow checking for
+integer operations (including division by zero) or checks for access
+before elaboration on subprogram calls. All other run-time checks, as
+required by the Ada 95 Reference Manual, are generated by default.
+The following @code{gcc} switches refine this default behavior:
+
+@table @option
+@c !sort!
+@item -gnatp
+@cindex @option{-gnatp} (@code{gcc})
+@cindex Suppressing checks
+@cindex Checks, suppressing
+@findex Suppress
+Suppress all run-time checks as though @code{pragma Suppress (all_checks})
+had been present in the source. Validity checks are also suppressed (in
+other words @option{-gnatp} also implies @option{-gnatVn}.
+Use this switch to improve the performance
+of the code at the expense of safety in the presence of invalid data or
+program bugs.
+
+@item -gnato
+@cindex @option{-gnato} (@code{gcc})
+@cindex Overflow checks
+@cindex Check, overflow
+Enables overflow checking for integer operations.
+This causes GNAT to generate slower and larger executable
+programs by adding code to check for overflow (resulting in raising
+@code{Constraint_Error} as required by standard Ada
+semantics). These overflow checks correspond to situations in which
+the true value of the result of an operation may be outside the base
+range of the result type. The following example shows the distinction:
+
+@smallexample @c ada
+X1 : Integer := Integer'Last;
+X2 : Integer range 1 .. 5 := 5;
+X3 : Integer := Integer'Last;
+X4 : Integer range 1 .. 5 := 5;
+F : Float := 2.0E+20;
+...
+X1 := X1 + 1;
+X2 := X2 + 1;
+X3 := Integer (F);
+X4 := Integer (F);
+@end smallexample
+
+@noindent
+Here the first addition results in a value that is outside the base range
+of Integer, and hence requires an overflow check for detection of the
+constraint error. Thus the first assignment to @code{X1} raises a
+@code{Constraint_Error} exception only if @option{-gnato} is set.
+
+The second increment operation results in a violation
+of the explicit range constraint, and such range checks are always
+performed (unless specifically suppressed with a pragma @code{suppress}
+or the use of @option{-gnatp}).
+
+The two conversions of @code{F} both result in values that are outside
+the base range of type @code{Integer} and thus will raise
+@code{Constraint_Error} exceptions only if @option{-gnato} is used.
+The fact that the result of the second conversion is assigned to
+variable @code{X4} with a restricted range is irrelevant, since the problem
+is in the conversion, not the assignment.
+
+Basically the rule is that in the default mode (@option{-gnato} not
+used), the generated code assures that all integer variables stay
+within their declared ranges, or within the base range if there is
+no declared range. This prevents any serious problems like indexes
+out of range for array operations.
+
+What is not checked in default mode is an overflow that results in
+an in-range, but incorrect value. In the above example, the assignments
+to @code{X1}, @code{X2}, @code{X3} all give results that are within the
+range of the target variable, but the result is wrong in the sense that
+it is too large to be represented correctly. Typically the assignment
+to @code{X1} will result in wrap around to the largest negative number.
+The conversions of @code{F} will result in some @code{Integer} value
+and if that integer value is out of the @code{X4} range then the
+subsequent assignment would generate an exception.
+
+@findex Machine_Overflows
+Note that the @option{-gnato} switch does not affect the code generated
+for any floating-point operations; it applies only to integer
+semantics).
+For floating-point, GNAT has the @code{Machine_Overflows}
+attribute set to @code{False} and the normal mode of operation is to
+generate IEEE NaN and infinite values on overflow or invalid operations
+(such as dividing 0.0 by 0.0).
+
+The reason that we distinguish overflow checking from other kinds of
+range constraint checking is that a failure of an overflow check can
+generate an incorrect value, but cannot cause erroneous behavior. This
+is unlike the situation with a constraint check on an array subscript,
+where failure to perform the check can result in random memory description,
+or the range check on a case statement, where failure to perform the check
+can cause a wild jump.
+
+Note again that @option{-gnato} is off by default, so overflow checking is
+not performed in default mode. This means that out of the box, with the
+default settings, GNAT does not do all the checks expected from the
+language description in the Ada Reference Manual. If you want all constraint
+checks to be performed, as described in this Manual, then you must
+explicitly use the -gnato switch either on the @code{gnatmake} or
+@code{gcc} command.
+
+@item -gnatE
+@cindex @option{-gnatE} (@code{gcc})
+@cindex Elaboration checks
+@cindex Check, elaboration
+Enables dynamic checks for access-before-elaboration
+on subprogram calls and generic instantiations.
+For full details of the effect and use of this switch,
+@xref{Compiling Using gcc}.
+@end table
+
+@findex Unsuppress
+@noindent
+The setting of these switches only controls the default setting of the
+checks. You may modify them using either @code{Suppress} (to remove
+checks) or @code{Unsuppress} (to add back suppressed checks) pragmas in
+the program source.
+
+@node Stack Overflow Checking
+@subsection Stack Overflow Checking
+@cindex Stack Overflow Checking
+@cindex -fstack-check
+
+@noindent
+For most operating systems, @code{gcc} does not perform stack overflow
+checking by default. This means that if the main environment task or
+some other task exceeds the available stack space, then unpredictable
+behavior will occur.
+
+To activate stack checking, compile all units with the gcc option
+@option{-fstack-check}. For example:
+
+@smallexample
+gcc -c -fstack-check package1.adb
+@end smallexample
+
+@noindent
+Units compiled with this option will generate extra instructions to check
+that any use of the stack (for procedure calls or for declaring local
+variables in declare blocks) do not exceed the available stack space.
+If the space is exceeded, then a @code{Storage_Error} exception is raised.
+
+For declared tasks, the stack size is always controlled by the size
+given in an applicable @code{Storage_Size} pragma (or is set to
+the default size if no pragma is used.
+
+For the environment task, the stack size depends on
+system defaults and is unknown to the compiler. The stack
+may even dynamically grow on some systems, precluding the
+normal Ada semantics for stack overflow. In the worst case,
+unbounded stack usage, causes unbounded stack expansion
+resulting in the system running out of virtual memory.
+
+The stack checking may still work correctly if a fixed
+size stack is allocated, but this cannot be guaranteed.
+To ensure that a clean exception is signalled for stack
+overflow, set the environment variable
+@code{GNAT_STACK_LIMIT} to indicate the maximum
+stack area that can be used, as in:
+@cindex GNAT_STACK_LIMIT
+
+@smallexample
+SET GNAT_STACK_LIMIT 1600
+@end smallexample
+
+@noindent
+The limit is given in kilobytes, so the above declaration would
+set the stack limit of the environment task to 1.6 megabytes.
+Note that the only purpose of this usage is to limit the amount
+of stack used by the environment task. If it is necessary to
+increase the amount of stack for the environment task, then this
+is an operating systems issue, and must be addressed with the
+appropriate operating systems commands.
+
+
+@node Using gcc for Syntax Checking
+@subsection Using @code{gcc} for Syntax Checking
+@table @option
+@item -gnats
+@cindex @option{-gnats} (@code{gcc})
+@ifclear vms
+
+@noindent
+The @code{s} stands for ``syntax''.
+@end ifclear
+
+Run GNAT in syntax checking only mode. For
+example, the command
+
+@smallexample
+$ gcc -c -gnats x.adb
+@end smallexample
+
+@noindent
+compiles file @file{x.adb} in syntax-check-only mode. You can check a
+series of files in a single command
+@ifclear vms
+, and can use wild cards to specify such a group of files.
+Note that you must specify the @option{-c} (compile
+only) flag in addition to the @option{-gnats} flag.
+@end ifclear
+.
+You may use other switches in conjunction with @option{-gnats}. In
+particular, @option{-gnatl} and @option{-gnatv} are useful to control the
+format of any generated error messages.
+
+When the source file is empty or contains only empty lines and/or comments,
+the output is a warning:
+
+@smallexample
+$ gcc -c -gnats -x ada toto.txt
+toto.txt:1:01: warning: empty file, contains no compilation units
+$
+@end smallexample
+
+Otherwise, the output is simply the error messages, if any. No object file or
+ALI file is generated by a syntax-only compilation. Also, no units other
+than the one specified are accessed. For example, if a unit @code{X}
+@code{with}'s a unit @code{Y}, compiling unit @code{X} in syntax
+check only mode does not access the source file containing unit
+@code{Y}.
+
+@cindex Multiple units, syntax checking
+Normally, GNAT allows only a single unit in a source file. However, this
+restriction does not apply in syntax-check-only mode, and it is possible
+to check a file containing multiple compilation units concatenated
+together. This is primarily used by the @code{gnatchop} utility
+(@pxref{Renaming Files Using gnatchop}).
+@end table
+
+
+@node Using gcc for Semantic Checking
+@subsection Using @code{gcc} for Semantic Checking
+@table @option
+@item -gnatc
+@cindex @option{-gnatc} (@code{gcc})
+
+@ifclear vms
+@noindent
+The @code{c} stands for ``check''.
+@end ifclear
+Causes the compiler to operate in semantic check mode,
+with full checking for all illegalities specified in the
+Ada 95 Reference Manual, but without generation of any object code
+(no object file is generated).
+
+Because dependent files must be accessed, you must follow the GNAT
+semantic restrictions on file structuring to operate in this mode:
+
+@itemize @bullet
+@item
+The needed source files must be accessible
+(@pxref{Search Paths and the Run-Time Library (RTL)}).
+
+@item
+Each file must contain only one compilation unit.
+
+@item
+The file name and unit name must match (@pxref{File Naming Rules}).
+@end itemize
+
+The output consists of error messages as appropriate. No object file is
+generated. An @file{ALI} file is generated for use in the context of
+cross-reference tools, but this file is marked as not being suitable
+for binding (since no object file is generated).
+The checking corresponds exactly to the notion of
+legality in the Ada 95 Reference Manual.
+
+Any unit can be compiled in semantics-checking-only mode, including
+units that would not normally be compiled (subunits,
+and specifications where a separate body is present).
+@end table
+
+@node Compiling Ada 83 Programs
+@subsection Compiling Ada 83 Programs
+@table @option
+@cindex Ada 83 compatibility
+@item -gnat83
+@cindex @option{-gnat83} (@code{gcc})
+@cindex ACVC, Ada 83 tests
+
+@noindent
+Although GNAT is primarily an Ada 95 compiler, it accepts this switch to
+specify that an Ada 83 program is to be compiled in Ada 83 mode. If you specify
+this switch, GNAT rejects most Ada 95 extensions and applies Ada 83 semantics
+where this can be done easily.
+It is not possible to guarantee this switch does a perfect
+job; for example, some subtle tests, such as are
+found in earlier ACVC tests (and that have been removed from the ACATS suite
+for Ada 95), might not compile correctly.
+Nevertheless, this switch may be useful in some circumstances, for example
+where, due to contractual reasons, legacy code needs to be maintained
+using only Ada 83 features.
+
+With few exceptions (most notably the need to use @code{<>} on
+@cindex Generic formal parameters
+unconstrained generic formal parameters, the use of the new Ada 95
+reserved words, and the use of packages
+with optional bodies), it is not necessary to use the
+@option{-gnat83} switch when compiling Ada 83 programs, because, with rare
+exceptions, Ada 95 is upwardly compatible with Ada 83. This
+means that a correct Ada 83 program is usually also a correct Ada 95
+program.
+For further information, please refer to @ref{Compatibility and Porting Guide}.
+
+@end table
+
+@node Character Set Control
+@subsection Character Set Control
+@table @option
+@item ^-gnati^/IDENTIFIER_CHARACTER_SET=^@var{c}
+@cindex @option{^-gnati^/IDENTIFIER_CHARACTER_SET^} (@code{gcc})
+
+@noindent
+Normally GNAT recognizes the Latin-1 character set in source program
+identifiers, as described in the Ada 95 Reference Manual.
+This switch causes
+GNAT to recognize alternate character sets in identifiers. @var{c} is a
+single character ^^or word^ indicating the character set, as follows:
+
+@table @code
+@item 1
+ISO 8859-1 (Latin-1) identifiers
+
+@item 2
+ISO 8859-2 (Latin-2) letters allowed in identifiers
+
+@item 3
+ISO 8859-3 (Latin-3) letters allowed in identifiers
+
+@item 4
+ISO 8859-4 (Latin-4) letters allowed in identifiers
+
+@item 5
+ISO 8859-5 (Cyrillic) letters allowed in identifiers
+
+@item 9
+ISO 8859-15 (Latin-9) letters allowed in identifiers
+
+@item ^p^PC^
+IBM PC letters (code page 437) allowed in identifiers
+
+@item ^8^PC850^
+IBM PC letters (code page 850) allowed in identifiers
+
+@item ^f^FULL_UPPER^
+Full upper-half codes allowed in identifiers
+
+@item ^n^NO_UPPER^
+No upper-half codes allowed in identifiers
+
+@item ^w^WIDE^
+Wide-character codes (that is, codes greater than 255)
+allowed in identifiers
+@end table
+
+@xref{Foreign Language Representation}, for full details on the
+implementation of these character sets.
+
+@item ^-gnatW^/WIDE_CHARACTER_ENCODING=^@var{e}
+@cindex @option{^-gnatW^/WIDE_CHARACTER_ENCODING^} (@code{gcc})
+Specify the method of encoding for wide characters.
+@var{e} is one of the following:
+
+@table @code
+
+@item ^h^HEX^
+Hex encoding (brackets coding also recognized)
+
+@item ^u^UPPER^
+Upper half encoding (brackets encoding also recognized)
+
+@item ^s^SHIFT_JIS^
+Shift/JIS encoding (brackets encoding also recognized)
+
+@item ^e^EUC^
+EUC encoding (brackets encoding also recognized)
+
+@item ^8^UTF8^
+UTF-8 encoding (brackets encoding also recognized)
+
+@item ^b^BRACKETS^
+Brackets encoding only (default value)
+@end table
+For full details on the these encoding
+methods see @xref{Wide Character Encodings}.
+Note that brackets coding is always accepted, even if one of the other
+options is specified, so for example @option{-gnatW8} specifies that both
+brackets and @code{UTF-8} encodings will be recognized. The units that are
+with'ed directly or indirectly will be scanned using the specified
+representation scheme, and so if one of the non-brackets scheme is
+used, it must be used consistently throughout the program. However,
+since brackets encoding is always recognized, it may be conveniently
+used in standard libraries, allowing these libraries to be used with
+any of the available coding schemes.
+scheme. If no @option{-gnatW?} parameter is present, then the default
+representation is Brackets encoding only.
+
+Note that the wide character representation that is specified (explicitly
+or by default) for the main program also acts as the default encoding used
+for Wide_Text_IO files if not specifically overridden by a WCEM form
+parameter.
+
+@end table
+@node File Naming Control
+@subsection File Naming Control
+
+@table @option
+@item ^-gnatk^/FILE_NAME_MAX_LENGTH=^@var{n}
+@cindex @option{-gnatk} (@code{gcc})
+Activates file name ``krunching''. @var{n}, a decimal integer in the range
+1-999, indicates the maximum allowable length of a file name (not
+including the @file{.ads} or @file{.adb} extension). The default is not
+to enable file name krunching.
+
+For the source file naming rules, @xref{File Naming Rules}.
+@end table
+
+
+@node Subprogram Inlining Control
+@subsection Subprogram Inlining Control
+
+@table @option
+@c !sort!
+@item -gnatn
+@cindex @option{-gnatn} (@code{gcc})
+@ifclear vms
+The @code{n} here is intended to suggest the first syllable of the
+word ``inline''.
+@end ifclear
+GNAT recognizes and processes @code{Inline} pragmas. However, for the
+inlining to actually occur, optimization must be enabled. To enable
+inlining of subprograms specified by pragma @code{Inline},
+you must also specify this switch.
+In the absence of this switch, GNAT does not attempt
+inlining and does not need to access the bodies of
+subprograms for which @code{pragma Inline} is specified if they are not
+in the current unit.
+
+If you specify this switch the compiler will access these bodies,
+creating an extra source dependency for the resulting object file, and
+where possible, the call will be inlined.
+For further details on when inlining is possible
+see @xref{Inlining of Subprograms}.
+
+@item -gnatN
+@cindex @option{-gnatN} (@code{gcc})
+The front end inlining activated by this switch is generally more extensive,
+and quite often more effective than the standard @option{-gnatn} inlining mode.
+It will also generate additional dependencies.
+Note that
+@option{-gnatN} automatically implies @option{-gnatn} so it is not necessary
+to specify both options.
+@end table
+
+@node Auxiliary Output Control
+@subsection Auxiliary Output Control
+
+@table @option
+@item -gnatt
+@cindex @option{-gnatt} (@code{gcc})
+@cindex Writing internal trees
+@cindex Internal trees, writing to file
+Causes GNAT to write the internal tree for a unit to a file (with the
+extension @file{.adt}.
+This not normally required, but is used by separate analysis tools.
+Typically
+these tools do the necessary compilations automatically, so you should
+not have to specify this switch in normal operation.
+
+@item -gnatu
+@cindex @option{-gnatu} (@code{gcc})
+Print a list of units required by this compilation on @file{stdout}.
+The listing includes all units on which the unit being compiled depends
+either directly or indirectly.
+
+@ifclear vms
+@item -pass-exit-codes
+@cindex @option{-pass-exit-codes} (@code{gcc})
+If this switch is not used, the exit code returned by @code{gcc} when
+compiling multiple files indicates whether all source files have
+been successfully used to generate object files or not.
+
+When @option{-pass-exit-codes} is used, @code{gcc} exits with an extended
+exit status and allows an integrated development environment to better
+react to a compilation failure. Those exit status are:
+
+@table @asis
+@item 5
+There was an error in at least one source file.
+@item 3
+At least one source file did not generate an object file.
+@item 2
+The compiler died unexpectedly (internal error for example).
+@item 0
+An object file has been generated for every source file.
+@end table
+@end ifclear
+@end table
+
+@node Debugging Control
+@subsection Debugging Control
+
+@table @option
+@c !sort!
+@cindex Debugging options
+@ifclear vms
+@item -gnatd@var{x}
+@cindex @option{-gnatd} (@code{gcc})
+Activate internal debugging switches. @var{x} is a letter or digit, or
+string of letters or digits, which specifies the type of debugging
+outputs desired. Normally these are used only for internal development
+or system debugging purposes. You can find full documentation for these
+switches in the body of the @code{Debug} unit in the compiler source
+file @file{debug.adb}.
+@end ifclear
+
+@item -gnatG
+@cindex @option{-gnatG} (@code{gcc})
+This switch causes the compiler to generate auxiliary output containing
+a pseudo-source listing of the generated expanded code. Like most Ada
+compilers, GNAT works by first transforming the high level Ada code into
+lower level constructs. For example, tasking operations are transformed
+into calls to the tasking run-time routines. A unique capability of GNAT
+is to list this expanded code in a form very close to normal Ada source.
+This is very useful in understanding the implications of various Ada
+usage on the efficiency of the generated code. There are many cases in
+Ada (e.g. the use of controlled types), where simple Ada statements can
+generate a lot of run-time code. By using @option{-gnatG} you can identify
+these cases, and consider whether it may be desirable to modify the coding
+approach to improve efficiency.
+
+The format of the output is very similar to standard Ada source, and is
+easily understood by an Ada programmer. The following special syntactic
+additions correspond to low level features used in the generated code that
+do not have any exact analogies in pure Ada source form. The following
+is a partial list of these special constructions. See the specification
+of package @code{Sprint} in file @file{sprint.ads} for a full list.
+
+@table @code
+@item new @var{xxx} [storage_pool = @var{yyy}]
+Shows the storage pool being used for an allocator.
+
+@item at end @var{procedure-name};
+Shows the finalization (cleanup) procedure for a scope.
+
+@item (if @var{expr} then @var{expr} else @var{expr})
+Conditional expression equivalent to the @code{x?y:z} construction in C.
+
+@item @var{target}^^^(@var{source})
+A conversion with floating-point truncation instead of rounding.
+
+@item @var{target}?(@var{source})
+A conversion that bypasses normal Ada semantic checking. In particular
+enumeration types and fixed-point types are treated simply as integers.
+
+@item @var{target}?^^^(@var{source})
+Combines the above two cases.
+
+@item @var{x} #/ @var{y}
+@itemx @var{x} #mod @var{y}
+@itemx @var{x} #* @var{y}
+@itemx @var{x} #rem @var{y}
+A division or multiplication of fixed-point values which are treated as
+integers without any kind of scaling.
+
+@item free @var{expr} [storage_pool = @var{xxx}]
+Shows the storage pool associated with a @code{free} statement.
+
+@item freeze @var{typename} [@var{actions}]
+Shows the point at which @var{typename} is frozen, with possible
+associated actions to be performed at the freeze point.
+
+@item reference @var{itype}
+Reference (and hence definition) to internal type @var{itype}.
+
+@item @var{function-name}! (@var{arg}, @var{arg}, @var{arg})
+Intrinsic function call.
+
+@item @var{labelname} : label
+Declaration of label @var{labelname}.
+
+@item @var{expr} && @var{expr} && @var{expr} ... && @var{expr}
+A multiple concatenation (same effect as @var{expr} & @var{expr} &
+@var{expr}, but handled more efficiently).
+
+@item [constraint_error]
+Raise the @code{Constraint_Error} exception.
+
+@item @var{expression}'reference
+A pointer to the result of evaluating @var{expression}.
+
+@item @var{target-type}!(@var{source-expression})
+An unchecked conversion of @var{source-expression} to @var{target-type}.
+
+@item [@var{numerator}/@var{denominator}]
+Used to represent internal real literals (that) have no exact
+representation in base 2-16 (for example, the result of compile time
+evaluation of the expression 1.0/27.0).
+@end table
+
+@item -gnatD
+@cindex @option{-gnatD} (@code{gcc})
+When used in conjunction with @option{-gnatG}, this switch causes
+the expanded source, as described above for
+@option{-gnatG} to be written to files with names
+@file{^xxx.dg^XXX_DG^}, where @file{xxx} is the normal file name,
+instead of to the standard ooutput file. For
+example, if the source file name is @file{hello.adb}, then a file
+@file{^hello.adb.dg^HELLO.ADB_DG^} will be written. The debugging
+information generated by the @code{gcc} @option{^-g^/DEBUG^} switch
+will refer to the generated @file{^xxx.dg^XXX_DG^} file. This allows
+you to do source level debugging using the generated code which is
+sometimes useful for complex code, for example to find out exactly
+which part of a complex construction raised an exception. This switch
+also suppress generation of cross-reference information (see
+@option{-gnatx}) since otherwise the cross-reference information
+would refer to the @file{^.dg^.DG^} file, which would cause
+confusion since this is not the original source file.
+
+Note that @option{-gnatD} actually implies @option{-gnatG}
+automatically, so it is not necessary to give both options.
+In other words @option{-gnatD} is equivalent to @option{-gnatDG}).
+
+@ifclear vms
+@item -gnatR[0|1|2|3[s]]
+@cindex @option{-gnatR} (@code{gcc})
+This switch controls output from the compiler of a listing showing
+representation information for declared types and objects. For
+@option{-gnatR0}, no information is output (equivalent to omitting
+the @option{-gnatR} switch). For @option{-gnatR1} (which is the default,
+so @option{-gnatR} with no parameter has the same effect), size and alignment
+information is listed for declared array and record types. For
+@option{-gnatR2}, size and alignment information is listed for all
+expression information for values that are computed at run time for
+variant records. These symbolic expressions have a mostly obvious
+format with #n being used to represent the value of the n'th
+discriminant. See source files @file{repinfo.ads/adb} in the
+@code{GNAT} sources for full details on the format of @option{-gnatR3}
+output. If the switch is followed by an s (e.g. @option{-gnatR2s}), then
+the output is to a file with the name @file{^file.rep^file_REP^} where
+file is the name of the corresponding source file.
+@end ifclear
+@ifset vms
+@item /REPRESENTATION_INFO
+@cindex @option{/REPRESENTATION_INFO} (@code{gcc})
+This qualifier controls output from the compiler of a listing showing
+representation information for declared types and objects. For
+@option{/REPRESENTATION_INFO=NONE}, no information is output
+(equivalent to omitting the @option{/REPRESENTATION_INFO} qualifier).
+@option{/REPRESENTATION_INFO} without option is equivalent to
+@option{/REPRESENTATION_INFO=ARRAYS}.
+For @option{/REPRESENTATION_INFO=ARRAYS}, size and alignment
+information is listed for declared array and record types. For
+@option{/REPRESENTATION_INFO=OBJECTS}, size and alignment information
+is listed for all expression information for values that are computed
+at run time for variant records. These symbolic expressions have a mostly
+obvious format with #n being used to represent the value of the n'th
+discriminant. See source files @file{REPINFO.ADS/ADB} in the
+@code{GNAT} sources for full details on the format of
+@option{/REPRESENTATION_INFO=SYMBOLIC} output.
+If _FILE is added at the end of an option
+(e.g. @option{/REPRESENTATION_INFO=ARRAYS_FILE}),
+then the output is to a file with the name @file{file_REP} where
+file is the name of the corresponding source file.
+@end ifset
+
+@item -gnatS
+@cindex @option{-gnatS} (@code{gcc})
+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 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
+determine the characteristics of target dependent
+types in package Standard.
+
+@item -gnatx
+@cindex @option{-gnatx} (@code{gcc})
+Normally the compiler generates full cross-referencing information in
+the @file{ALI} file. This information is used by a number of tools,
+including @code{gnatfind} and @code{gnatxref}. The @option{-gnatx} switch
+suppresses this information. This saves some space and may slightly
+speed up compilation, but means that these tools cannot be used.
+@end table
+
+@node Exception Handling Control
+@subsection Exception Handling Control
+
+@noindent
+GNAT uses two methods for handling exceptions at run-time. The
+@code{longjmp/setjmp} method saves the context when entering
+a frame with an exception handler. Then when an exception is
+raised, the context can be restored immediately, without the
+need for tracing stack frames. This method provides very fast
+exception propagation, but introduces significant overhead for
+the use of exception handlers, even if no exception is raised.
+
+The other approach is called ``zero cost'' exception handling.
+With this method, the compiler builds static tables to describe
+the exception ranges. No dynamic code is required when entering
+a frame containing an exception handler. When an exception is
+raised, the tables are used to control a back trace of the
+subprogram invocation stack to locate the required exception
+handler. This method has considerably poorer performance for
+the propagation of exceptions, but there is no overhead for
+exception handlers if no exception is raised.
+
+The following switches can be used to control which of the
+two exception handling methods is used.
+
+@table @option
+@c !sort!
+
+@item -gnatL
+@cindex @option{-gnatL} (@code{gcc})
+This switch causes the longjmp/setjmp approach to be used
+for exception handling. If this is the default mechanism for the
+target (see below), then this has no effect. If the default
+mechanism for the target is zero cost exceptions, then
+this switch can be used to modify this default, but it must be
+used for all units in the partition, including all run-time
+library units. One way to achieve this is to use the
+@option{-a} and @option{-f} switches for @code{gnatmake}.
+This option is rarely used. One case in which it may be
+advantageous is if you have an application where exception
+raising is common and the overall performance of the
+application is improved by favoring exception propagation.
+
+@item -gnatZ
+@cindex @option{-gnatZ} (@code{gcc})
+@cindex Zero Cost Exceptions
+This switch causes the zero cost approach to be sed
+for exception handling. If this is the default mechanism for the
+target (see below), then this has no effect. If the default
+mechanism for the target is longjmp/setjmp exceptions, then
+this switch can be used to modify this default, but it must be
+used for all units in the partition, including all run-time
+library units. One way to achieve this is to use the
+@option{-a} and @option{-f} switches for @code{gnatmake}.
+This option can only be used if the zero cost approach
+is available for the target in use (see below).
+@end table
+
+@noindent
+The @code{longjmp/setjmp} approach is available on all targets, but
+the @code{zero cost} approach is only available on selected targets.
+To determine whether zero cost exceptions can be used for a
+particular target, look at the private part of the file system.ads.
+Either @code{GCC_ZCX_Support} or @code{Front_End_ZCX_Support} must
+be True to use the zero cost approach. If both of these switches
+are set to False, this means that zero cost exception handling
+is not yet available for that target. The switch
+@code{ZCX_By_Default} indicates the default approach. If this
+switch is set to True, then the @code{zero cost} approach is
+used by default.
+
+@node Units to Sources Mapping Files
+@subsection Units to Sources Mapping Files
+
+@table @option
+
+@item -gnatem^^=^@var{path}
+@cindex @option{-gnatem} (@code{gcc})
+A mapping file is a way to communicate to the compiler two mappings:
+from unit names to file names (without any directory information) and from
+file names to path names (with full directory information). These mappings
+are used by the compiler to short-circuit the path search.
+
+The use of mapping files is not required for correct operation of the
+compiler, but mapping files can improve efficiency, particularly when
+sources are read over a slow network connection. In normal operation,
+you need not be concerned with the format or use of mapping files,
+and the @option{-gnatem} switch is not a switch that you would use
+explicitly. it is intended only for use by automatic tools such as
+@code{gnatmake} running under the project file facility. The
+description here of the format of mapping files is provided
+for completeness and for possible use by other tools.
+
+A mapping file is a sequence of sets of three lines. In each set,
+the first line is the unit name, in lower case, with ``@code{%s}''
+appended for
+specifications and ``@code{%b}'' appended for bodies; the second line is the
+file name; and the third line is the path name.
+
+Example:
+@smallexample
+ main%b
+ main.2.ada
+ /gnat/project1/sources/main.2.ada
+@end smallexample
+
+When the switch @option{-gnatem} is specified, the compiler will create
+in memory the two mappings from the specified file. If there is any problem
+(non existent file, truncated file or duplicate entries), no mapping
+will be created.
+
+Several @option{-gnatem} switches may be specified; however, only the last
+one on the command line will be taken into account.
+
+When using a project file, @code{gnatmake} create a temporary mapping file
+and communicates it to the compiler using this switch.
+
+@end table
+
+
+@node Integrated Preprocessing
+@subsection Integrated Preprocessing
+
+@noindent
+GNAT sources may be preprocessed immediately before compilation; the actual
+text of the source is not the text of the source file, but is derived from it
+through a process called preprocessing. Integrated preprocessing is specified
+through switches @option{-gnatep} and/or @option{-gnateD}. @option{-gnatep}
+indicates, through a text file, the preprocessing data to be used.
+@option{-gnateD} specifies or modifies the values of preprocessing symbol.
+
+@noindent
+It is recommended that @code{gnatmake} switch ^-s^/SWITCH_CHECK^ should be
+used when Integrated Preprocessing is used. The reason is that preprocessing
+with another Preprocessing Data file without changing the sources will
+not trigger recompilation without this switch.
+
+@noindent
+Note that @code{gnatmake} switch ^-m^/MINIMAL_RECOMPILATION^ will almost
+always trigger recompilation for sources that are preprocessed,
+because @code{gnatmake} cannot compute the checksum of the source after
+preprocessing.
+
+@noindent
+The actual preprocessing function is described in details in section
+@ref{Preprocessing Using gnatprep}. This section only describes how integrated
+preprocessing is triggered and parameterized.
+
+@table @code
+
+@item -gnatep=@var{file}
+@cindex @option{-gnatep} (@code{gcc})
+This switch indicates to the compiler the file name (without directory
+information) of the preprocessor data file to use. The preprocessor data file
+should be found in the source directories.
+
+@noindent
+A preprocessing data file is a text file with significant lines indicating
+how should be preprocessed either a specific source or all sources not
+mentioned in other lines. A significant line is a non empty, non comment line.
+Comments are similar to Ada comments.
+
+@noindent
+Each significant line starts with either a literal string or the character '*'.
+A literal string is the file name (without directory information) of the source
+to preprocess. A character '*' indicates the preprocessing for all the sources
+that are not specified explicitly on other lines (order of the lines is not
+significant). It is an error to have two lines with the same file name or two
+lines starting with the character '*'.
+
+@noindent
+After the file name or the character '*', another optional literal string
+indicating the file name of the definition file to be used for preprocessing.
+(see @ref{Form of Definitions File}. The definition files are found by the
+compiler in one of the source directories. In some cases, when compiling
+a source in a directory other than the current directory, if the definition
+file is in the current directory, it may be necessary to add the current
+directory as a source directory through switch ^-I.^/SEARCH=[]^, otherwise
+the compiler would not find the definition file.
+
+@noindent
+Then, optionally, ^switches^switches^ similar to those of @code{gnatprep} may
+be found. Those ^switches^switches^ are:
+
+@table @code
+
+@item -b
+Causes both preprocessor lines and the lines deleted by
+preprocessing to be replaced by blank lines, preserving the line number.
+This ^switch^switch^ is always implied; however, if specified after @option{-c}
+it cancels the effect of @option{-c}.
+
+@item -c
+Causes both preprocessor lines and the lines deleted
+by preprocessing to be retained as comments marked
+with the special string ``@code{--! }''.
+
+@item -Dsymbol=value
+Define or redefine a symbol, associated with value. A symbol is an Ada
+identifier, or an Ada reserved word, with the exception of @code{if},
+@code{else}, @code{elsif}, @code{end}, @code{and}, @code{or} and @code{then}.
+@code{value} is either a literal string, an Ada identifier or any Ada reserved
+word. A symbol declared with this ^switch^switch^ replaces a symbol with the
+same name defined in a definition file.
+
+@item -s
+Causes a sorted list of symbol names and values to be
+listed on the standard output file.
+
+@item -u
+Causes undefined symbols to be treated as having the value @code{FALSE}
+in the context
+of a preprocessor test. In the absence of this option, an undefined symbol in
+a @code{#if} or @code{#elsif} test will be treated as an error.
+
+@end table
+
+@noindent
+Examples of valid lines in a preprocessor data file:
+
+@smallexample
+ "toto.adb" "prep.def" -u
+ -- preprocess "toto.adb", using definition file "prep.def",
+ -- undefined symbol are False.
+
+ * -c -DVERSION=V101
+ -- preprocess all other sources without a definition file;
+ -- suppressed lined are commented; symbol VERSION has the value V101.
+
+ "titi.adb" "prep2.def" -s
+ -- preprocess "titi.adb", using definition file "prep2.def";
+ -- list all symbols with their values.
+@end smallexample
+
+@item ^-gnateD^/DATA_PREPROCESSING=^symbol[=value]
+@cindex @option{-gnateD} (@code{gcc})
+Define or redefine a preprocessing symbol, associated with value. If no value
+is given on the command line, then the value of the symbol is @code{True}.
+A symbol is an identifier, following normal Ada (case-insensitive)
+rules for its syntax, and value is any sequence (including an empty sequence)
+of characters from the set (letters, digits, period, underline).
+Ada reserved words may be used as symbols, with the exceptions of @code{if},
+@code{else}, @code{elsif}, @code{end}, @code{and}, @code{or} and @code{then}.
+
+@noindent
+A symbol declared with this ^switch^switch^ on the command line replaces a
+symbol with the same name either in a definition file or specified with a
+^switch^switch^ -D in the preprocessor data file.
+
+@noindent
+This switch is similar to switch @option{^-D^/ASSOCIATE^} of @code{gnatprep}.
+
+@end table
+
+@node Code Generation Control
+@subsection Code Generation Control
+
+@noindent
+
+The GCC technology provides a wide range of target dependent
+@option{-m} switches for controlling
+details of code generation with respect to different versions of
+architectures. This includes variations in instruction sets (e.g.
+different members of the power pc family), and different requirements
+for optimal arrangement of instructions (e.g. different members of
+the x86 family). The list of available @option{-m} switches may be
+found in the GCC documentation.
+
+Use of the these @option{-m} switches may in some cases result in improved
+code performance.
+
+The GNAT Pro technology is tested and qualified without any
+@option{-m} switches,
+so generally the most reliable approach is to avoid the use of these
+switches. However, we generally expect most of these switches to work
+successfully with GNAT Pro, and many customers have reported successful
+use of these options.
+
+Our general advice is to avoid the use of @option{-m} switches unless
+special needs lead to requirements in this area. In particular,
+there is no point in using @option{-m} switches to improve performance
+unless you actually see a performance improvement.
+
+@ifset vms
+@node Return Codes
+@subsection Return Codes
+@cindex Return Codes
+@cindex @option{/RETURN_CODES=VMS}
+
+@noindent
+On VMS, GNAT compiled programs return POSIX-style codes by default,
+e.g. @option{/RETURN_CODES=POSIX}.
+
+To enable VMS style return codes, GNAT LINK with the option
+@option{/RETURN_CODES=VMS}. For example:
+
+@smallexample
+GNAT LINK MYMAIN.ALI /RETURN_CODES=VMS
+@end smallexample
+
+@noindent
+Programs built with /RETURN_CODES=VMS are suitable to be called in
+VMS DCL scripts. Programs compiled with the default /RETURN_CODES=POSIX
+are suitable for spawning with appropriate GNAT RTL routines.
+
+@end ifset
+
+
+@node Search Paths and the Run-Time Library (RTL)
+@section Search Paths and the Run-Time Library (RTL)
+
+@noindent
+With the GNAT source-based library system, the compiler must be able to
+find source files for units that are needed by the unit being compiled.
+Search paths are used to guide this process.
+
+The compiler compiles one source file whose name must be given
+explicitly on the command line. In other words, no searching is done
+for this file. To find all other source files that are needed (the most
+common being the specs of units), the compiler examines the following
+directories, in the following order:
+
+@enumerate
+@item
+The directory containing the source file of the main unit being compiled
+(the file name on the command line).
+
+@item
+Each directory named by an @option{^-I^/SOURCE_SEARCH^} switch given on the
+@code{gcc} command line, in the order given.
+
+@item
+@findex ADA_INCLUDE_PATH
+Each of the directories listed in the value of the
+@code{ADA_INCLUDE_PATH} ^environment variable^logical name^.
+@ifclear vms
+Construct this value
+exactly as the @code{PATH} environment variable: a list of directory
+names separated by colons (semicolons when working with the NT version).
+@end ifclear
+@ifset vms
+Normally, define this value as a logical name containing a comma separated
+list of directory names.
+
+This variable can also be defined by means of an environment string
+(an argument to the DEC C exec* set of functions).
+
+Logical Name:
+@smallexample
+DEFINE ANOTHER_PATH FOO:[BAG]
+DEFINE ADA_INCLUDE_PATH ANOTHER_PATH,FOO:[BAM],FOO:[BAR]
+@end smallexample
+
+By default, the path includes GNU:[LIB.OPENVMS7_x.2_8_x.DECLIB]
+first, followed by the standard Ada 95
+libraries in GNU:[LIB.OPENVMS7_x.2_8_x.ADAINCLUDE].
+If this is not redefined, the user will obtain the DEC Ada 83 IO packages
+(Text_IO, Sequential_IO, etc)
+instead of the Ada95 packages. Thus, in order to get the Ada 95
+packages by default, ADA_INCLUDE_PATH must be redefined.
+@end ifset
+
+@item
+@findex ADA_PRJ_INCLUDE_FILE
+Each of the directories listed in the text file whose name is given
+by the @code{ADA_PRJ_INCLUDE_FILE} ^environment variable^logical name^.
+
+@noindent
+@code{ADA_PRJ_INCLUDE_FILE} is normally set by gnatmake or by the ^gnat^GNAT^
+driver when project files are used. It should not normally be set
+by other means.
+
+@item
+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 the library}
+@end ifclear
+@end enumerate
+
+@noindent
+Specifying the switch @option{^-I-^/NOCURRENT_DIRECTORY^}
+inhibits the use of the directory
+containing the source file named in the command line. You can still
+have this directory on your search path, but in this case it must be
+explicitly requested with a @option{^-I^/SOURCE_SEARCH^} switch.
+
+Specifying the switch @option{-nostdinc}
+inhibits the search of the default location for the GNAT Run Time
+Library (RTL) source files.
+
+The compiler outputs its object files and ALI files in the current
+working directory.
+@ifclear vms
+Caution: The object file can be redirected with the @option{-o} switch;
+however, @code{gcc} and @code{gnat1} have not been coordinated on this
+so the @file{ALI} file will not go to the right place. Therefore, you should
+avoid using the @option{-o} switch.
+@end ifclear
+
+@findex System.IO
+The packages @code{Ada}, @code{System}, and @code{Interfaces} and their
+children make up the GNAT RTL, together with the simple @code{System.IO}
+package used in the @code{"Hello World"} example. The sources for these units
+are needed by the compiler and are kept together in one directory. Not
+all of the bodies are needed, but all of the sources are kept together
+anyway. In a normal installation, you need not specify these directory
+names when compiling or binding. Either the environment variables or
+the built-in defaults cause these files to be found.
+
+In addition to the language-defined hierarchies (@code{System}, @code{Ada} and
+@code{Interfaces}), the GNAT distribution provides a fourth hierarchy,
+consisting of child units of @code{GNAT}. This is a collection of generally
+useful types, subprograms, etc. See the @cite{GNAT Reference Manual} for
+further details.
+
+Besides simplifying access to the RTL, a major use of search paths is
+in compiling sources from multiple directories. This can make
+development environments much more flexible.
+
+
+@node Order of Compilation Issues
+@section Order of Compilation Issues
+
+@noindent
+If, in our earlier example, there was a spec for the @code{hello}
+procedure, it would be contained in the file @file{hello.ads}; yet this
+file would not have to be explicitly compiled. This is the result of the
+model we chose to implement library management. Some of the consequences
+of this model are as follows:
+
+@itemize @bullet
+@item
+There is no point in compiling specs (except for package
+specs with no bodies) because these are compiled as needed by clients. If
+you attempt a useless compilation, you will receive an error message.
+It is also useless to compile subunits because they are compiled as needed
+by the parent.
+
+@item
+There are no order of compilation requirements: performing a
+compilation never obsoletes anything. The only way you can obsolete
+something and require recompilations is to modify one of the
+source files on which it depends.
+
+@item
+There is no library as such, apart from the ALI files
+(@pxref{The Ada Library Information Files}, for information on the format
+of these files). For now we find it convenient to create separate ALI files,
+but eventually the information therein may be incorporated into the object
+file directly.
+
+@item
+When you compile a unit, the source files for the specs of all units
+that it @code{with}'s, all its subunits, and the bodies of any generics it
+instantiates must be available (reachable by the search-paths mechanism
+described above), or you will receive a fatal error message.
+@end itemize
+
+@node Examples
+@section Examples
+
+@noindent
+The following are some typical Ada compilation command line examples:
+
+@table @code
+@item $ gcc -c xyz.adb
+Compile body in file @file{xyz.adb} with all default options.
+
+@ifclear vms
+@item $ gcc -c -O2 -gnata xyz-def.adb
+@end ifclear
+@ifset vms
+@item $ GNAT COMPILE /OPTIMIZE=ALL -gnata xyz-def.adb
+@end ifset
+
+Compile the child unit package in file @file{xyz-def.adb} with extensive
+optimizations, and pragma @code{Assert}/@code{Debug} statements
+enabled.
+
+@item $ gcc -c -gnatc abc-def.adb
+Compile the subunit in file @file{abc-def.adb} in semantic-checking-only
+mode.
+@end table
+
+@node Binding Using gnatbind
+@chapter Binding Using @code{gnatbind}
+@findex gnatbind
+
+@menu
+* Running gnatbind::
+* Switches for gnatbind::
+* Command-Line Access::
+* Search Paths for gnatbind::
+* Examples of gnatbind Usage::
+@end menu
+
+@noindent
+This chapter describes the GNAT binder, @code{gnatbind}, which is used
+to bind compiled GNAT objects. The @code{gnatbind} program performs
+four separate functions:
+
+@enumerate
+@item
+Checks that a program is consistent, in accordance with the rules in
+Chapter 10 of the Ada 95 Reference Manual. In particular, error
+messages are generated if a program uses inconsistent versions of a
+given unit.
+
+@item
+Checks that an acceptable order of elaboration exists for the program
+and issues an error message if it cannot find an order of elaboration
+that satisfies the rules in Chapter 10 of the Ada 95 Language Manual.
+
+@item
+Generates a main program incorporating the given elaboration order.
+This program is a small Ada package (body and spec) that
+must be subsequently compiled
+using the GNAT compiler. The necessary compilation step is usually
+performed automatically by @code{gnatlink}. The two most important
+functions of this program
+are to call the elaboration routines of units in an appropriate order
+and to call the main program.
+
+@item
+Determines the set of object files required by the given main program.
+This information is output in the forms of comments in the generated program,
+to be read by the @code{gnatlink} utility used to link the Ada application.
+@end enumerate
+
+
+@node Running gnatbind
+@section Running @code{gnatbind}
+
+@noindent
+The form of the @code{gnatbind} command is
+
+@smallexample
+$ gnatbind [@i{switches}] @i{mainprog}[.ali] [@i{switches}]
+@end smallexample
+
+@noindent
+where @file{@i{mainprog}.adb} is the Ada file containing the main program
+unit body. If no switches are specified, @code{gnatbind} constructs an Ada
+package in two files whose names are
+@file{b~@i{mainprog}.ads}, and @file{b~@i{mainprog}.adb}.
+For example, if given the
+parameter @file{hello.ali}, for a main program contained in file
+@file{hello.adb}, the binder output files would be @file{b~hello.ads}
+and @file{b~hello.adb}.
+
+When doing consistency checking, the binder takes into consideration
+any source files it can locate. For example, if the binder determines
+that the given main program requires the package @code{Pack}, whose
+@file{.ALI}
+file is @file{pack.ali} and whose corresponding source spec file is
+@file{pack.ads}, it attempts to locate the source file @file{pack.ads}
+(using the same search path conventions as previously described for the
+@code{gcc} command). If it can locate this source file, it checks that
+the time stamps
+or source checksums of the source and its references to in @file{ALI} files
+match. In other words, any @file{ALI} files that mentions this spec must have
+resulted from compiling this version of the source file (or in the case
+where the source checksums match, a version close enough that the
+difference does not matter).
+
+@cindex Source files, use by binder
+The effect of this consistency checking, which includes source files, is
+that the binder ensures that the program is consistent with the latest
+version of the source files that can be located at bind time. Editing a
+source file without compiling files that depend on the source file cause
+error messages to be generated by the binder.
+
+For example, suppose you have a main program @file{hello.adb} and a
+package @code{P}, from file @file{p.ads} and you perform the following
+steps:
+
+@enumerate
+@item
+Enter @code{gcc -c hello.adb} to compile the main program.
+
+@item
+Enter @code{gcc -c p.ads} to compile package @code{P}.
+
+@item
+Edit file @file{p.ads}.
+
+@item
+Enter @code{gnatbind hello}.
+@end enumerate
+
+@noindent
+At this point, the file @file{p.ali} contains an out-of-date time stamp
+because the file @file{p.ads} has been edited. The attempt at binding
+fails, and the binder generates the following error messages:
+
+@smallexample
+error: "hello.adb" must be recompiled ("p.ads" has been modified)
+error: "p.ads" has been modified and must be recompiled
+@end smallexample
+
+@noindent
+Now both files must be recompiled as indicated, and then the bind can
+succeed, generating a main program. You need not normally be concerned
+with the contents of this file, but for reference purposes a sample
+binder output file is given in @ref{Example of Binder Output File}.
+
+In most normal usage, the default mode of @command{gnatbind} which is to
+generate the main package in Ada, as described in the previous section.
+In particular, this means that any Ada programmer can read and understand
+the generated main program. It can also be debugged just like any other
+Ada code provided the @option{^-g^/DEBUG^} switch is used for
+@command{gnatbind} and @command{gnatlink}.
+
+However for some purposes it may be convenient to generate the main
+program in C rather than Ada. This may for example be helpful when you
+are generating a mixed language program with the main program in C. The
+GNAT compiler itself is an example.
+The use of the @option{^-C^/BIND_FILE=C^} switch
+for both @code{gnatbind} and @code{gnatlink} will cause the program to
+be generated in C (and compiled using the gnu C compiler).
+
+
+@node Switches for gnatbind
+@section Switches for @command{gnatbind}
+
+@noindent
+The following switches are available with @code{gnatbind}; details will
+be presented in subsequent sections.
+
+@menu
+* Consistency-Checking Modes::
+* Binder Error Message Control::
+* Elaboration Control::
+* Output Control::
+* Binding with Non-Ada Main Programs::
+* Binding Programs with No Main Subprogram::
+@end menu
+
+@table @option
+@c !sort!
+@item ^-aO^/OBJECT_SEARCH^
+@cindex @option{^-aO^/OBJECT_SEARCH^} (@command{gnatbind})
+Specify directory to be searched for ALI files.
+
+@item ^-aI^/SOURCE_SEARCH^
+@cindex @option{^-aI^/SOURCE_SEARCH^} (@command{gnatbind})
+Specify directory to be searched for source file.
+
+@item ^-A^/BIND_FILE=ADA^
+@cindex @option{^-A^/BIND_FILE=ADA^} (@command{gnatbind})
+Generate binder program in Ada (default)
+
+@item ^-b^/REPORT_ERRORS=BRIEF^
+@cindex @option{^-b^/REPORT_ERRORS=BRIEF^} (@command{gnatbind})
+Generate brief messages to @file{stderr} even if verbose mode set.
+
+@item ^-c^/NOOUTPUT^
+@cindex @option{^-c^/NOOUTPUT^} (@command{gnatbind})
+Check only, no generation of binder output file.
+
+@item ^-C^/BIND_FILE=C^
+@cindex @option{^-C^/BIND_FILE=C^} (@command{gnatbind})
+Generate binder program in C
+
+@item ^-e^/ELABORATION_DEPENDENCIES^
+@cindex @option{^-e^/ELABORATION_DEPENDENCIES^} (@command{gnatbind})
+Output complete list of elaboration-order dependencies.
+
+@item ^-E^/STORE_TRACEBACKS^
+@cindex @option{^-E^/STORE_TRACEBACKS^} (@command{gnatbind})
+Store tracebacks in exception occurrences when the target supports it.
+This is the default with the zero cost exception mechanism.
+@ignore
+@c The following may get moved to an appendix
+This option is currently supported on the following targets:
+all x86 ports, Solaris, Windows, HP-UX, AIX, PowerPC VxWorks and Alpha VxWorks.
+@end ignore
+See also the packages @code{GNAT.Traceback} and
+@code{GNAT.Traceback.Symbolic} for more information.
+@ifclear vms
+Note that on x86 ports, you must not use @option{-fomit-frame-pointer}
+@code{gcc} option.
+@end ifclear
+
+@item ^-F^/FORCE_ELABS_FLAGS^
+@cindex @option{^-F^/FORCE_ELABS_FLAGS^} (@command{gnatbind})
+Force the checks of elaboration flags. @command{gnatbind} does not normally
+generate checks of elaboration flags for the main executable, except when
+a Stand-Alone Library is used. However, there are cases when this cannot be
+detected by gnatbind. An example is importing an interface of a Stand-Alone
+Library through a pragma Import and only specifying through a linker switch
+this Stand-Alone Library. This switch is used to guarantee that elaboration
+flag checks are generated.
+
+@item ^-h^/HELP^
+@cindex @option{^-h^/HELP^} (@command{gnatbind})
+Output usage (help) information
+
+@item ^-I^/SEARCH^
+@cindex @option{^-I^/SEARCH^} (@command{gnatbind})
+Specify directory to be searched for source and ALI files.
+
+@item ^-I-^/NOCURRENT_DIRECTORY^
+@cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@command{gnatbind})
+Do not look for sources in the current directory where @code{gnatbind} was
+invoked, and do not look for ALI files in the directory containing the
+ALI file named in the @code{gnatbind} command line.
+
+@item ^-l^/ORDER_OF_ELABORATION^
+@cindex @option{^-l^/ORDER_OF_ELABORATION^} (@command{gnatbind})
+Output chosen elaboration order.
+
+@item ^-Lxxx^/BUILD_LIBRARY=xxx^
+@cindex @option{^-L^/BUILD_LIBRARY^} (@command{gnatbind})
+Binds the units for library building. In this case the adainit and
+adafinal procedures (See @pxref{Binding with Non-Ada Main Programs})
+are renamed to ^xxxinit^XXXINIT^ and
+^xxxfinal^XXXFINAL^.
+Implies ^-n^/NOCOMPILE^.
+@ifclear vms
+(@pxref{GNAT and Libraries}, for more details.)
+@end ifclear
+@ifset vms
+On OpenVMS, these init and final procedures are exported in uppercase
+letters. For example if /BUILD_LIBRARY=toto is used, the exported name of
+the init procedure will be "TOTOINIT" and the exported name of the final
+procedure will be "TOTOFINAL".
+@end ifset
+
+@item ^-Mxyz^/RENAME_MAIN=xyz^
+@cindex @option{^-M^/RENAME_MAIN^} (@command{gnatbind})
+Rename generated main program from main to xyz
+
+@item ^-m^/ERROR_LIMIT=^@var{n}
+@cindex @option{^-m^/ERROR_LIMIT^} (@command{gnatbind})
+Limit number of detected errors to @var{n}, where @var{n} is
+in the range 1..999_999. The default value if no switch is
+given is 9999. Binding is terminated if the limit is exceeded.
+@ifset unw
+Furthermore, under Windows, the sources pointed to by the libraries path
+set in the registry are not searched for.
+@end ifset
+
+@item ^-n^/NOMAIN^
+@cindex @option{^-n^/NOMAIN^} (@command{gnatbind})
+No main program.
+
+@item -nostdinc
+@cindex @option{-nostdinc} (@command{gnatbind})
+Do not look for sources in the system default directory.
+
+@item -nostdlib
+@cindex @option{-nostdlib} (@command{gnatbind})
+Do not look for library files in the system default directory.
+
+@item --RTS=@var{rts-path}
+@cindex @option{--RTS} (@code{gnatbind})
+Specifies the default location of the runtime library. Same meaning as the
+equivalent @code{gnatmake} flag (see @ref{Switches for gnatmake}).
+
+@item ^-o ^/OUTPUT=^@var{file}
+@cindex @option{^-o ^/OUTPUT^} (@command{gnatbind})
+Name the output file @var{file} (default is @file{b~@var{xxx}.adb}).
+Note that if this option is used, then linking must be done manually,
+gnatlink cannot be used.
+
+@item ^-O^/OBJECT_LIST^
+@cindex @option{^-O^/OBJECT_LIST^} (@command{gnatbind})
+Output object list.
+
+@item ^-p^/PESSIMISTIC_ELABORATION^
+@cindex @option{^-p^/PESSIMISTIC_ELABORATION^} (@command{gnatbind})
+Pessimistic (worst-case) elaboration order
+
+@item ^-s^/READ_SOURCES=ALL^
+@cindex @option{^-s^/READ_SOURCES=ALL^} (@command{gnatbind})
+Require all source files to be present.
+
+@item ^-S@var{xxx}^/INITIALIZE_SCALARS=@var{xxx}^
+@cindex @option{^-S^/INITIALIZE_SCALARS^} (@command{gnatbind})
+Specifies the value to be used when detecting uninitialized scalar
+objects with pragma Initialize_Scalars.
+The @var{xxx} ^string specified with the switch^option^ may be either
+@itemize @bullet
+@item ``@option{^in^INVALID^}'' requesting an invalid value where possible
+@item ``@option{^lo^LOW^}'' for the lowest possible value
+possible, and the low
+@item ``@option{^hi^HIGH^}'' for the highest possible value
+@item ``@option{xx}'' for a value consisting of repeated bytes with the
+value 16#xx# (i.e. xx is a string of two hexadecimal digits).
+@end itemize
+
+In addition, you can specify @option{-Sev} to indicate that the value is
+to be set at run time. In this case, the program will look for an environment
+@cindex GNAT_INIT_SCALARS
+variable of the form @code{GNAT_INIT_SCALARS=xx}, where xx is one
+of @option{in/lo/hi/xx} with the same meanings as above.
+If no environment variable is found, or if it does not have a valid value,
+then the default is @option{in} (invalid values).
+
+@ifclear vms
+@item -static
+@cindex @option{-static} (@code{gnatbind})
+Link against a static GNAT run time.
+
+@item -shared
+@cindex @option{-shared} (@code{gnatbind})
+Link against a shared GNAT run time when available.
+@end ifclear
+
+@item ^-t^/NOTIME_STAMP_CHECK^
+@cindex @option{^-t^/NOTIME_STAMP_CHECK^} (@code{gnatbind})
+Tolerate time stamp and other consistency errors
+
+@item ^-T@var{n}^/TIME_SLICE=@var{n}^
+@cindex @option{^-T^/TIME_SLICE^} (@code{gnatbind})
+Set the time slice value to @var{n} milliseconds. If the system supports
+the specification of a specific time slice value, then the indicated value
+is used. If the system does not support specific time slice values, but
+does support some general notion of round-robin scheduling, then any
+non-zero value will activate round-robin scheduling.
+
+A value of zero is treated specially. It turns off time
+slicing, and in addition, indicates to the tasking run time that the
+semantics should match as closely as possible the Annex D
+requirements of the Ada RM, and in particular sets the default
+scheduling policy to @code{FIFO_Within_Priorities}.
+
+@item ^-v^/REPORT_ERRORS=VERBOSE^
+@cindex @option{^-v^/REPORT_ERRORS=VERBOSE^} (@code{gnatbind})
+Verbose mode. Write error messages, header, summary output to
+@file{stdout}.
+
+@ifclear vms
+@item -w@var{x}
+@cindex @option{-w} (@code{gnatbind})
+Warning mode (@var{x}=s/e for suppress/treat as error)
+@end ifclear
+
+@ifset vms
+@item /WARNINGS=NORMAL
+@cindex @option{/WARNINGS} (@code{gnatbind})
+Normal warnings mode. Warnings are issued but ignored
+
+@item /WARNINGS=SUPPRESS
+@cindex @option{/WARNINGS} (@code{gnatbind})
+All warning messages are suppressed
+
+@item /WARNINGS=ERROR
+@cindex @option{/WARNINGS} (@code{gnatbind})
+Warning messages are treated as fatal errors
+@end ifset
+
+@item ^-x^/READ_SOURCES=NONE^
+@cindex @option{^-x^/READ_SOURCES^} (@code{gnatbind})
+Exclude source files (check object consistency only).
+
+@ifset vms
+@item /READ_SOURCES=AVAILABLE
+@cindex @option{/READ_SOURCES} (@code{gnatbind})
+Default mode, in which sources are checked for consistency only if
+they are available.
+@end ifset
+
+@item ^-z^/ZERO_MAIN^
+@cindex @option{^-z^/ZERO_MAIN^} (@code{gnatbind})
+No main subprogram.
+@end table
+
+@ifclear vms
+@noindent
+You may obtain this listing of switches by running @code{gnatbind} with
+no arguments.
+@end ifclear
+
+
+@node Consistency-Checking Modes
+@subsection Consistency-Checking Modes
+
+@noindent
+As described earlier, by default @code{gnatbind} checks
+that object files are consistent with one another and are consistent
+with any source files it can locate. The following switches control binder
+access to sources.
+
+@table @option
+@c !sort!
+@item ^-s^/READ_SOURCES=ALL^
+@cindex @option{^-s^/READ_SOURCES=ALL^} (@code{gnatbind})
+Require source files to be present. In this mode, the binder must be
+able to locate all source files that are referenced, in order to check
+their consistency. In normal mode, if a source file cannot be located it
+is simply ignored. If you specify this switch, a missing source
+file is an error.
+
+@item ^-x^/READ_SOURCES=NONE^
+@cindex @option{^-x^/READ_SOURCES=NONE^} (@code{gnatbind})
+Exclude source files. In this mode, the binder only checks that ALI
+files are consistent with one another. Source files are not accessed.
+The binder runs faster in this mode, and there is still a guarantee that
+the resulting program is self-consistent.
+If a source file has been edited since it was last compiled, and you
+specify this switch, the binder will not detect that the object
+file is out of date with respect to the source file. Note that this is the
+mode that is automatically used by @code{gnatmake} because in this
+case the checking against sources has already been performed by
+@code{gnatmake} in the course of compilation (i.e. before binding).
+
+@ifset vms
+@item /READ_SOURCES=AVAILABLE
+@cindex @code{/READ_SOURCES=AVAILABLE} (@code{gnatbind})
+This is the default mode in which source files are checked if they are
+available, and ignored if they are not available.
+@end ifset
+@end table
+
+@node Binder Error Message Control
+@subsection Binder Error Message Control
+
+@noindent
+The following switches provide control over the generation of error
+messages from the binder:
+
+@table @option
+@c !sort!
+@item ^-v^/REPORT_ERRORS=VERBOSE^
+@cindex @option{^-v^/REPORT_ERRORS=VERBOSE^} (@code{gnatbind})
+Verbose mode. In the normal mode, brief error messages are generated to
+@file{stderr}. If this switch is present, a header is written
+to @file{stdout} and any error messages are directed to @file{stdout}.
+All that is written to @file{stderr} is a brief summary message.
+
+@item ^-b^/REPORT_ERRORS=BRIEF^
+@cindex @option{^-b^/REPORT_ERRORS=BRIEF^} (@code{gnatbind})
+Generate brief error messages to @file{stderr} even if verbose mode is
+specified. This is relevant only when used with the
+@option{^-v^/REPORT_ERRORS=VERBOSE^} switch.
+
+@ifclear vms
+@item -m@var{n}
+@cindex @option{-m} (@code{gnatbind})
+Limits the number of error messages to @var{n}, a decimal integer in the
+range 1-999. The binder terminates immediately if this limit is reached.
+
+@item -M@var{xxx}
+@cindex @option{-M} (@code{gnatbind})
+Renames the generated main program from @code{main} to @code{xxx}.
+This is useful in the case of some cross-building environments, where
+the actual main program is separate from the one generated
+by @code{gnatbind}.
+@end ifclear
+
+@item ^-ws^/WARNINGS=SUPPRESS^
+@cindex @option{^-ws^/WARNINGS=SUPPRESS^} (@code{gnatbind})
+@cindex Warnings
+Suppress all warning messages.
+
+@item ^-we^/WARNINGS=ERROR^
+@cindex @option{^-we^/WARNINGS=ERROR^} (@code{gnatbind})
+Treat any warning messages as fatal errors.
+
+@ifset vms
+@item /WARNINGS=NORMAL
+Standard mode with warnings generated, but warnings do not get treated
+as errors.
+@end ifset
+
+@item ^-t^/NOTIME_STAMP_CHECK^
+@cindex @option{^-t^/NOTIME_STAMP_CHECK^} (@code{gnatbind})
+@cindex Time stamp checks, in binder
+@cindex Binder consistency checks
+@cindex Consistency checks, in binder
+The binder performs a number of consistency checks including:
+
+@itemize @bullet
+@item
+Check that time stamps of a given source unit are consistent
+@item
+Check that checksums of a given source unit are consistent
+@item
+Check that consistent versions of @code{GNAT} were used for compilation
+@item
+Check consistency of configuration pragmas as required
+@end itemize
+
+@noindent
+Normally failure of such checks, in accordance with the consistency
+requirements of the Ada Reference Manual, causes error messages to be
+generated which abort the binder and prevent the output of a binder
+file and subsequent link to obtain an executable.
+
+The @option{^-t^/NOTIME_STAMP_CHECK^} switch converts these error messages
+into warnings, so that
+binding and linking can continue to completion even in the presence of such
+errors. The result may be a failed link (due to missing symbols), or a
+non-functional executable which has undefined semantics.
+@emph{This means that
+@option{^-t^/NOTIME_STAMP_CHECK^} should be used only in unusual situations,
+with extreme care.}
+@end table
+
+@node Elaboration Control
+@subsection Elaboration Control
+
+@noindent
+The following switches provide additional control over the elaboration
+order. For full details see @xref{Elaboration Order Handling in GNAT}.
+
+@table @option
+@item ^-p^/PESSIMISTIC_ELABORATION^
+@cindex @option{^-p^/PESSIMISTIC_ELABORATION^} (@code{gnatbind})
+Normally the binder attempts to choose an elaboration order that is
+likely to minimize the likelihood of an elaboration order error resulting
+in raising a @code{Program_Error} exception. This switch reverses the
+action of the binder, and requests that it deliberately choose an order
+that is likely to maximize the likelihood of an elaboration error.
+This is useful in ensuring portability and avoiding dependence on
+accidental fortuitous elaboration ordering.
+
+Normally it only makes sense to use the @option{^-p^/PESSIMISTIC_ELABORATION^}
+switch if dynamic
+elaboration checking is used (@option{-gnatE} switch used for compilation).
+This is because in the default static elaboration mode, all necessary
+@code{Elaborate_All} pragmas are implicitly inserted.
+These implicit pragmas are still respected by the binder in
+@option{^-p^/PESSIMISTIC_ELABORATION^} mode, so a
+safe elaboration order is assured.
+@end table
+
+@node Output Control
+@subsection Output Control
+
+@noindent
+The following switches allow additional control over the output
+generated by the binder.
+
+@table @option
+@c !sort!
+
+@item ^-A^/BIND_FILE=ADA^
+@cindex @option{^-A^/BIND_FILE=ADA^} (@code{gnatbind})
+Generate binder program in Ada (default). The binder program is named
+@file{b~@var{mainprog}.adb} by default. This can be changed with
+@option{^-o^/OUTPUT^} @code{gnatbind} option.
+
+@item ^-c^/NOOUTPUT^
+@cindex @option{^-c^/NOOUTPUT^} (@code{gnatbind})
+Check only. Do not generate the binder output file. In this mode the
+binder performs all error checks but does not generate an output file.
+
+@item ^-C^/BIND_FILE=C^
+@cindex @option{^-C^/BIND_FILE=C^} (@code{gnatbind})
+Generate binder program in C. The binder program is named
+@file{b_@var{mainprog}.c}.
+This can be changed with @option{^-o^/OUTPUT^} @code{gnatbind}
+option.
+
+@item ^-e^/ELABORATION_DEPENDENCIES^
+@cindex @option{^-e^/ELABORATION_DEPENDENCIES^} (@code{gnatbind})
+Output complete list of elaboration-order dependencies, showing the
+reason for each dependency. This output can be rather extensive but may
+be useful in diagnosing problems with elaboration order. The output is
+written to @file{stdout}.
+
+@item ^-h^/HELP^
+@cindex @option{^-h^/HELP^} (@code{gnatbind})
+Output usage information. The output is written to @file{stdout}.
+
+@item ^-K^/LINKER_OPTION_LIST^
+@cindex @option{^-K^/LINKER_OPTION_LIST^} (@code{gnatbind})
+Output linker options to @file{stdout}. Includes library search paths,
+contents of pragmas Ident and Linker_Options, and libraries added
+by @code{gnatbind}.
+
+@item ^-l^/ORDER_OF_ELABORATION^
+@cindex @option{^-l^/ORDER_OF_ELABORATION^} (@code{gnatbind})
+Output chosen elaboration order. The output is written to @file{stdout}.
+
+@item ^-O^/OBJECT_LIST^
+@cindex @option{^-O^/OBJECT_LIST^} (@code{gnatbind})
+Output full names of all the object files that must be linked to provide
+the Ada component of the program. The output is written to @file{stdout}.
+This list includes the files explicitly supplied and referenced by the user
+as well as implicitly referenced run-time unit files. The latter are
+omitted if the corresponding units reside in shared libraries. The
+directory names for the run-time units depend on the system configuration.
+
+@item ^-o ^/OUTPUT=^@var{file}
+@cindex @option{^-o^/OUTPUT^} (@code{gnatbind})
+Set name of output file to @var{file} instead of the normal
+@file{b~@var{mainprog}.adb} default. Note that @var{file} denote the Ada
+binder generated body filename. In C mode you would normally give
+@var{file} an extension of @file{.c} because it will be a C source program.
+Note that if this option is used, then linking must be done manually.
+It is not possible to use gnatlink in this case, since it cannot locate
+the binder file.
+
+@item ^-r^/RESTRICTION_LIST^
+@cindex @option{^-r^/RESTRICTION_LIST^} (@code{gnatbind})
+Generate list of @code{pragma Restrictions} that could be applied to
+the current unit. This is useful for code audit purposes, and also may
+be used to improve code generation in some cases.
+
+@end table
+
+@node Binding with Non-Ada Main Programs
+@subsection Binding with Non-Ada Main Programs
+
+@noindent
+In our description so far we have assumed that the main
+program is in Ada, and that the task of the binder is to generate a
+corresponding function @code{main} that invokes this Ada main
+program. GNAT also supports the building of executable programs where
+the main program is not in Ada, but some of the called routines are
+written in Ada and compiled using GNAT (@pxref{Mixed Language Programming}).
+The following switch is used in this situation:
+
+@table @option
+@item ^-n^/NOMAIN^
+@cindex @option{^-n^/NOMAIN^} (@code{gnatbind})
+No main program. The main program is not in Ada.
+@end table
+
+@noindent
+In this case, most of the functions of the binder are still required,
+but instead of generating a main program, the binder generates a file
+containing the following callable routines:
+
+@table @code
+@item adainit
+@findex adainit
+You must call this routine to initialize the Ada part of the program by
+calling the necessary elaboration routines. A call to @code{adainit} is
+required before the first call to an Ada subprogram.
+
+Note that it is assumed that the basic execution environment must be setup
+to be appropriate for Ada execution at the point where the first Ada
+subprogram is called. In particular, if the Ada code will do any
+floating-point operations, then the FPU must be setup in an appropriate
+manner. For the case of the x86, for example, full precision mode is
+required. The procedure GNAT.Float_Control.Reset may be used to ensure
+that the FPU is in the right state.
+
+@item adafinal
+@findex adafinal
+You must call this routine to perform any library-level finalization
+required by the Ada subprograms. A call to @code{adafinal} is required
+after the last call to an Ada subprogram, and before the program
+terminates.
+@end table
+
+@noindent
+If the @option{^-n^/NOMAIN^} switch
+@cindex @option{^-n^/NOMAIN^} (@command{gnatbind})
+@cindex Binder, multiple input files
+is given, more than one ALI file may appear on
+the command line for @code{gnatbind}. The normal @dfn{closure}
+calculation is performed for each of the specified units. Calculating
+the closure means finding out the set of units involved by tracing
+@code{with} references. The reason it is necessary to be able to
+specify more than one ALI file is that a given program may invoke two or
+more quite separate groups of Ada units.
+
+The binder takes the name of its output file from the last specified ALI
+file, unless overridden by the use of the @option{^-o file^/OUTPUT=file^}.
+@cindex @option{^-o^/OUTPUT^} (@command{gnatbind})
+The output is an Ada unit in source form that can
+be compiled with GNAT unless the -C switch is used in which case the
+output is a C source file, which must be compiled using the C compiler.
+This compilation occurs automatically as part of the @code{gnatlink}
+processing.
+
+Currently the GNAT run time requires a FPU using 80 bits mode
+precision. Under targets where this is not the default it is required to
+call GNAT.Float_Control.Reset before using floating point numbers (this
+include float computation, float input and output) in the Ada code. A
+side effect is that this could be the wrong mode for the foreign code
+where floating point computation could be broken after this call.
+
+@node Binding Programs with No Main Subprogram
+@subsection Binding Programs with No Main Subprogram
+
+@noindent
+It is possible to have an Ada program which does not have a main
+subprogram. This program will call the elaboration routines of all the
+packages, then the finalization routines.
+
+The following switch is used to bind programs organized in this manner:
+
+@table @option
+@item ^-z^/ZERO_MAIN^
+@cindex @option{^-z^/ZERO_MAIN^} (@code{gnatbind})
+Normally the binder checks that the unit name given on the command line
+corresponds to a suitable main subprogram. When this switch is used,
+a list of ALI files can be given, and the execution of the program
+consists of elaboration of these units in an appropriate order.
+@end table
+
+
+@node Command-Line Access
+@section Command-Line Access
+
+@noindent
+The package @code{Ada.Command_Line} provides access to the command-line
+arguments and program name. In order for this interface to operate
+correctly, the two variables
+
+@smallexample
+@group
+int gnat_argc;
+char **gnat_argv;
+@end group
+@end smallexample
+
+@noindent
+@findex gnat_argv
+@findex gnat_argc
+are declared in one of the GNAT library routines. These variables must
+be set from the actual @code{argc} and @code{argv} values passed to the
+main program. With no @option{^n^/NOMAIN^} present, @code{gnatbind}
+generates the C main program to automatically set these variables.
+If the @option{^n^/NOMAIN^} switch is used, there is no automatic way to
+set these variables. If they are not set, the procedures in
+@code{Ada.Command_Line} will not be available, and any attempt to use
+them will raise @code{Constraint_Error}. If command line access is
+required, your main program must set @code{gnat_argc} and
+@code{gnat_argv} from the @code{argc} and @code{argv} values passed to
+it.
+
+
+@node Search Paths for gnatbind
+@section Search Paths for @code{gnatbind}
+
+@noindent
+The binder takes the name of an ALI file as its argument and needs to
+locate source files as well as other ALI files to verify object consistency.
+
+For source files, it follows exactly the same search rules as @code{gcc}
+(@pxref{Search Paths and the Run-Time Library (RTL)}). For ALI files the
+directories searched are:
+
+@enumerate
+@item
+The directory containing the ALI file named in the command line, unless
+the switch @option{^-I-^/NOCURRENT_DIRECTORY^} is specified.
+
+@item
+All directories specified by @option{^-I^/SEARCH^}
+switches on the @code{gnatbind}
+command line, in the order given.
+
+@item
+@findex ADA_OBJECTS_PATH
+Each of the directories listed in the value of the
+@code{ADA_OBJECTS_PATH} ^environment variable^logical name^.
+@ifset unw
+Construct this value
+exactly as the @code{PATH} environment variable: a list of directory
+names separated by colons (semicolons when working with the NT version
+of GNAT).
+@end ifset
+@ifset vms
+Normally, define this value as a logical name containing a comma separated
+list of directory names.
+
+This variable can also be defined by means of an environment string
+(an argument to the DEC C exec* set of functions).
+
+Logical Name:
+@smallexample
+DEFINE ANOTHER_PATH FOO:[BAG]
+DEFINE ADA_OBJECTS_PATH ANOTHER_PATH,FOO:[BAM],FOO:[BAR]
+@end smallexample
+
+By default, the path includes GNU:[LIB.OPENVMS7_x.2_8_x.DECLIB]
+first, followed by the standard Ada 95
+libraries in GNU:[LIB.OPENVMS7_x.2_8_x.ADALIB].
+If this is not redefined, the user will obtain the DEC Ada 83 IO packages
+(Text_IO, Sequential_IO, etc)
+instead of the Ada95 packages. Thus, in order to get the Ada 95
+packages by default, ADA_OBJECTS_PATH must be redefined.
+@end ifset
+
+@item
+@findex ADA_PRJ_OBJECTS_FILE
+Each of the directories listed in the text file whose name is given
+by the @code{ADA_PRJ_OBJECTS_FILE} ^environment variable^logical name^.
+
+@noindent
+@code{ADA_PRJ_OBJECTS_FILE} is normally set by gnatmake or by the ^gnat^GNAT^
+driver when project files are used. It should not normally be set
+by other means.
+
+@item
+The content of the @file{ada_object_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) unless the switch @option{-nostdlib} is
+specified.
+@ifclear vms
+@ref{Installing the library}
+@end ifclear
+@end enumerate
+
+@noindent
+In the binder the switch @option{^-I^/SEARCH^}
+@cindex @option{^-I^/SEARCH^} (@command{gnatbind})
+is used to specify both source and
+library file paths. Use @option{^-aI^/SOURCE_SEARCH^}
+@cindex @option{^-aI^/SOURCE_SEARCH^} (@command{gnatbind})
+instead if you want to specify
+source paths only, and @option{^-aO^/LIBRARY_SEARCH^}
+@cindex @option{^-aO^/LIBRARY_SEARCH^} (@command{gnatbind})
+if you want to specify library paths
+only. This means that for the binder
+@option{^-I^/SEARCH=^}@var{dir} is equivalent to
+@option{^-aI^/SOURCE_SEARCH=^}@var{dir}
+@option{^-aO^/OBJECT_SEARCH=^}@var{dir}.
+The binder generates the bind file (a C language source file) in the
+current working directory.
+
+@findex Ada
+@findex System
+@findex Interfaces
+@findex GNAT
+The packages @code{Ada}, @code{System}, and @code{Interfaces} and their
+children make up the GNAT Run-Time Library, together with the package
+GNAT and its children, which contain a set of useful additional
+library functions provided by GNAT. The sources for these units are
+needed by the compiler and are kept together in one directory. The ALI
+files and object files generated by compiling the RTL are needed by the
+binder and the linker and are kept together in one directory, typically
+different from the directory containing the sources. In a normal
+installation, you need not specify these directory names when compiling
+or binding. Either the environment variables or the built-in defaults
+cause these files to be found.
+
+Besides simplifying access to the RTL, a major use of search paths is
+in compiling sources from multiple directories. This can make
+development environments much more flexible.
+
+@node Examples of gnatbind Usage
+@section Examples of @code{gnatbind} Usage
+
+@noindent
+This section contains a number of examples of using the GNAT binding
+utility @code{gnatbind}.
+
+@table @code
+@item gnatbind hello
+The main program @code{Hello} (source program in @file{hello.adb}) is
+bound using the standard switch settings. The generated main program is
+@file{b~hello.adb}. This is the normal, default use of the binder.
+
+@ifclear vms
+@item gnatbind hello -o mainprog.adb
+@end ifclear
+@ifset vms
+@item gnatbind HELLO.ALI /OUTPUT=Mainprog.ADB
+@end ifset
+The main program @code{Hello} (source program in @file{hello.adb}) is
+bound using the standard switch settings. The generated main program is
+@file{mainprog.adb} with the associated spec in
+@file{mainprog.ads}. Note that you must specify the body here not the
+spec, in the case where the output is in Ada. Note that if this option
+is used, then linking must be done manually, since gnatlink will not
+be able to find the generated file.
+
+@ifclear vms
+@item gnatbind main -C -o mainprog.c -x
+@end ifclear
+@ifset vms
+@item gnatbind MAIN.ALI /BIND_FILE=C /OUTPUT=Mainprog.C /READ_SOURCES=NONE
+@end ifset
+The main program @code{Main} (source program in
+@file{main.adb}) is bound, excluding source files from the
+consistency checking, generating
+the file @file{mainprog.c}.
+
+@ifclear vms
+@item gnatbind -x main_program -C -o mainprog.c
+This command is exactly the same as the previous example. Switches may
+appear anywhere in the command line, and single letter switches may be
+combined into a single switch.
+@end ifclear
+
+@ifclear vms
+@item gnatbind -n math dbase -C -o ada-control.c
+@end ifclear
+@ifset vms
+@item gnatbind /NOMAIN math dbase /BIND_FILE=C /OUTPUT=ada-control.c
+@end ifset
+The main program is in a language other than Ada, but calls to
+subprograms in packages @code{Math} and @code{Dbase} appear. This call
+to @code{gnatbind} generates the file @file{ada-control.c} containing
+the @code{adainit} and @code{adafinal} routines to be called before and
+after accessing the Ada units.
+@end table
+
+
+@c ------------------------------------
+@node Linking Using gnatlink
+@chapter Linking Using @code{gnatlink}
+@c ------------------------------------
+@findex gnatlink
+
+@noindent
+This chapter discusses @code{gnatlink}, a tool that links
+an Ada program and builds an executable file. This utility
+invokes the system linker ^(via the @code{gcc} command)^^
+with a correct list of object files and library references.
+@code{gnatlink} automatically determines the list of files and
+references for the Ada part of a program. It uses the binder file
+generated by the @command{gnatbind} to determine this list.
+
+@menu
+* Running gnatlink::
+* Switches for gnatlink::
+* Setting Stack Size from gnatlink::
+* Setting Heap Size from gnatlink::
+@end menu
+
+@node Running gnatlink
+@section Running @code{gnatlink}
+
+@noindent
+The form of the @code{gnatlink} command is
+
+@smallexample
+$ gnatlink [@var{switches}] @var{mainprog}[.ali]
+ [@var{non-Ada objects}] [@var{linker options}]
+@end smallexample
+
+@noindent
+The arguments of @code{gnatlink} (switches, main @file{ALI} file,
+non-Ada objects
+or linker options) may be in any order, provided that no non-Ada object may
+be mistaken for a main @file{ALI} file.
+Any file name @file{F} without the @file{.ali}
+extension will be taken as the main @file{ALI} file if a file exists
+whose name is the concatenation of @file{F} and @file{.ali}.
+
+@noindent
+@file{@var{mainprog}.ali} references the ALI file of the main program.
+The @file{.ali} extension of this file can be omitted. From this
+reference, @code{gnatlink} locates the corresponding binder file
+@file{b~@var{mainprog}.adb} and, using the information in this file along
+with the list of non-Ada objects and linker options, constructs a
+linker command file to create the executable.
+
+The arguments other than the @code{gnatlink} switches and the main @file{ALI}
+file are passed to the linker uninterpreted.
+They typically include the names of
+object files for units written in other languages than Ada and any library
+references required to resolve references in any of these foreign language
+units, or in @code{Import} pragmas in any Ada units.
+
+@var{linker options} is an optional list of linker specific
+switches.
+The default linker called by gnatlink is @var{gcc} which in
+turn calls the appropriate system linker.
+Standard options for the linker such as @option{-lmy_lib} or
+@option{-Ldir} can be added as is.
+For options that are not recognized by
+@var{gcc} as linker options, use the @var{gcc} switches @option{-Xlinker} or
+@option{-Wl,}.
+Refer to the GCC documentation for
+details. Here is an example showing how to generate a linker map:
+
+@ifclear vms
+@smallexample
+$ gnatlink my_prog -Wl,-Map,MAPFILE
+@end smallexample
+@end ifclear
+
+@ifset vms
+<<Need example for VMS>>
+@end ifset
+
+Using @var{linker options} it is possible to set the program stack and
+heap size. See @ref{Setting Stack Size from gnatlink}, and
+@ref{Setting Heap Size from gnatlink}.
+
+@code{gnatlink} determines the list of objects required by the Ada
+program and prepends them to the list of objects passed to the linker.
+@code{gnatlink} also gathers any arguments set by the use of
+@code{pragma Linker_Options} and adds them to the list of arguments
+presented to the linker.
+
+@ifset vms
+@code{gnatlink} accepts the following types of extra files on the command
+line: objects (.OBJ), libraries (.OLB), sharable images (.EXE), and
+options files (.OPT). These are recognized and handled according to their
+extension.
+@end ifset
+
+@node Switches for gnatlink
+@section Switches for @code{gnatlink}
+
+@noindent
+The following switches are available with the @code{gnatlink} utility:
+
+@table @option
+@c !sort!
+
+@item ^-A^/BIND_FILE=ADA^
+@cindex @option{^-A^/BIND_FILE=ADA^} (@code{gnatlink})
+The binder has generated code in Ada. This is the default.
+
+@item ^-C^/BIND_FILE=C^
+@cindex @option{^-C^/BIND_FILE=C^} (@code{gnatlink})
+If instead of generating a file in Ada, the binder has generated one in
+C, then the linker needs to know about it. Use this switch to signal
+to @code{gnatlink} that the binder has generated C code rather than
+Ada code.
+
+@item ^-f^/FORCE_OBJECT_FILE_LIST^
+@cindex Command line length
+@cindex @option{^-f^/FORCE_OBJECT_FILE_LIST^} (@code{gnatlink})
+On some targets, the command line length is limited, and @code{gnatlink}
+will generate a separate file for the linker if the list of object files
+is too long.
+The @option{^-f^/FORCE_OBJECT_FILE_LIST^} switch forces this file
+to be generated even if
+the limit is not exceeded. This is useful in some cases to deal with
+special situations where the command line length is exceeded.
+
+@item ^-g^/DEBUG^
+@cindex Debugging information, including
+@cindex @option{^-g^/DEBUG^} (@code{gnatlink})
+The option to include debugging information causes the Ada bind file (in
+other words, @file{b~@var{mainprog}.adb}) to be compiled with
+@option{^-g^/DEBUG^}.
+In addition, the binder does not delete the @file{b~@var{mainprog}.adb},
+@file{b~@var{mainprog}.o} and @file{b~@var{mainprog}.ali} files.
+Without @option{^-g^/DEBUG^}, the binder removes these files by
+default. The same procedure apply if a C bind file was generated using
+@option{^-C^/BIND_FILE=C^} @code{gnatbind} option, in this case the filenames
+are @file{b_@var{mainprog}.c} and @file{b_@var{mainprog}.o}.
+
+@item ^-n^/NOCOMPILE^
+@cindex @option{^-n^/NOCOMPILE^} (@code{gnatlink})
+Do not compile the file generated by the binder. This may be used when
+a link is rerun with different options, but there is no need to recompile
+the binder file.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@code{gnatlink})
+Causes additional information to be output, including a full list of the
+included object files. This switch option is most useful when you want
+to see what set of object files are being used in the link step.
+
+@item ^-v -v^/VERBOSE/VERBOSE^
+@cindex @option{^-v -v^/VERBOSE/VERBOSE^} (@code{gnatlink})
+Very verbose mode. Requests that the compiler operate in verbose mode when
+it compiles the binder file, and that the system linker run in verbose mode.
+
+@item ^-o ^/EXECUTABLE=^@var{exec-name}
+@cindex @option{^-o^/EXECUTABLE^} (@code{gnatlink})
+@var{exec-name} specifies an alternate name for the generated
+executable program. If this switch is omitted, the executable has the same
+name as the main unit. For example, @code{gnatlink try.ali} creates
+an executable called @file{^try^TRY.EXE^}.
+
+@ifclear vms
+@item -b @var{target}
+@cindex @option{-b} (@code{gnatlink})
+Compile your program to run on @var{target}, which is the name of a
+system configuration. You must have a GNAT cross-compiler built if
+@var{target} is not the same as your host system.
+
+@item -B@var{dir}
+@cindex @option{-B} (@code{gnatlink})
+Load compiler executables (for example, @code{gnat1}, the Ada compiler)
+from @var{dir} instead of the default location. Only use this switch
+when multiple versions of the GNAT compiler are available. See the
+@code{gcc} manual page for further details. You would normally use the
+@option{-b} or @option{-V} switch instead.
+
+@item --GCC=@var{compiler_name}
+@cindex @option{--GCC=compiler_name} (@code{gnatlink})
+Program used for compiling the binder file. The default is
+`@code{gcc}'. You need to use quotes around @var{compiler_name} if
+@code{compiler_name} contains spaces or other separator characters. As
+an example @option{--GCC="foo -x -y"} will instruct @code{gnatlink} to use
+@code{foo -x -y} as your compiler. Note that switch @option{-c} is always
+inserted after your command name. Thus in the above example the compiler
+command that will be used by @code{gnatlink} will be @code{foo -c -x -y}.
+If several @option{--GCC=compiler_name} are used, only the last
+@var{compiler_name} is taken into account. However, all the additional
+switches are also taken into account. Thus,
+@option{--GCC="foo -x -y" --GCC="bar -z -t"} is equivalent to
+@option{--GCC="bar -x -y -z -t"}.
+
+@item --LINK=@var{name}
+@cindex @option{--LINK=} (@code{gnatlink})
+@var{name} is the name of the linker to be invoked. This is especially
+useful in mixed language programs since languages such as C++ require
+their own linker to be used. When this switch is omitted, the default
+name for the linker is (@file{gcc}). When this switch is used, the
+specified linker is called instead of (@file{gcc}) with exactly the same
+parameters that would have been passed to (@file{gcc}) so if the desired
+linker requires different parameters it is necessary to use a wrapper
+script that massages the parameters before invoking the real linker. It
+may be useful to control the exact invocation by using the verbose
+switch.
+
+@end ifclear
+
+@ifset vms
+@item /DEBUG=TRACEBACK
+@cindex @code{/DEBUG=TRACEBACK} (@code{gnatlink})
+This qualifier causes sufficient information to be included in the
+executable file to allow a traceback, but does not include the full
+symbol information needed by the debugger.
+
+@item /IDENTIFICATION="<string>"
+@code{"<string>"} specifies the string to be stored in the image file
+identification field in the image header.
+It overrides any pragma @code{Ident} specified string.
+
+@item /NOINHIBIT-EXEC
+Generate the executable file even if there are linker warnings.
+
+@item /NOSTART_FILES
+Don't link in the object file containing the ``main'' transfer address.
+Used when linking with a foreign language main program compiled with a
+Digital compiler.
+
+@item /STATIC
+Prefer linking with object libraries over sharable images, even without
+/DEBUG.
+@end ifset
+
+@end table
+
+@node Setting Stack Size from gnatlink
+@section Setting Stack Size from @code{gnatlink}
+
+@noindent
+Under Windows systems, it is possible to specify the program stack size from
+@code{gnatlink} using either:
+
+@itemize @bullet
+
+@item using @option{-Xlinker} linker option
+
+@smallexample
+$ gnatlink hello -Xlinker --stack=0x10000,0x1000
+@end smallexample
+
+This sets the stack reserve size to 0x10000 bytes and the stack commit
+size to 0x1000 bytes.
+
+@item using @option{-Wl} linker option
+
+@smallexample
+$ gnatlink hello -Wl,--stack=0x1000000
+@end smallexample
+
+This sets the stack reserve size to 0x1000000 bytes. Note that with
+@option{-Wl} option it is not possible to set the stack commit size
+because the coma is a separator for this option.
+
+@end itemize
+
+@node Setting Heap Size from gnatlink
+@section Setting Heap Size from @code{gnatlink}
+
+@noindent
+Under Windows systems, it is possible to specify the program heap size from
+@code{gnatlink} using either:
+
+@itemize @bullet
+
+@item using @option{-Xlinker} linker option
+
+@smallexample
+$ gnatlink hello -Xlinker --heap=0x10000,0x1000
+@end smallexample
+
+This sets the heap reserve size to 0x10000 bytes and the heap commit
+size to 0x1000 bytes.
+
+@item using @option{-Wl} linker option
+
+@smallexample
+$ gnatlink hello -Wl,--heap=0x1000000
+@end smallexample
+
+This sets the heap reserve size to 0x1000000 bytes. Note that with
+@option{-Wl} option it is not possible to set the heap commit size
+because the coma is a separator for this option.
+
+@end itemize
+
+@node The GNAT Make Program gnatmake
+@chapter The GNAT Make Program @code{gnatmake}
+@findex gnatmake
+
+@menu
+* Running gnatmake::
+* Switches for gnatmake::
+* Mode Switches for gnatmake::
+* Notes on the Command Line::
+* How gnatmake Works::
+* Examples of gnatmake Usage::
+@end menu
+@noindent
+A typical development cycle when working on an Ada program consists of
+the following steps:
+
+@enumerate
+@item
+Edit some sources to fix bugs.
+
+@item
+Add enhancements.
+
+@item
+Compile all sources affected.
+
+@item
+Rebind and relink.
+
+@item
+Test.
+@end enumerate
+
+@noindent
+The third step can be tricky, because not only do the modified files
+@cindex Dependency rules
+have to be compiled, but any files depending on these files must also be
+recompiled. The dependency rules in Ada can be quite complex, especially
+in the presence of overloading, @code{use} clauses, generics and inlined
+subprograms.
+
+@code{gnatmake} automatically takes care of the third and fourth steps
+of this process. It determines which sources need to be compiled,
+compiles them, and binds and links the resulting object files.
+
+Unlike some other Ada make programs, the dependencies are always
+accurately recomputed from the new sources. The source based approach of
+the GNAT compilation model makes this possible. This means that if
+changes to the source program cause corresponding changes in
+dependencies, they will always be tracked exactly correctly by
+@code{gnatmake}.
+
+@node Running gnatmake
+@section Running @code{gnatmake}
+
+@noindent
+The usual form of the @code{gnatmake} command is
+
+@smallexample
+$ gnatmake [@var{switches}] @var{file_name}
+ [@var{file_names}] [@var{mode_switches}]
+@end smallexample
+
+@noindent
+The only required argument is one @var{file_name}, which specifies
+a compilation unit that is a main program. Several @var{file_names} can be
+specified: this will result in several executables being built.
+If @code{switches} are present, they can be placed before the first
+@var{file_name}, between @var{file_names} or after the last @var{file_name}.
+If @var{mode_switches} are present, they must always be placed after
+the last @var{file_name} and all @code{switches}.
+
+If you are using standard file extensions (.adb and .ads), then the
+extension may be omitted from the @var{file_name} arguments. However, if
+you are using non-standard extensions, then it is required that the
+extension be given. A relative or absolute directory path can be
+specified in a @var{file_name}, in which case, the input source file will
+be searched for in the specified directory only. Otherwise, the input
+source file will first be searched in the directory where
+@code{gnatmake} was invoked and if it is not found, it will be search on
+the source path of the compiler as described in
+@ref{Search Paths and the Run-Time Library (RTL)}.
+
+All @code{gnatmake} output (except when you specify
+@option{^-M^/DEPENDENCIES_LIST^}) is to
+@file{stderr}. The output produced by the
+@option{^-M^/DEPENDENCIES_LIST^} switch is send to
+@file{stdout}.
+
+@node Switches for gnatmake
+@section Switches for @code{gnatmake}
+
+@noindent
+You may specify any of the following switches to @code{gnatmake}:
+
+@table @option
+@c !sort!
+@ifclear vms
+@item --GCC=@var{compiler_name}
+@cindex @option{--GCC=compiler_name} (@code{gnatmake})
+Program used for compiling. The default is `@code{gcc}'. You need to use
+quotes around @var{compiler_name} if @code{compiler_name} contains
+spaces or other separator characters. As an example @option{--GCC="foo -x
+-y"} will instruct @code{gnatmake} to use @code{foo -x -y} as your
+compiler. Note that switch @option{-c} is always inserted after your
+command name. Thus in the above example the compiler command that will
+be used by @code{gnatmake} will be @code{foo -c -x -y}.
+If several @option{--GCC=compiler_name} are used, only the last
+@var{compiler_name} is taken into account. However, all the additional
+switches are also taken into account. Thus,
+@option{--GCC="foo -x -y" --GCC="bar -z -t"} is equivalent to
+@option{--GCC="bar -x -y -z -t"}.
+
+@item --GNATBIND=@var{binder_name}
+@cindex @option{--GNATBIND=binder_name} (@code{gnatmake})
+Program used for binding. The default is `@code{gnatbind}'. You need to
+use quotes around @var{binder_name} if @var{binder_name} contains spaces
+or other separator characters. As an example @option{--GNATBIND="bar -x
+-y"} will instruct @code{gnatmake} to use @code{bar -x -y} as your
+binder. Binder switches that are normally appended by @code{gnatmake} to
+`@code{gnatbind}' are now appended to the end of @code{bar -x -y}.
+
+@item --GNATLINK=@var{linker_name}
+@cindex @option{--GNATLINK=linker_name} (@code{gnatmake})
+Program used for linking. The default is `@code{gnatlink}'. You need to
+use quotes around @var{linker_name} if @var{linker_name} contains spaces
+or other separator characters. As an example @option{--GNATLINK="lan -x
+-y"} will instruct @code{gnatmake} to use @code{lan -x -y} as your
+linker. Linker switches that are normally appended by @code{gnatmake} to
+`@code{gnatlink}' are now appended to the end of @code{lan -x -y}.
+
+@end ifclear
+
+@item ^-a^/ALL_FILES^
+@cindex @option{^-a^/ALL_FILES^} (@code{gnatmake})
+Consider all files in the make process, even the GNAT internal system
+files (for example, the predefined Ada library files), as well as any
+locked files. Locked files are files whose ALI file is write-protected.
+By default,
+@code{gnatmake} does not check these files,
+because the assumption is that the GNAT internal files are properly up
+to date, and also that any write protected ALI files have been properly
+installed. Note that if there is an installation problem, such that one
+of these files is not up to date, it will be properly caught by the
+binder.
+You may have to specify this switch if you are working on GNAT
+itself. The switch @option{^-a^/ALL_FILES^} is also useful
+in conjunction with @option{^-f^/FORCE_COMPILE^}
+if you need to recompile an entire application,
+including run-time files, using special configuration pragmas,
+such as a @code{Normalize_Scalars} pragma.
+
+By default
+@code{gnatmake ^-a^/ALL_FILES^} compiles all GNAT
+internal files with
+@ifclear vms
+@code{gcc -c -gnatpg} rather than @code{gcc -c}.
+@end ifclear
+@ifset vms
+the @code{/CHECKS=SUPPRESS_ALL /STYLE_CHECKS=GNAT} switch.
+@end ifset
+
+@item ^-b^/ACTIONS=BIND^
+@cindex @option{^-b^/ACTIONS=BIND^} (@code{gnatmake})
+Bind only. Can be combined with @option{^-c^/ACTIONS=COMPILE^} to do
+compilation and binding, but no link.
+Can be combined with @option{^-l^/ACTIONS=LINK^}
+to do binding and linking. When not combined with
+@option{^-c^/ACTIONS=COMPILE^}
+all the units in the closure of the main program must have been previously
+compiled and must be up to date. The root unit specified by @var{file_name}
+may be given without extension, with the source extension or, if no GNAT
+Project File is specified, with the ALI file extension.
+
+@item ^-c^/ACTIONS=COMPILE^
+@cindex @option{^-c^/ACTIONS=COMPILE^} (@code{gnatmake})
+Compile only. Do not perform binding, except when @option{^-b^/ACTIONS=BIND^}
+is also specified. Do not perform linking, except if both
+@option{^-b^/ACTIONS=BIND^} and
+ @option{^-l^/ACTIONS=LINK^} are also specified.
+If the root unit specified by @var{file_name} is not a main unit, this is the
+default. Otherwise @code{gnatmake} will attempt binding and linking
+unless all objects are up to date and the executable is more recent than
+the objects.
+
+@item ^-C^/MAPPING^
+@cindex @option{^-C^/MAPPING^} (@code{gnatmake})
+Use a temporary mapping file. A mapping file is a way to communicate to the
+compiler two mappings: from unit names to file names (without any directory
+information) and from file names to path names (with full directory
+information). These mappings are used by the compiler to short-circuit the path
+search. When @code{gnatmake} is invoked with this switch, it will create
+a temporary mapping file, initially populated by the project manager,
+if @option{^-P^/PROJECT_FILE^} is used, otherwise initially empty.
+Each invocation of the compiler will add the newly accessed sources to the
+mapping file. This will improve the source search during the next invocation
+of the compiler.
+
+@item ^-C=^/USE_MAPPING_FILE=^@var{file}
+@cindex @option{^-C=^/USE_MAPPING^} (@code{gnatmake})
+Use a specific mapping file. The file, specified as a path name (absolute or
+relative) by this switch, should already exist, otherwise the switch is
+ineffective. The specified mapping file will be communicated to the compiler.
+This switch is not compatible with a project file
+(^-P^/PROJECT_FILE=^@var{file}) or with multiple compiling processes
+(^-j^/PROCESSES=^nnn, when nnn is greater than 1).
+
+@item ^-D ^/DIRECTORY_OBJECTS=^@var{dir}
+@cindex @option{^-D^/DIRECTORY_OBJECTS^} (@code{gnatmake})
+Put all object files and ALI file in directory @var{dir}.
+If the @option{^-D^/DIRECTORY_OBJECTS^} switch is not used, all object files
+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
+files may be up to date, but don't recompile predefined or GNAT internal
+files or locked files (files with a write-protected ALI file),
+unless the @option{^-a^/ALL_FILES^} switch is also specified.
+
+@item ^-F^/FULL_PATH_IN_BRIEF_MESSAGES^
+@cindex @option{^-F^/FULL_PATH_IN_BRIEF_MESSAGES^} (@code{gnatmake})
+When using project files, if some errors or warnings are detected during
+parsing and verbose mode is not in effect (no use of switch
+^-v^/VERBOSE^), then error lines start with the full path name of the project
+file, rather than its simple file name.
+
+@item ^-i^/IN_PLACE^
+@cindex @option{^-i^/IN_PLACE^} (@code{gnatmake})
+In normal mode, @code{gnatmake} compiles all object files and ALI files
+into the current directory. If the @option{^-i^/IN_PLACE^} switch is used,
+then instead object files and ALI files that already exist are overwritten
+in place. This means that once a large project is organized into separate
+directories in the desired manner, then @code{gnatmake} will automatically
+maintain and update this organization. If no ALI files are found on the
+Ada object path (@ref{Search Paths and the Run-Time Library (RTL)}),
+the new object and ALI files are created in the
+directory containing the source being compiled. If another organization
+is desired, where objects and sources are kept in different directories,
+a useful technique is to create dummy ALI files in the desired directories.
+When detecting such a dummy file, @code{gnatmake} will be forced to recompile
+the corresponding source file, and it will be put the resulting object
+and ALI files in the directory where it found the dummy file.
+
+@item ^-j^/PROCESSES=^@var{n}
+@cindex @option{^-j^/PROCESSES^} (@code{gnatmake})
+@cindex Parallel make
+Use @var{n} processes to carry out the (re)compilations. On a
+multiprocessor machine compilations will occur in parallel. In the
+event of compilation errors, messages from various compilations might
+get interspersed (but @code{gnatmake} will give you the full ordered
+list of failing compiles at the end). If this is problematic, rerun
+the make process with n set to 1 to get a clean list of messages.
+
+@item ^-k^/CONTINUE_ON_ERROR^
+@cindex @option{^-k^/CONTINUE_ON_ERROR^} (@code{gnatmake})
+Keep going. Continue as much as possible after a compilation error. To
+ease the programmer's task in case of compilation errors, the list of
+sources for which the compile fails is given when @code{gnatmake}
+terminates.
+
+If @code{gnatmake} is invoked with several @file{file_names} and with this
+switch, if there are compilation errors when building an executable,
+@code{gnatmake} will not attempt to build the following executables.
+
+@item ^-l^/ACTIONS=LINK^
+@cindex @option{^-l^/ACTIONS=LINK^} (@code{gnatmake})
+Link only. Can be combined with @option{^-b^/ACTIONS=BIND^} to binding
+and linking. Linking will not be performed if combined with
+@option{^-c^/ACTIONS=COMPILE^}
+but not with @option{^-b^/ACTIONS=BIND^}.
+When not combined with @option{^-b^/ACTIONS=BIND^}
+all the units in the closure of the main program must have been previously
+compiled and must be up to date, and the main program need to have been bound.
+The root unit specified by @var{file_name}
+may be given without extension, with the source extension or, if no GNAT
+Project File is specified, with the ALI file extension.
+
+@item ^-m^/MINIMAL_RECOMPILATION^
+@cindex @option{^-m^/MINIMAL_RECOMPILATION^} (@code{gnatmake})
+Specifies that the minimum necessary amount of recompilations
+be performed. In this mode @code{gnatmake} ignores time
+stamp differences when the only
+modifications to a source file consist in adding/removing comments,
+empty lines, spaces or tabs. This means that if you have changed the
+comments in a source file or have simply reformatted it, using this
+switch will tell gnatmake not to recompile files that depend on it
+(provided other sources on which these files depend have undergone no
+semantic modifications). Note that the debugging information may be
+out of date with respect to the sources if the @option{-m} switch causes
+a compilation to be switched, so the use of this switch represents a
+trade-off between compilation time and accurate debugging information.
+
+@item ^-M^/DEPENDENCIES_LIST^
+@cindex Dependencies, producing list
+@cindex @option{^-M^/DEPENDENCIES_LIST^} (@code{gnatmake})
+Check if all objects are up to date. If they are, output the object
+dependences to @file{stdout} in a form that can be directly exploited in
+a @file{Makefile}. By default, each source file is prefixed with its
+(relative or absolute) directory name. This name is whatever you
+specified in the various @option{^-aI^/SOURCE_SEARCH^}
+and @option{^-I^/SEARCH^} switches. If you use
+@code{gnatmake ^-M^/DEPENDENCIES_LIST^}
+@option{^-q^/QUIET^}
+(see below), only the source file names,
+without relative paths, are output. If you just specify the
+@option{^-M^/DEPENDENCIES_LIST^}
+switch, dependencies of the GNAT internal system files are omitted. This
+is typically what you want. If you also specify
+the @option{^-a^/ALL_FILES^} switch,
+dependencies of the GNAT internal files are also listed. Note that
+dependencies of the objects in external Ada libraries (see switch
+@option{^-aL^/SKIP_MISSING=^}@var{dir} in the following list)
+are never reported.
+
+@item ^-n^/DO_OBJECT_CHECK^
+@cindex @option{^-n^/DO_OBJECT_CHECK^} (@code{gnatmake})
+Don't compile, bind, or link. Checks if all objects are up to date.
+If they are not, the full name of the first file that needs to be
+recompiled is printed.
+Repeated use of this option, followed by compiling the indicated source
+file, will eventually result in recompiling all required units.
+
+@item ^-o ^/EXECUTABLE=^@var{exec_name}
+@cindex @option{^-o^/EXECUTABLE^} (@code{gnatmake})
+Output executable name. The name of the final executable program will be
+@var{exec_name}. If the @option{^-o^/EXECUTABLE^} switch is omitted the default
+name for the executable will be the name of the input file in appropriate form
+for an executable file on the host system.
+
+This switch cannot be used when invoking @code{gnatmake} with several
+@file{file_names}.
+
+@item ^-P^/PROJECT_FILE=^@var{project}
+@cindex @option{^-P^/PROJECT_FILE^} (@code{gnatmake})
+Use project file @var{project}. Only one such switch can be used.
+See @ref{gnatmake and Project Files}.
+
+@item ^-q^/QUIET^
+@cindex @option{^-q^/QUIET^} (@code{gnatmake})
+Quiet. When this flag is not set, the commands carried out by
+@code{gnatmake} are displayed.
+
+@item ^-s^/SWITCH_CHECK/^
+@cindex @option{^-s^/SWITCH_CHECK^} (@code{gnatmake})
+Recompile if compiler switches have changed since last compilation.
+All compiler switches but -I and -o are taken into account in the
+following way:
+orders between different ``first letter'' switches are ignored, but
+orders between same switches are taken into account. For example,
+@option{-O -O2} is different than @option{-O2 -O}, but @option{-g -O}
+is equivalent to @option{-O -g}.
+
+This switch is recommended when Integrated Preprocessing is used.
+
+@item ^-u^/UNIQUE^
+@cindex @option{^-u^/UNIQUE^} (@code{gnatmake})
+Unique. Recompile at most the main files. It implies -c. Combined with
+-f, it is equivalent to calling the compiler directly. Note that using
+^-u^/UNIQUE^ with a project file and no main has a special meaning
+(see @ref{Project Files and Main Subprograms}).
+
+@item ^-U^/ALL_PROJECTS^
+@cindex @option{^-U^/ALL_PROJECTS^} (@code{gnatmake})
+When used without a project file or with one or several mains on the command
+line, is equivalent to ^-u^/UNIQUE^. When used with a project file and no main
+on the command line, all sources of all project files are checked and compiled
+if not up to date, and libraries are rebuilt, if necessary.
+
+@item ^-v^/REASONS^
+@cindex @option{^-v^/REASONS^} (@code{gnatmake})
+Verbose. Displays the reason for all recompilations @code{gnatmake}
+decides are necessary.
+
+@item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}
+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
+@code{external(name)} when parsing the project file.
+See @ref{Switches Related to Project Files}.
+
+@item ^-z^/NOMAIN^
+@cindex @option{^-z^/NOMAIN^} (@code{gnatmake})
+No main subprogram. Bind and link the program even if the unit name
+given on the command line is a package name. The resulting executable
+will execute the elaboration routines of the package and its closure,
+then the finalization routines.
+
+@item ^-g^/DEBUG^
+@cindex @option{^-g^/DEBUG^} (@code{gnatmake})
+Enable debugging. This switch is simply passed to the compiler and to the
+linker.
+
+@end table
+
+@table @asis
+@item @code{gcc} @asis{switches}
+@ifclear vms
+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}
+but is recognizable as a valid qualifier for @code{GNAT COMPILE} is
+automatically treated as a compiler switch, and passed on to all
+compilations that are carried out.
+@end ifset
+@end table
+
+@noindent
+Source and library search path switches:
+
+@table @option
+@c !sort!
+@item ^-aI^/SOURCE_SEARCH=^@var{dir}
+@cindex @option{^-aI^/SOURCE_SEARCH^} (@code{gnatmake})
+When looking for source files also look in directory @var{dir}.
+The order in which source files search is undertaken is
+described in @ref{Search Paths and the Run-Time Library (RTL)}.
+
+@item ^-aL^/SKIP_MISSING=^@var{dir}
+@cindex @option{^-aL^/SKIP_MISSING^} (@code{gnatmake})
+Consider @var{dir} as being an externally provided Ada library.
+Instructs @code{gnatmake} to skip compilation units whose @file{.ALI}
+files have been located in directory @var{dir}. This allows you to have
+missing bodies for the units in @var{dir} and to ignore out of date bodies
+for the same units. You still need to specify
+the location of the specs for these units by using the switches
+@option{^-aI^/SOURCE_SEARCH=^@var{dir}}
+or @option{^-I^/SEARCH=^@var{dir}}.
+Note: this switch is provided for compatibility with previous versions
+of @code{gnatmake}. The easier method of causing standard libraries
+to be excluded from consideration is to write-protect the corresponding
+ALI files.
+
+@item ^-aO^/OBJECT_SEARCH=^@var{dir}
+@cindex @option{^-aO^/OBJECT_SEARCH^} (@code{gnatmake})
+When searching for library and object files, look in directory
+@var{dir}. The order in which library files are searched is described in
+@ref{Search Paths for gnatbind}.
+
+@item ^-A^/CONDITIONAL_SOURCE_SEARCH=^@var{dir}
+@cindex Search paths, for @code{gnatmake}
+@cindex @option{^-A^/CONDITIONAL_SOURCE_SEARCH^} (@code{gnatmake})
+Equivalent to @option{^-aL^/SKIP_MISSING=^@var{dir}
+^-aI^/SOURCE_SEARCH=^@var{dir}}.
+
+@item ^-I^/SEARCH=^@var{dir}
+@cindex @option{^-I^/SEARCH^} (@code{gnatmake})
+Equivalent to @option{^-aO^/OBJECT_SEARCH=^@var{dir}
+^-aI^/SOURCE_SEARCH=^@var{dir}}.
+
+@item ^-I-^/NOCURRENT_DIRECTORY^
+@cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatmake})
+@cindex Source files, suppressing search
+Do not look for source files in the directory containing the source
+file named in the command line.
+Do not look for ALI or object files in the directory
+where @code{gnatmake} was invoked.
+
+@item ^-L^/LIBRARY_SEARCH=^@var{dir}
+@cindex @option{^-L^/LIBRARY_SEARCH^} (@code{gnatmake})
+@cindex Linker libraries
+Add directory @var{dir} to the list of directories in which the linker
+will search for libraries. This is equivalent to
+@option{-largs ^-L^/LIBRARY_SEARCH=^}@var{dir}.
+@ifclear vms
+Furthermore, under Windows, the sources pointed to by the libraries path
+set in the registry are not searched for.
+@end ifclear
+
+@item -nostdinc
+@cindex @option{-nostdinc} (@code{gnatmake})
+Do not look for source files in the system default directory.
+
+@item -nostdlib
+@cindex @option{-nostdlib} (@code{gnatmake})
+Do not look for library files in the system default directory.
+
+@item --RTS=@var{rts-path}
+@cindex @option{--RTS} (@code{gnatmake})
+Specifies the default location of the runtime library. GNAT looks for the
+runtime
+in the following directories, and stops as soon as a valid runtime is found
+(@file{adainclude} or @file{ada_source_path}, and @file{adalib} or
+@file{ada_object_path} present):
+
+@itemize @bullet
+@item <current directory>/$rts_path
+
+@item <default-search-dir>/$rts_path
+
+@item <default-search-dir>/rts-$rts_path
+@end itemize
+
+@noindent
+The selected path is handled like a normal RTS path.
+
+@end table
+
+@node Mode Switches for gnatmake
+@section Mode Switches for @code{gnatmake}
+
+@noindent
+The mode switches (referred to as @code{mode_switches}) allow the
+inclusion of switches that are to be passed to the compiler itself, the
+binder or the linker. The effect of a mode switch is to cause all
+subsequent switches up to the end of the switch list, or up to the next
+mode switch, to be interpreted as switches to be passed on to the
+designated component of GNAT.
+
+@table @option
+@c !sort!
+@item -cargs @var{switches}
+@cindex @option{-cargs} (@code{gnatmake})
+Compiler switches. Here @var{switches} is a list of switches
+that are valid switches for @code{gcc}. They will be passed on to
+all compile steps performed by @code{gnatmake}.
+
+@item -bargs @var{switches}
+@cindex @option{-bargs} (@code{gnatmake})
+Binder switches. Here @var{switches} is a list of switches
+that are valid switches for @code{gnatbind}. They will be passed on to
+all bind steps performed by @code{gnatmake}.
+
+@item -largs @var{switches}
+@cindex @option{-largs} (@code{gnatmake})
+Linker switches. Here @var{switches} is a list of switches
+that are valid switches for @code{gnatlink}. They will be passed on to
+all link steps performed by @code{gnatmake}.
+
+@item -margs @var{switches}
+@cindex @option{-margs} (@code{gnatmake})
+Make switches. The switches are directly interpreted by @code{gnatmake},
+regardless of any previous occurrence of @option{-cargs}, @option{-bargs}
+or @option{-largs}.
+@end table
+
+@node Notes on the Command Line
+@section Notes on the Command Line
+
+@noindent
+This section contains some additional useful notes on the operation
+of the @code{gnatmake} command.
+
+@itemize @bullet
+@item
+@cindex Recompilation, by @code{gnatmake}
+If @code{gnatmake} finds no ALI files, it recompiles the main program
+and all other units required by the main program.
+This means that @code{gnatmake}
+can be used for the initial compile, as well as during subsequent steps of
+the development cycle.
+
+@item
+If you enter @code{gnatmake @var{file}.adb}, where @file{@var{file}.adb}
+is a subunit or body of a generic unit, @code{gnatmake} recompiles
+@file{@var{file}.adb} (because it finds no ALI) and stops, issuing a
+warning.
+
+@item
+In @code{gnatmake} the switch @option{^-I^/SEARCH^}
+is used to specify both source and
+library file paths. Use @option{^-aI^/SOURCE_SEARCH^}
+instead if you just want to specify
+source paths only and @option{^-aO^/OBJECT_SEARCH^}
+if you want to specify library paths
+only.
+
+@item
+@code{gnatmake} examines both an ALI file and its corresponding object file
+for consistency. If an ALI is more recent than its corresponding object,
+or if the object file is missing, the corresponding source will be recompiled.
+Note that @code{gnatmake} expects an ALI and the corresponding object file
+to be in the same directory.
+
+@item
+@code{gnatmake} will ignore any files whose ALI file is write-protected.
+This may conveniently be used to exclude standard libraries from
+consideration and in particular it means that the use of the
+@option{^-f^/FORCE_COMPILE^} switch will not recompile these files
+unless @option{^-a^/ALL_FILES^} is also specified.
+
+@item
+@code{gnatmake} has been designed to make the use of Ada libraries
+particularly convenient. Assume you have an Ada library organized
+as follows: @i{^obj-dir^[OBJ_DIR]^} contains the objects and ALI files for
+of your Ada compilation units,
+whereas @i{^include-dir^[INCLUDE_DIR]^} contains the
+specs of these units, but no bodies. Then to compile a unit
+stored in @code{main.adb}, which uses this Ada library you would just type
+
+@smallexample
+@ifclear vms
+$ gnatmake -aI@var{include-dir} -aL@var{obj-dir} main
+@end ifclear
+@ifset vms
+$ gnatmake /SOURCE_SEARCH=@i{[INCLUDE_DIR]}
+ /SKIP_MISSING=@i{[OBJ_DIR]} main
+@end ifset
+@end smallexample
+
+@item
+Using @code{gnatmake} along with the
+@option{^-m (minimal recompilation)^/MINIMAL_RECOMPILATION^}
+switch provides a mechanism for avoiding unnecessary rcompilations. Using
+this switch,
+you can update the comments/format of your
+source files without having to recompile everything. Note, however, that
+adding or deleting lines in a source files may render its debugging
+info obsolete. If the file in question is a spec, the impact is rather
+limited, as that debugging info will only be useful during the
+elaboration phase of your program. For bodies the impact can be more
+significant. In all events, your debugger will warn you if a source file
+is more recent than the corresponding object, and alert you to the fact
+that the debugging information may be out of date.
+@end itemize
+
+@node How gnatmake Works
+@section How @code{gnatmake} Works
+
+@noindent
+Generally @code{gnatmake} automatically performs all necessary
+recompilations and you don't need to worry about how it works. However,
+it may be useful to have some basic understanding of the @code{gnatmake}
+approach and in particular to understand how it uses the results of
+previous compilations without incorrectly depending on them.
+
+First a definition: an object file is considered @dfn{up to date} if the
+corresponding ALI file exists and its time stamp predates that of the
+object file and if all the source files listed in the
+dependency section of this ALI file have time stamps matching those in
+the ALI file. This means that neither the source file itself nor any
+files that it depends on have been modified, and hence there is no need
+to recompile this file.
+
+@code{gnatmake} works by first checking if the specified main unit is up
+to date. If so, no compilations are required for the main unit. If not,
+@code{gnatmake} compiles the main program to build a new ALI file that
+reflects the latest sources. Then the ALI file of the main unit is
+examined to find all the source files on which the main program depends,
+and @code{gnatmake} recursively applies the above procedure on all these files.
+
+This process ensures that @code{gnatmake} only trusts the dependencies
+in an existing ALI file if they are known to be correct. Otherwise it
+always recompiles to determine a new, guaranteed accurate set of
+dependencies. As a result the program is compiled ``upside down'' from what may
+be more familiar as the required order of compilation in some other Ada
+systems. In particular, clients are compiled before the units on which
+they depend. The ability of GNAT to compile in any order is critical in
+allowing an order of compilation to be chosen that guarantees that
+@code{gnatmake} will recompute a correct set of new dependencies if
+necessary.
+
+When invoking @code{gnatmake} with several @var{file_names}, if a unit is
+imported by several of the executables, it will be recompiled at most once.
+
+Note: when using non-standard naming conventions
+(See @ref{Using Other File Names}), changing through a configuration pragmas
+file the version of a source and invoking @code{gnatmake} to recompile may
+have no effect, if the previous version of the source is still accessible
+by @code{gnatmake}. It may be necessary to use the switch ^-f^/FORCE_COMPILE^.
+
+@node Examples of gnatmake Usage
+@section Examples of @code{gnatmake} Usage
+
+@table @code
+@item gnatmake hello.adb
+Compile all files necessary to bind and link the main program
+@file{hello.adb} (containing unit @code{Hello}) and bind and link the
+resulting object files to generate an executable file @file{^hello^HELLO.EXE^}.
+
+@item gnatmake main1 main2 main3
+Compile all files necessary to bind and link the main programs
+@file{main1.adb} (containing unit @code{Main1}), @file{main2.adb}
+(containing unit @code{Main2}) and @file{main3.adb}
+(containing unit @code{Main3}) and bind and link the resulting object files
+to generate three executable files @file{^main1^MAIN1.EXE^},
+@file{^main2^MAIN2.EXE^}
+and @file{^main3^MAIN3.EXE^}.
+
+@ifclear vms
+@item gnatmake -q Main_Unit -cargs -O2 -bargs -l
+@end ifclear
+
+@ifset vms
+@item gnatmake Main_Unit /QUIET
+ /COMPILER_QUALIFIERS /OPTIMIZE=ALL
+ /BINDER_QUALIFIERS /ORDER_OF_ELABORATION
+@end ifset
+Compile all files necessary to bind and link the main program unit
+@code{Main_Unit} (from file @file{main_unit.adb}). All compilations will
+be done with optimization level 2 and the order of elaboration will be
+listed by the binder. @code{gnatmake} will operate in quiet mode, not
+displaying commands it is executing.
+@end table
+
+
+@c *************************
+@node Improving Performance
+@chapter Improving Performance
+@cindex Improving performance
+
+@noindent
+This chapter presents several topics related to program performance.
+It first describes some of the tradeoffs that need to be considered
+and some of the techniques for making your program run faster.
+It then documents the @command{gnatelim} tool, which can reduce
+the size of program executables.
+
+@ifnottex
+@menu
+* Performance Considerations::
+* Reducing the Size of Ada Executables with gnatelim::
+@end menu
+@end ifnottex
+
+
+@c *****************************
+@node Performance Considerations
+@section Performance Considerations
+
+@noindent
+The GNAT system provides a number of options that allow a trade-off
+between
+
+@itemize @bullet
+@item
+performance of the generated code
+
+@item
+speed of compilation
+
+@item
+minimization of dependences and recompilation
+
+@item
+the degree of run-time checking.
+@end itemize
+
+@noindent
+The defaults (if no options are selected) aim at improving the speed
+of compilation and minimizing dependences, at the expense of performance
+of the generated code:
+
+@itemize @bullet
+@item
+no optimization
+
+@item
+no inlining of subprogram calls
+
+@item
+all run-time checks enabled except overflow and elaboration checks
+@end itemize
+
+@noindent
+These options are suitable for most program development purposes. This
+chapter describes how you can modify these choices, and also provides
+some guidelines on debugging optimized code.
+
+@menu
+* Controlling Run-Time Checks::
+* Use of Restrictions::
+* Optimization Levels::
+* Debugging Optimized Code::
+* Inlining of Subprograms::
+* Optimization and Strict Aliasing::
+@ifset vms
+* Coverage Analysis::
+@end ifset
+@end menu
+
+@node Controlling Run-Time Checks
+@subsection Controlling Run-Time Checks
+
+@noindent
+By default, GNAT generates all run-time checks, except arithmetic overflow
+checking for integer operations and checks for access before elaboration on
+subprogram calls. The latter are not required in default mode, because all
+necessary checking is done at compile time.
+@cindex @option{-gnatp} (@code{gcc})
+@cindex @option{-gnato} (@code{gcc})
+Two gnat switches, @option{-gnatp} and @option{-gnato} allow this default to
+be modified. @xref{Run-Time Checks}.
+
+Our experience is that the default is suitable for most development
+purposes.
+
+We treat integer overflow specially because these
+are quite expensive and in our experience are not as important as other
+run-time checks in the development process. Note that division by zero
+is not considered an overflow check, and divide by zero checks are
+generated where required by default.
+
+Elaboration checks are off by default, and also not needed by default, since
+GNAT uses a static elaboration analysis approach that avoids the need for
+run-time checking. This manual contains a full chapter discussing the issue
+of elaboration checks, and if the default is not satisfactory for your use,
+you should read this chapter.
+
+For validity checks, the minimal checks required by the Ada Reference
+Manual (for case statements and assignments to array elements) are on
+by default. These can be suppressed by use of the @option{-gnatVn} switch.
+Note that in Ada 83, there were no validity checks, so if the Ada 83 mode
+is acceptable (or when comparing GNAT performance with an Ada 83 compiler),
+it may be reasonable to routinely use @option{-gnatVn}. Validity checks
+are also suppressed entirely if @option{-gnatp} is used.
+
+@cindex Overflow checks
+@cindex Checks, overflow
+@findex Suppress
+@findex Unsuppress
+@cindex pragma Suppress
+@cindex pragma Unsuppress
+Note that the setting of the switches controls the default setting of
+the checks. They may be modified using either @code{pragma Suppress} (to
+remove checks) or @code{pragma Unsuppress} (to add back suppressed
+checks) in the program source.
+
+@node Use of Restrictions
+@subsection Use of Restrictions
+
+@noindent
+The use of pragma Restrictions allows you to control which features are
+permitted in your program. Apart from the obvious point that if you avoid
+relatively expensive features like finalization (enforceable by the use
+of pragma Restrictions (No_Finalization), the use of this pragma does not
+affect the generated code in most cases.
+
+One notable exception to this rule is that the possibility of task abort
+results in some distributed overhead, particularly if finalization or
+exception handlers are used. The reason is that certain sections of code
+have to be marked as non-abortable.
+
+If you use neither the @code{abort} statement, nor asynchronous transfer
+of control (@code{select .. then abort}), then this distributed overhead
+is removed, which may have a general positive effect in improving
+overall performance. Especially code involving frequent use of tasking
+constructs and controlled types will show much improved performance.
+The relevant restrictions pragmas are
+
+@smallexample
+ pragma Restrictions (No_Abort_Statements);
+ pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+@end smallexample
+
+@noindent
+It is recommended that these restriction pragmas be used if possible. Note
+that this also means that you can write code without worrying about the
+possibility of an immediate abort at any point.
+
+@node Optimization Levels
+@subsection Optimization Levels
+@cindex @option{^-O^/OPTIMIZE^} (@code{gcc})
+
+@noindent
+The default is optimization off. This results in the fastest compile
+times, but GNAT makes absolutely no attempt to optimize, and the
+generated programs are considerably larger and slower than when
+optimization is enabled. You can use the
+@ifclear vms
+@option{-O@var{n}} switch, where @var{n} is an integer from 0 to 3,
+@end ifclear
+@ifset vms
+@code{OPTIMIZE} qualifier
+@end ifset
+to @code{gcc} to control the optimization level:
+
+@table @option
+@item ^-O0^/OPTIMIZE=NONE^
+No optimization (the default);
+generates unoptimized code but has
+the fastest compilation time.
+
+@item ^-O1^/OPTIMIZE=SOME^
+Medium level optimization;
+optimizes reasonably well but does not
+degrade compilation time significantly.
+
+@item ^-O2^/OPTIMIZE=ALL^
+@ifset vms
+@itemx /OPTIMIZE=DEVELOPMENT
+@end ifset
+Full optimization;
+generates highly optimized code and has
+the slowest compilation time.
+
+@item ^-O3^/OPTIMIZE=INLINING^
+Full optimization as in @option{-O2},
+and also attempts automatic inlining of small
+subprograms within a unit (@pxref{Inlining of Subprograms}).
+@end table
+
+@noindent
+Higher optimization levels perform more global transformations on the
+program and apply more expensive analysis algorithms in order to generate
+faster and more compact code. The price in compilation time, and the
+resulting improvement in execution time,
+both depend on the particular application and the hardware environment.
+You should experiment to find the best level for your application.
+
+Since the precise set of optimizations done at each level will vary from
+release to release (and sometime from target to target), it is best to think
+of the optimization settings in general terms.
+The @cite{Using GNU GCC} manual contains details about
+^the @option{-O} settings and a number of @option{-f} options that^how to^
+individually enable or disable specific optimizations.
+
+Unlike some other compilation systems, ^@command{gcc}^GNAT^ has
+been tested extensively at all optimization levels. There are some bugs
+which appear only with optimization turned on, but there have also been
+bugs which show up only in @emph{unoptimized} code. Selecting a lower
+level of optimization does not improve the reliability of the code
+generator, which in practice is highly reliable at all optimization
+levels.
+
+Note regarding the use of @option{-O3}: The use of this optimization level
+is generally discouraged with GNAT, since it often results in larger
+executables which run more slowly. See further discussion of this point
+in @pxref{Inlining of Subprograms}.
+
+
+@node Debugging Optimized Code
+@subsection Debugging Optimized Code
+@cindex Debugging optimized code
+@cindex Optimization and debugging
+
+@noindent
+Although it is possible to do a reasonable amount of debugging at
+@ifclear vms
+non-zero optimization levels,
+the higher the level the more likely that
+@end ifclear
+@ifset vms
+@option{/OPTIMIZE} settings other than @code{NONE},
+such settings will make it more likely that
+@end ifset
+source-level constructs will have been eliminated by optimization.
+For example, if a loop is strength-reduced, the loop
+control variable may be completely eliminated and thus cannot be
+displayed in the debugger.
+This can only happen at @option{-O2} or @option{-O3}.
+Explicit temporary variables that you code might be eliminated at
+^level^setting^ @option{-O1} or higher.
+
+The use of the @option{^-g^/DEBUG^} switch,
+@cindex @option{^-g^/DEBUG^} (@code{gcc})
+which is needed for source-level debugging,
+affects the size of the program executable on disk,
+and indeed the debugging information can be quite large.
+However, it has no effect on the generated code (and thus does not
+degrade performance)
+
+Since the compiler generates debugging tables for a compilation unit before
+it performs optimizations, the optimizing transformations may invalidate some
+of the debugging data. You therefore need to anticipate certain
+anomalous situations that may arise while debugging optimized code.
+These are the most common cases:
+
+@enumerate
+@item
+@i{The ``hopping Program Counter'':} Repeated @code{step} or @code{next}
+commands show
+the PC bouncing back and forth in the code. This may result from any of
+the following optimizations:
+
+@itemize @bullet
+@item
+@i{Common subexpression elimination:} using a single instance of code for a
+quantity that the source computes several times. As a result you
+may not be able to stop on what looks like a statement.
+
+@item
+@i{Invariant code motion:} moving an expression that does not change within a
+loop, to the beginning of the loop.
+
+@item
+@i{Instruction scheduling:} moving instructions so as to
+overlap loads and stores (typically) with other code, or in
+general to move computations of values closer to their uses. Often
+this causes you to pass an assignment statement without the assignment
+happening and then later bounce back to the statement when the
+value is actually needed. Placing a breakpoint on a line of code
+and then stepping over it may, therefore, not always cause all the
+expected side-effects.
+@end itemize
+
+@item
+@i{The ``big leap'':} More commonly known as @emph{cross-jumping}, in which
+two identical pieces of code are merged and the program counter suddenly
+jumps to a statement that is not supposed to be executed, simply because
+it (and the code following) translates to the same thing as the code
+that @emph{was} supposed to be executed. This effect is typically seen in
+sequences that end in a jump, such as a @code{goto}, a @code{return}, or
+a @code{break} in a C @code{^switch^switch^} statement.
+
+@item
+@i{The ``roving variable'':} The symptom is an unexpected value in a variable.
+There are various reasons for this effect:
+
+@itemize @bullet
+@item
+In a subprogram prologue, a parameter may not yet have been moved to its
+``home''.
+
+@item
+A variable may be dead, and its register re-used. This is
+probably the most common cause.
+
+@item
+As mentioned above, the assignment of a value to a variable may
+have been moved.
+
+@item
+A variable may be eliminated entirely by value propagation or
+other means. In this case, GCC may incorrectly generate debugging
+information for the variable
+@end itemize
+
+@noindent
+In general, when an unexpected value appears for a local variable or parameter
+you should first ascertain if that value was actually computed by
+your program, as opposed to being incorrectly reported by the debugger.
+Record fields or
+array elements in an object designated by an access value
+are generally less of a problem, once you have ascertained that the access
+value is sensible.
+Typically, this means checking variables in the preceding code and in the
+calling subprogram to verify that the value observed is explainable from other
+values (one must apply the procedure recursively to those
+other values); or re-running the code and stopping a little earlier
+(perhaps before the call) and stepping to better see how the variable obtained
+the value in question; or continuing to step @emph{from} the point of the
+strange value to see if code motion had simply moved the variable's
+assignments later.
+@end enumerate
+
+@noindent
+In light of such anomalies, a recommended technique is to use @option{-O0}
+early in the software development cycle, when extensive debugging capabilities
+are most needed, and then move to @option{-O1} and later @option{-O2} as
+the debugger becomes less critical.
+Whether to use the @option{^-g^/DEBUG^} switch in the release version is
+a release management issue.
+@ifclear vms
+Note that if you use @option{-g} you can then use the @command{strip} program
+on the resulting executable,
+which removes both debugging information and global symbols.
+@end ifclear
+
+
+@node Inlining of Subprograms
+@subsection Inlining of Subprograms
+
+@noindent
+A call to a subprogram in the current unit is inlined if all the
+following conditions are met:
+
+@itemize @bullet
+@item
+The optimization level is at least @option{-O1}.
+
+@item
+The called subprogram is suitable for inlining: It must be small enough
+and not contain nested subprograms or anything else that @code{gcc}
+cannot support in inlined subprograms.
+
+@item
+The call occurs after the definition of the body of the subprogram.
+
+@item
+@cindex pragma Inline
+@findex Inline
+Either @code{pragma Inline} applies to the subprogram or it is
+small and automatic inlining (optimization level @option{-O3}) is
+specified.
+@end itemize
+
+@noindent
+Calls to subprograms in @code{with}'ed units are normally not inlined.
+To achieve this level of inlining, the following conditions must all be
+true:
+
+@itemize @bullet
+@item
+The optimization level is at least @option{-O1}.
+
+@item
+The called subprogram is suitable for inlining: It must be small enough
+and not contain nested subprograms or anything else @code{gcc} cannot
+support in inlined subprograms.
+
+@item
+The call appears in a body (not in a package spec).
+
+@item
+There is a @code{pragma Inline} for the subprogram.
+
+@item
+@cindex @option{-gnatn} (@code{gcc})
+The @option{^-gnatn^/INLINE^} switch
+is used in the @code{gcc} command line
+@end itemize
+
+Note that specifying the @option{-gnatn} switch causes additional
+compilation dependencies. Consider the following:
+
+@smallexample @c ada
+@cartouche
+package R is
+ procedure Q;
+ pragma Inline (Q);
+end R;
+package body R is
+ ...
+end R;
+
+with R;
+procedure Main is
+begin
+ ...
+ R.Q;
+end Main;
+@end cartouche
+@end smallexample
+
+@noindent
+With the default behavior (no @option{-gnatn} switch specified), the
+compilation of the @code{Main} procedure depends only on its own source,
+@file{main.adb}, and the spec of the package in file @file{r.ads}. This
+means that editing the body of @code{R} does not require recompiling
+@code{Main}.
+
+On the other hand, the call @code{R.Q} is not inlined under these
+circumstances. If the @option{-gnatn} switch is present when @code{Main}
+is compiled, the call will be inlined if the body of @code{Q} is small
+enough, but now @code{Main} depends on the body of @code{R} in
+@file{r.adb} as well as on the spec. This means that if this body is edited,
+the main program must be recompiled. Note that this extra dependency
+occurs whether or not the call is in fact inlined by @code{gcc}.
+
+The use of front end inlining with @option{-gnatN} generates similar
+additional dependencies.
+
+@cindex @option{^-fno-inline^/INLINE=SUPPRESS^} (@code{gcc})
+Note: The @option{^-fno-inline^/INLINE=SUPPRESS^} switch
+can be used to prevent
+all inlining. This switch overrides all other conditions and ensures
+that no inlining occurs. The extra dependences resulting from
+@option{-gnatn} will still be active, even if
+this switch is used to suppress the resulting inlining actions.
+
+Note regarding the use of @option{-O3}: There is no difference in inlining
+behavior between @option{-O2} and @option{-O3} for subprograms with an explicit
+pragma @code{Inline} assuming the use of @option{-gnatn}
+or @option{-gnatN} (the switches that activate inlining). If you have used
+pragma @code{Inline} in appropriate cases, then it is usually much better
+to use @option{-O2} and @option{-gnatn} and avoid the use of @option{-O3} which
+in this case only has the effect of inlining subprograms you did not
+think should be inlined. We often find that the use of @option{-O3} slows
+down code by performing excessive inlining, leading to increased instruction
+cache pressure from the increased code size. So the bottom line here is
+that you should not automatically assume that @option{-O3} is better than
+@option{-O2}, and indeed you should use @option{-O3} only if tests show that
+it actually improves performance.
+
+@node Optimization and Strict Aliasing
+@subsection Optimization and Strict Aliasing
+@cindex Aliasing
+@cindex Strict Aliasing
+@cindex No_Strict_Aliasing
+
+@noindent
+The strong typing capabilities of Ada allow an optimizer to generate
+efficient code in situations where other languages would be forced to
+make worst case assumptions preventing such optimizations. Consider
+the following example:
+
+@smallexample @c ada
+@cartouche
+procedure R is
+ type Int1 is new Integer;
+ type Int2 is new Integer;
+ type Int1A is access Int1;
+ type Int2A is access Int2;
+ Int1V : Int1A;
+ Int2V : Int2A;
+ ...
+
+begin
+ ...
+ for J in Data'Range loop
+ if Data (J) = Int1V.all then
+ Int2V.all := Int2V.all + 1;
+ end if;
+ end loop;
+ ...
+end R;
+@end cartouche
+@end smallexample
+
+@noindent
+In this example, since the variable @code{Int1V} can only access objects
+of type @code{Int1}, and @code{Int2V} can only access objects of type
+@code{Int2}, there is no possibility that the assignment to
+@code{Int2V.all} affects the value of @code{Int1V.all}. This means that
+the compiler optimizer can "know" that the value @code{Int1V.all} is constant
+for all iterations of the loop and avoid the extra memory reference
+required to dereference it each time through the loop.
+
+This kind of optimziation, called strict aliasing analysis, is
+triggered by specifying an optimization level of @option{-O2} or
+higher and allows @code{GNAT} to generate more efficient code
+when access values are involved.
+
+However, although this optimization is always correct in terms of
+the formal semantics of the Ada Reference Manual, difficulties can
+arise if features like @code{Unchecked_Conversion} are used to break
+the typing system. Consider the following complete program example:
+
+@smallexample @c ada
+@cartouche
+package p1 is
+ type int1 is new integer;
+ type int2 is new integer;
+ type a1 is access int1;
+ type a2 is access int2;
+end p1;
+
+with p1; use p1;
+package p2 is
+ function to_a2 (Input : a1) return a2;
+end p2;
+
+with Unchecked_Conversion;
+package body p2 is
+ function to_a2 (Input : a1) return a2 is
+ function to_a2u is
+ new Unchecked_Conversion (a1, a2);
+ begin
+ return to_a2u (Input);
+ end to_a2;
+end p2;
+
+with p2; use p2;
+with p1; use p1;
+with Text_IO; use Text_IO;
+procedure m is
+ v1 : a1 := new int1;
+ v2 : a2 := to_a2 (v1);
+begin
+ v1.all := 1;
+ v2.all := 0;
+ put_line (int1'image (v1.all));
+end;
+@end cartouche
+@end smallexample
+
+@noindent
+This program prints out 0 in @code{-O0} or @code{-O1}
+mode, but it prints out 1 in @code{-O2} mode. That's
+because in strict aliasing mode, the compiler can and
+does assume that the assignment to @code{v2.all} could not
+affect the value of @code{v1.all}, since different types
+are involved.
+
+This behavior is not a case of non-conformance with the standard, since
+the Ada RM specifies that an unchecked conversion where the resulting
+bit pattern is not a correct value of the target type can result in an
+abnormal value and attempting to reference an abnormal value makes the
+execution of a program erroneous. That's the case here since the result
+does not point to an object of type @code{int2}. This means that the
+effect is entirely unpredictable.
+
+However, although that explanation may satisfy a language
+lawyer, in practice an applications programmer expects an
+unchecked conversion involving pointers to create true
+aliases and the behavior of printing 1 seems plain wrong.
+In this case, the strict aliasing optimization is unwelcome.
+
+Indeed the compiler recognizes this possibility, and the
+unchecked conversion generates a warning:
+
+@smallexample
+p2.adb:5:07: warning: possible aliasing problem with type "a2"
+p2.adb:5:07: warning: use -fno-strict-aliasing switch for references
+p2.adb:5:07: warning: or use "pragma No_Strict_Aliasing (a2);"
+@end smallexample
+
+@noindent
+Unfortunately the problem is recognized when compiling the body of
+package @code{p2}, but the actual "bad" code is generated while
+compiling the body of @code{m} and this latter compilation does not see
+the suspicious @code{Unchecked_Conversion}.
+
+As implied by the warning message, there are approaches you can use to
+avoid the unwanted strict aliasing optimization in a case like this.
+
+One possibility is to simply avoid the use of @code{-O2}, but
+that is a bit drastic, since it throws away a number of useful
+optimizations that do not involve strict aliasing assumptions.
+
+A less drastic approach is to compile the program using the
+option @code{-fno-strict-aliasing}. Actually it is only the
+unit containing the dereferencing of the suspicious pointer
+that needs to be compiled. So in this case, if we compile
+unit @code{m} with this switch, then we get the expected
+value of zero printed. Analyzing which units might need
+the switch can be painful, so a more reasonable approach
+is to compile the entire program with options @code{-O2}
+and @code{-fno-strict-aliasing}. If the performance is
+satisfactory with this combination of options, then the
+advantage is that the entire issue of possible "wrong"
+optimization due to strict aliasing is avoided.
+
+To avoid the use of compiler switches, the configuration
+pragma @code{No_Strict_Aliasing} with no parameters may be
+used to specify that for all access types, the strict
+aliasing optimization should be suppressed.
+
+However, these approaches are still overkill, in that they causes
+all manipulations of all access values to be deoptimized. A more
+refined approach is to concentrate attention on the specific
+access type identified as problematic.
+
+First, if a careful analysis of uses of the pointer shows
+that there are no possible problematic references, then
+the warning can be suppressed by bracketing the
+instantiation of @code{Unchecked_Conversion} to turn
+the warning off:
+
+@smallexample @c ada
+ pragma Warnings (Off);
+ function to_a2u is
+ new Unchecked_Conversion (a1, a2);
+ pragma Warnings (On);
+@end smallexample
+
+@noindent
+Of course that approach is not appropriate for this particular
+example, since indeed there is a problematic reference. In this
+case we can take one of two other approaches.
+
+The first possibility is to move the instantiation of unchecked
+conversion to the unit in which the type is declared. In
+this example, we would move the instantiation of
+@code{Unchecked_Conversion} from the body of package
+@code{p2} to the spec of package @code{p1}. Now the
+warning disappears. That's because any use of the
+access type knows there is a suspicious unchecked
+conversion, and the strict aliasing optimization
+is automatically suppressed for the type.
+
+If it is not practical to move the unchecked conversion to the same unit
+in which the destination access type is declared (perhaps because the
+source type is not visible in that unit), you may use pragma
+@code{No_Strict_Aliasing} for the type. This pragma must occur in the
+same declarative sequence as the declaration of the access type:
+
+@smallexample @c ada
+ type a2 is access int2;
+ pragma No_Strict_Aliasing (a2);
+@end smallexample
+
+@noindent
+Here again, the compiler now knows that the strict aliasing optimization
+should be suppressed for any reference to type @code{a2} and the
+expected behavior is obtained.
+
+Finally, note that although the compiler can generate warnings for
+simple cases of unchecked conversions, there are tricker and more
+indirect ways of creating type incorrect aliases which the compiler
+cannot detect. Examples are the use of address overlays and unchecked
+conversions involving composite types containing access types as
+components. In such cases, no warnings are generated, but there can
+still be aliasing problems. One safe coding practice is to forbid the
+use of address clauses for type overlaying, and to allow unchecked
+conversion only for primitive types. This is not really a significant
+restriction since any possible desired effect can be achieved by
+unchecked conversion of access values.
+
+@ifset vms
+@node Coverage Analysis
+@subsection Coverage Analysis
+
+@noindent
+GNAT supports the Digital Performance Coverage Analyzer (PCA), which allows
+the user to determine the distribution of execution time across a program,
+@pxref{Profiling} for details of usage.
+@end ifset
+
+@node Reducing the Size of Ada Executables with gnatelim
+@section Reducing the Size of Ada Executables with @code{gnatelim}
+@findex gnatelim
+
+@noindent
+This section describes @command{gnatelim}, a tool which detects unused
+subprograms and helps the compiler to create a smaller executable for your
+program.
+
+@menu
+* About gnatelim::
+* Running gnatelim::
+* Correcting the List of Eliminate Pragmas::
+* Making Your Executables Smaller::
+* Summary of the gnatelim Usage Cycle::
+@end menu
+
+@node About gnatelim
+@subsection About @code{gnatelim}
+
+@noindent
+When a program shares a set of Ada
+packages with other programs, it may happen that this program uses
+only a fraction of the subprograms defined in these packages. The code
+created for these unused subprograms increases the size of the executable.
+
+@code{gnatelim} tracks unused subprograms in an Ada program and
+outputs a list of GNAT-specific pragmas @code{Eliminate} marking all the
+subprograms that are declared but never called. By placing the list of
+@code{Eliminate} pragmas in the GNAT configuration file @file{gnat.adc} and
+recompiling your program, you may decrease the size of its executable,
+because the compiler will not generate the code for 'eliminated' subprograms.
+See GNAT Reference Manual for more information about this pragma.
+
+@code{gnatelim} needs as its input data the name of the main subprogram
+and a bind file for a main subprogram.
+
+To create a bind file for @code{gnatelim}, run @code{gnatbind} for
+the main subprogram. @code{gnatelim} can work with both Ada and C
+bind files; when both are present, it uses the Ada bind file.
+The following commands will build the program and create the bind file:
+
+@smallexample
+$ gnatmake ^-c Main_Prog^/ACTIONS=COMPILE MAIN_PROG^
+$ gnatbind main_prog
+@end smallexample
+
+Note that @code{gnatelim} needs neither object nor ALI files.
+
+@node Running gnatelim
+@subsection Running @code{gnatelim}
+
+@noindent
+@code{gnatelim} has the following command-line interface:
+
+@smallexample
+$ gnatelim [options] name
+@end smallexample
+
+@noindent
+@code{name} should be a name of a source file that contains the main subprogram
+of a program (partition).
+
+@code{gnatelim} has the following switches:
+
+@table @option
+@c !sort!
+@item ^-q^/QUIET^
+@cindex @option{^-q^/QUIET^} (@command{gnatelim})
+Quiet mode: by default @code{gnatelim} outputs to the standard error
+stream the number of program units left to be processed. This option turns
+this trace off.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@command{gnatelim})
+Verbose mode: @code{gnatelim} version information is printed as Ada
+comments to the standard output stream. Also, in addition to the number of
+program units left @code{gnatelim} will output the name of the current unit
+being processed.
+
+@item ^-a^/ALL^
+@cindex @option{^-a^/ALL^} (@command{gnatelim})
+Also look for subprograms from the GNAT run time that can be eliminated. Note
+that when @file{gnat.adc} is produced using this switch, the entire program
+must be recompiled with switch @option{^-a^/ALL_FILES^} to @code{gnatmake}.
+
+@item ^-I^/INCLUDE_DIRS=^@var{dir}
+@cindex @option{^-I^/INCLUDE_DIRS^} (@command{gnatelim})
+When looking for source files also look in directory @var{dir}. Specifying
+@option{^-I-^/INCLUDE_DIRS=-^} instructs @code{gnatelim} not to look for
+sources in the current directory.
+
+@item ^-b^/BIND_FILE=^@var{bind_file}
+@cindex @option{^-b^/BIND_FILE^} (@command{gnatelim})
+Specifies @var{bind_file} as the bind file to process. If not set, the name
+of the bind file is computed from the full expanded Ada name
+of a main subprogram.
+
+@item ^-C^/CONFIG_FILE=^@var{config_file}
+@cindex @option{^-C^/CONFIG_FILE^} (@command{gnatelim})
+Specifies a file @var{config_file} that contains configuration pragmas. The
+file must be specified with full path.
+
+@item ^--GCC^/COMPILER^=@var{compiler_name}
+@cindex @option{^-GCC^/COMPILER^} (@command{gnatelim})
+Instructs @code{gnatelim} to use specific @code{gcc} compiler instead of one
+available on the path.
+
+@item ^--GNATMAKE^/GNATMAKE^=@var{gnatmake_name}
+@cindex @option{^--GNATMAKE^/GNATMAKE^} (@command{gnatelim})
+Instructs @code{gnatelim} to use specific @code{gnatmake} instead of one
+available on the path.
+
+@item -d@var{x}
+@cindex @option{-d@var{x}} (@command{gnatelim})
+Activate internal debugging switches. @var{x} is a letter or digit, or
+string of letters or digits, which specifies the type of debugging
+mode desired. Normally these are used only for internal development
+or system debugging purposes. You can find full documentation for these
+switches in the spec of the @code{Gnatelim} unit in the compiler
+source file @file{gnatelim.ads}.
+@end table
+
+@noindent
+@code{gnatelim} sends its output to the standard output stream, and all the
+tracing and debug information is sent to the standard error stream.
+In order to produce a proper GNAT configuration file
+@file{gnat.adc}, redirection must be used:
+
+@smallexample
+@ifset vms
+$ PIPE GNAT ELIM MAIN_PROG.ADB > GNAT.ADC
+@end ifset
+@ifclear vms
+$ gnatelim main_prog.adb > gnat.adc
+@end ifclear
+@end smallexample
+
+@ifclear vms
+@noindent
+or
+
+@smallexample
+$ gnatelim main_prog.adb >> gnat.adc
+@end smallexample
+
+@noindent
+in order to append the @code{gnatelim} output to the existing contents of
+@file{gnat.adc}.
+@end ifclear
+
+@node Correcting the List of Eliminate Pragmas
+@subsection Correcting the List of Eliminate Pragmas
+
+@noindent
+In some rare cases @code{gnatelim} may try to eliminate
+subprograms that are actually called in the program. In this case, the
+compiler will generate an error message of the form:
+
+@smallexample
+file.adb:106:07: cannot call eliminated subprogram "My_Prog"
+@end smallexample
+
+@noindent
+You will need to manually remove the wrong @code{Eliminate} pragmas from
+the @file{gnat.adc} file. You should recompile your program
+from scratch after that, because you need a consistent @file{gnat.adc} file
+during the entire compilation.
+
+
+@node Making Your Executables Smaller
+@subsection Making Your Executables Smaller
+
+@noindent
+In order to get a smaller executable for your program you now have to
+recompile the program completely with the new @file{gnat.adc} file
+created by @code{gnatelim} in your current directory:
+
+@smallexample
+$ gnatmake ^-f main_prog^/FORCE_COMPILE MAIN_PROG^
+@end smallexample
+
+@noindent
+(Use the @option{^-f^/FORCE_COMPILE^} option for @command{gnatmake} to
+recompile everything
+with the set of pragmas @code{Eliminate} that you have obtained with
+@command{gnatelim}).
+
+Be aware that the set of @code{Eliminate} pragmas is specific to each
+program. It is not recommended to merge sets of @code{Eliminate}
+pragmas created for different programs in one @file{gnat.adc} file.
+
+@node Summary of the gnatelim Usage Cycle
+@subsection Summary of the gnatelim Usage Cycle
+
+@noindent
+Here is a quick summary of the steps to be taken in order to reduce
+the size of your executables with @code{gnatelim}. You may use
+other GNAT options to control the optimization level,
+to produce the debugging information, to set search path, etc.
+
+@enumerate
+@item
+Produce a bind file
+
+@smallexample
+$ gnatmake ^-c main_prog^/ACTIONS=COMPILE MAIN_PROG^
+$ gnatbind main_prog
+@end smallexample
+
+@item
+Generate a list of @code{Eliminate} pragmas
+@smallexample
+@ifset vms
+$ PIPE GNAT ELIM MAIN_PROG > GNAT.ADC
+@end ifset
+@ifclear vms
+$ gnatelim main_prog >[>] gnat.adc
+@end ifclear
+@end smallexample
+
+@item
+Recompile the application
+
+@smallexample
+$ gnatmake ^-f main_prog^/FORCE_COMPILE MAIN_PROG^
+@end smallexample
+
+@end enumerate
+
+
+
+
+@c ********************************
+@node Renaming Files Using gnatchop
+@chapter Renaming Files Using @code{gnatchop}
+@findex gnatchop
+
+@noindent
+This chapter discusses how to handle files with multiple units by using
+the @code{gnatchop} utility. This utility is also useful in renaming
+files to meet the standard GNAT default file naming conventions.
+
+@menu
+* Handling Files with Multiple Units::
+* Operating gnatchop in Compilation Mode::
+* Command Line for gnatchop::
+* Switches for gnatchop::
+* Examples of gnatchop Usage::
+@end menu
+
+@node Handling Files with Multiple Units
+@section Handling Files with Multiple Units
+
+@noindent
+The basic compilation model of GNAT requires that a file submitted to the
+compiler have only one unit and there be a strict correspondence
+between the file name and the unit name.
+
+The @code{gnatchop} utility allows both of these rules to be relaxed,
+allowing GNAT to process files which contain multiple compilation units
+and files with arbitrary file names. @code{gnatchop}
+reads the specified file and generates one or more output files,
+containing one unit per file. The unit and the file name correspond,
+as required by GNAT.
+
+If you want to permanently restructure a set of ``foreign'' files so that
+they match the GNAT rules, and do the remaining development using the
+GNAT structure, you can simply use @command{gnatchop} once, generate the
+new set of files and work with them from that point on.
+
+Alternatively, if you want to keep your files in the ``foreign'' format,
+perhaps to maintain compatibility with some other Ada compilation
+system, you can set up a procedure where you use @command{gnatchop} each
+time you compile, regarding the source files that it writes as temporary
+files that you throw away.
+
+
+@node Operating gnatchop in Compilation Mode
+@section Operating gnatchop in Compilation Mode
+
+@noindent
+The basic function of @code{gnatchop} is to take a file with multiple units
+and split it into separate files. The boundary between files is reasonably
+clear, except for the issue of comments and pragmas. In default mode, the
+rule is that any pragmas between units belong to the previous unit, except
+that configuration pragmas always belong to the following unit. Any comments
+belong to the following unit. These rules
+almost always result in the right choice of
+the split point without needing to mark it explicitly and most users will
+find this default to be what they want. In this default mode it is incorrect to
+submit a file containing only configuration pragmas, or one that ends in
+configuration pragmas, to @code{gnatchop}.
+
+However, using a special option to activate ``compilation mode'',
+@code{gnatchop}
+can perform another function, which is to provide exactly the semantics
+required by the RM for handling of configuration pragmas in a compilation.
+In the absence of configuration pragmas (at the main file level), this
+option has no effect, but it causes such configuration pragmas to be handled
+in a quite different manner.
+
+First, in compilation mode, if @code{gnatchop} is given a file that consists of
+only configuration pragmas, then this file is appended to the
+@file{gnat.adc} file in the current directory. This behavior provides
+the required behavior described in the RM for the actions to be taken
+on submitting such a file to the compiler, namely that these pragmas
+should apply to all subsequent compilations in the same compilation
+environment. Using GNAT, the current directory, possibly containing a
+@file{gnat.adc} file is the representation
+of a compilation environment. For more information on the
+@file{gnat.adc} file, see the section on handling of configuration
+pragmas @pxref{Handling of Configuration Pragmas}.
+
+Second, in compilation mode, if @code{gnatchop}
+is given a file that starts with
+configuration pragmas, and contains one or more units, then these
+configuration pragmas are prepended to each of the chopped files. This
+behavior provides the required behavior described in the RM for the
+actions to be taken on compiling such a file, namely that the pragmas
+apply to all units in the compilation, but not to subsequently compiled
+units.
+
+Finally, if configuration pragmas appear between units, they are appended
+to the previous unit. This results in the previous unit being illegal,
+since the compiler does not accept configuration pragmas that follow
+a unit. This provides the required RM behavior that forbids configuration
+pragmas other than those preceding the first compilation unit of a
+compilation.
+
+For most purposes, @code{gnatchop} will be used in default mode. The
+compilation mode described above is used only if you need exactly
+accurate behavior with respect to compilations, and you have files
+that contain multiple units and configuration pragmas. In this
+circumstance the use of @code{gnatchop} with the compilation mode
+switch provides the required behavior, and is for example the mode
+in which GNAT processes the ACVC tests.
+
+@node Command Line for gnatchop
+@section Command Line for @code{gnatchop}
+
+@noindent
+The @code{gnatchop} command has the form:
+
+@smallexample
+$ gnatchop switches @var{file name} [@var{file name} @var{file name} ...]
+ [@var{directory}]
+@end smallexample
+
+@noindent
+The only required argument is the file name of the file to be chopped.
+There are no restrictions on the form of this file name. The file itself
+contains one or more Ada units, in normal GNAT format, concatenated
+together. As shown, more than one file may be presented to be chopped.
+
+When run in default mode, @code{gnatchop} generates one output file in
+the current directory for each unit in each of the files.
+
+@var{directory}, if specified, gives the name of the directory to which
+the output files will be written. If it is not specified, all files are
+written to the current directory.
+
+For example, given a
+file called @file{hellofiles} containing
+
+@smallexample @c ada
+@group
+@cartouche
+procedure hello;
+
+with Text_IO; use Text_IO;
+procedure hello is
+begin
+ Put_Line ("Hello");
+end hello;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+the command
+
+@smallexample
+$ gnatchop ^hellofiles^HELLOFILES.^
+@end smallexample
+
+@noindent
+generates two files in the current directory, one called
+@file{hello.ads} containing the single line that is the procedure spec,
+and the other called @file{hello.adb} containing the remaining text. The
+original file is not affected. The generated files can be compiled in
+the normal manner.
+
+@noindent
+When gnatchop is invoked on a file that is empty or that contains only empty
+lines and/or comments, gnatchop will not fail, but will not produce any
+new sources.
+
+For example, given a
+file called @file{toto.txt} containing
+
+@smallexample @c ada
+@group
+@cartouche
+-- Just a comment
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+the command
+
+@smallexample
+$ gnatchop ^toto.txt^TOT.TXT^
+@end smallexample
+
+@noindent
+will not produce any new file and will result in the following warnings:
+
+@smallexample
+toto.txt:1:01: warning: empty file, contains no compilation units
+no compilation units found
+no source files written
+@end smallexample
+
+@node Switches for gnatchop
+@section Switches for @code{gnatchop}
+
+@noindent
+@command{gnatchop} recognizes the following switches:
+
+@table @option
+@c !sort!
+
+@item ^-c^/COMPILATION^
+@cindex @option{^-c^/COMPILATION^} (@code{gnatchop})
+Causes @code{gnatchop} to operate in compilation mode, in which
+configuration pragmas are handled according to strict RM rules. See
+previous section for a full description of this mode.
+
+@ifclear vms
+@item -gnatxxx
+This passes the given @option{-gnatxxx} switch to @code{gnat} which is
+used to parse the given file. Not all @code{xxx} options make sense,
+but for example, the use of @option{-gnati2} allows @code{gnatchop} to
+process a source file that uses Latin-2 coding for identifiers.
+@end ifclear
+
+@item ^-h^/HELP^
+Causes @code{gnatchop} to generate a brief help summary to the standard
+output file showing usage information.
+
+@item ^-k@var{mm}^/FILE_NAME_MAX_LENGTH=@var{mm}^
+@cindex @option{^-k^/FILE_NAME_MAX_LENGTH^} (@code{gnatchop})
+Limit generated file names to the specified number @code{mm}
+of characters.
+This is useful if the
+resulting set of files is required to be interoperable with systems
+which limit the length of file names.
+@ifset vms
+If no value is given, or
+if no @code{/FILE_NAME_MAX_LENGTH} qualifier is given,
+a default of 39, suitable for OpenVMS Alpha
+Systems, is assumed
+@end ifset
+@ifclear vms
+No space is allowed between the @option{-k} and the numeric value. The numeric
+value may be omitted in which case a default of @option{-k8},
+suitable for use
+with DOS-like file systems, is used. If no @option{-k} switch
+is present then
+there is no limit on the length of file names.
+@end ifclear
+
+@item ^-p^/PRESERVE^
+@cindex @option{^-p^/PRESERVE^} (@code{gnatchop})
+Causes the file ^modification^creation^ time stamp of the input file to be
+preserved and used for the time stamp of the output file(s). This may be
+useful for preserving coherency of time stamps in an environment where
+@code{gnatchop} is used as part of a standard build process.
+
+@item ^-q^/QUIET^
+@cindex @option{^-q^/QUIET^} (@code{gnatchop})
+Causes output of informational messages indicating the set of generated
+files to be suppressed. Warnings and error messages are unaffected.
+
+@item ^-r^/REFERENCE^
+@cindex @option{^-r^/REFERENCE^} (@code{gnatchop})
+@findex Source_Reference
+Generate @code{Source_Reference} pragmas. Use this switch if the output
+files are regarded as temporary and development is to be done in terms
+of the original unchopped file. This switch causes
+@code{Source_Reference} pragmas to be inserted into each of the
+generated files to refers back to the original file name and line number.
+The result is that all error messages refer back to the original
+unchopped file.
+In addition, the debugging information placed into the object file (when
+the @option{^-g^/DEBUG^} switch of @code{gcc} or @code{gnatmake} is specified)
+also refers back to this original file so that tools like profilers and
+debuggers will give information in terms of the original unchopped file.
+
+If the original file to be chopped itself contains
+a @code{Source_Reference}
+pragma referencing a third file, then gnatchop respects
+this pragma, and the generated @code{Source_Reference} pragmas
+in the chopped file refer to the original file, with appropriate
+line numbers. This is particularly useful when @code{gnatchop}
+is used in conjunction with @code{gnatprep} to compile files that
+contain preprocessing statements and multiple units.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@code{gnatchop})
+Causes @code{gnatchop} to operate in verbose mode. The version
+number and copyright notice are output, as well as exact copies of
+the gnat1 commands spawned to obtain the chop control information.
+
+@item ^-w^/OVERWRITE^
+@cindex @option{^-w^/OVERWRITE^} (@code{gnatchop})
+Overwrite existing file names. Normally @code{gnatchop} regards it as a
+fatal error if there is already a file with the same name as a
+file it would otherwise output, in other words if the files to be
+chopped contain duplicated units. This switch bypasses this
+check, and causes all but the last instance of such duplicated
+units to be skipped.
+
+@ifclear vms
+@item --GCC=xxxx
+@cindex @option{--GCC=} (@code{gnatchop})
+Specify the path of the GNAT parser to be used. When this switch is used,
+no attempt is made to add the prefix to the GNAT parser executable.
+@end ifclear
+@end table
+
+@node Examples of gnatchop Usage
+@section Examples of @code{gnatchop} Usage
+
+@table @code
+@ifset vms
+@item gnatchop /OVERWRITE HELLO_S.ADA [PRERELEASE.FILES]
+@end ifset
+@ifclear vms
+@item gnatchop -w hello_s.ada prerelease/files
+@end ifclear
+
+Chops the source file @file{hello_s.ada}. The output files will be
+placed in the directory @file{^prerelease/files^[PRERELEASE.FILES]^},
+overwriting any
+files with matching names in that directory (no files in the current
+directory are modified).
+
+@item gnatchop ^archive^ARCHIVE.^
+Chops the source file @file{^archive^ARCHIVE.^}
+into the current directory. One
+useful application of @code{gnatchop} is in sending sets of sources
+around, for example in email messages. The required sources are simply
+concatenated (for example, using a ^Unix @code{cat}^VMS @code{APPEND/NEW}^
+command), and then
+@code{gnatchop} is used at the other end to reconstitute the original
+file names.
+
+@item gnatchop file1 file2 file3 direc
+Chops all units in files @file{file1}, @file{file2}, @file{file3}, placing
+the resulting files in the directory @file{direc}. Note that if any units
+occur more than once anywhere within this set of files, an error message
+is generated, and no files are written. To override this check, use the
+@option{^-w^/OVERWRITE^} switch,
+in which case the last occurrence in the last file will
+be the one that is output, and earlier duplicate occurrences for a given
+unit will be skipped.
+@end table
+
+@node Configuration Pragmas
+@chapter Configuration Pragmas
+@cindex Configuration pragmas
+@cindex Pragmas, configuration
+
+@noindent
+In Ada 95, configuration pragmas include those pragmas described as
+such in the Ada 95 Reference Manual, as well as
+implementation-dependent pragmas that are configuration pragmas. See the
+individual descriptions of pragmas in the GNAT Reference Manual for
+details on these additional GNAT-specific configuration pragmas. Most
+notably, the pragma @code{Source_File_Name}, which allows
+specifying non-default names for source files, is a configuration
+pragma. The following is a complete list of configuration pragmas
+recognized by @code{GNAT}:
+
+@smallexample
+ Ada_83
+ Ada_95
+ C_Pass_By_Copy
+ Component_Alignment
+ Discard_Names
+ Elaboration_Checks
+ Eliminate
+ Extend_System
+ Extensions_Allowed
+ External_Name_Casing
+ Float_Representation
+ Initialize_Scalars
+ License
+ Locking_Policy
+ Long_Float
+ Normalize_Scalars
+ Polling
+ Profile
+ Profile_Warnings
+ Propagate_Exceptions
+ Queuing_Policy
+ Ravenscar
+ Restricted_Run_Time
+ Restrictions
+ Restrictions_Warnings
+ Reviewable
+ Source_File_Name
+ Style_Checks
+ Suppress
+ Task_Dispatching_Policy
+ Universal_Data
+ Unsuppress
+ Use_VADS_Size
+ Warnings
+ Validity_Checks
+@end smallexample
+
+@menu
+* Handling of Configuration Pragmas::
+* The Configuration Pragmas Files::
+@end menu
+
+@node Handling of Configuration Pragmas
+@section Handling of Configuration Pragmas
+
+Configuration pragmas may either appear at the start of a compilation
+unit, in which case they apply only to that unit, or they may apply to
+all compilations performed in a given compilation environment.
+
+GNAT also provides the @code{gnatchop} utility to provide an automatic
+way to handle configuration pragmas following the semantics for
+compilations (that is, files with multiple units), described in the RM.
+See section @pxref{Operating gnatchop in Compilation Mode} for details.
+However, for most purposes, it will be more convenient to edit the
+@file{gnat.adc} file that contains configuration pragmas directly,
+as described in the following section.
+
+@node The Configuration Pragmas Files
+@section The Configuration Pragmas Files
+@cindex @file{gnat.adc}
+
+@noindent
+In GNAT a compilation environment is defined by the current
+directory at the time that a compile command is given. This current
+directory is searched for a file whose name is @file{gnat.adc}. If
+this file is present, it is expected to contain one or more
+configuration pragmas that will be applied to the current compilation.
+However, if the switch @option{-gnatA} is used, @file{gnat.adc} is not
+considered.
+
+Configuration pragmas may be entered into the @file{gnat.adc} file
+either by running @code{gnatchop} on a source file that consists only of
+configuration pragmas, or more conveniently by
+direct editing of the @file{gnat.adc} file, which is a standard format
+source file.
+
+In addition to @file{gnat.adc}, one additional file containing configuration
+pragmas may be applied to the current compilation using the switch
+@option{-gnatec}@var{path}. @var{path} must designate an existing file that
+contains only configuration pragmas. These configuration pragmas are
+in addition to those found in @file{gnat.adc} (provided @file{gnat.adc}
+is present and switch @option{-gnatA} is not used).
+
+It is allowed to specify several switches @option{-gnatec}, however only
+the last one on the command line will be taken into account.
+
+If you are using project file, a separate mechanism is provided using
+project attributes, see @ref{Specifying Configuration Pragmas} for more
+details.
+
+@ifset vms
+Of special interest to GNAT OpenVMS Alpha is the following
+configuration pragma:
+
+@smallexample @c ada
+@cartouche
+pragma Extend_System (Aux_DEC);
+@end cartouche
+@end smallexample
+
+@noindent
+In the presence of this pragma, GNAT adds to the definition of the
+predefined package SYSTEM all the additional types and subprograms that are
+defined in DEC Ada. See @pxref{Compatibility with DEC Ada} for details.
+@end ifset
+
+@node Handling Arbitrary File Naming Conventions Using gnatname
+@chapter Handling Arbitrary File Naming Conventions Using @code{gnatname}
+@cindex Arbitrary File Naming Conventions
+
+@menu
+* Arbitrary File Naming Conventions::
+* Running gnatname::
+* Switches for gnatname::
+* Examples of gnatname Usage::
+@end menu
+
+@node Arbitrary File Naming Conventions
+@section Arbitrary File Naming Conventions
+
+@noindent
+The GNAT compiler must be able to know the source file name of a compilation
+unit. When using the standard GNAT default file naming conventions
+(@code{.ads} for specs, @code{.adb} for bodies), the GNAT compiler
+does not need additional information.
+
+@noindent
+When the source file names do not follow the standard GNAT default file naming
+conventions, the GNAT compiler must be given additional information through
+a configuration pragmas file (see @ref{Configuration Pragmas})
+or a project file.
+When the non standard file naming conventions are well-defined,
+a small number of pragmas @code{Source_File_Name} specifying a naming pattern
+(see @ref{Alternative File Naming Schemes}) may be sufficient. However,
+if the file naming conventions are irregular or arbitrary, a number
+of pragma @code{Source_File_Name} for individual compilation units
+must be defined.
+To help maintain the correspondence between compilation unit names and
+source file names within the compiler,
+GNAT provides a tool @code{gnatname} to generate the required pragmas for a
+set of files.
+
+@node Running gnatname
+@section Running @code{gnatname}
+
+@noindent
+The usual form of the @code{gnatname} command is
+
+@smallexample
+$ gnatname [@var{switches}] @var{naming_pattern} [@var{naming_patterns}]
+@end smallexample
+
+@noindent
+All of the arguments are optional. If invoked without any argument,
+@code{gnatname} will display its usage.
+
+@noindent
+When used with at least one naming pattern, @code{gnatname} will attempt to
+find all the compilation units in files that follow at least one of the
+naming patterns. To find these compilation units,
+@code{gnatname} will use the GNAT compiler in syntax-check-only mode on all
+regular files.
+
+@noindent
+One or several Naming Patterns may be given as arguments to @code{gnatname}.
+Each Naming Pattern is enclosed between double quotes.
+A Naming Pattern is a regular expression similar to the wildcard patterns
+used in file names by the Unix shells or the DOS prompt.
+
+@noindent
+Examples of Naming Patterns are
+
+@smallexample
+ "*.[12].ada"
+ "*.ad[sb]*"
+ "body_*" "spec_*"
+@end smallexample
+
+@noindent
+For a more complete description of the syntax of Naming Patterns,
+see the second kind of regular expressions described in @file{g-regexp.ads}
+(the ``Glob'' regular expressions).
+
+@noindent
+When invoked with no switches, @code{gnatname} will create a configuration
+pragmas file @file{gnat.adc} in the current working directory, with pragmas
+@code{Source_File_Name} for each file that contains a valid Ada unit.
+
+@node Switches for gnatname
+@section Switches for @code{gnatname}
+
+@noindent
+Switches for @code{gnatname} must precede any specified Naming Pattern.
+
+@noindent
+You may specify any of the following switches to @code{gnatname}:
+
+@table @option
+@c !sort!
+
+@item ^-c^/CONFIG_FILE=^@file{file}
+@cindex @option{^-c^/CONFIG_FILE^} (@code{gnatname})
+Create a configuration pragmas file @file{file} (instead of the default
+@file{gnat.adc}).
+@ifclear vms
+There may be zero, one or more space between @option{-c} and
+@file{file}.
+@end ifclear
+@file{file} may include directory information. @file{file} must be
+writable. There may be only one switch @option{^-c^/CONFIG_FILE^}.
+When a switch @option{^-c^/CONFIG_FILE^} is
+specified, no switch @option{^-P^/PROJECT_FILE^} may be specified (see below).
+
+@item ^-d^/SOURCE_DIRS=^@file{dir}
+@cindex @option{^-d^/SOURCE_DIRS^} (@code{gnatname})
+Look for source files in directory @file{dir}. There may be zero, one or more
+spaces between @option{^-d^/SOURCE_DIRS=^} and @file{dir}.
+When a switch @option{^-d^/SOURCE_DIRS^}
+is specified, the current working directory will not be searched for source
+files, unless it is explicitly specified with a @option{^-d^/SOURCE_DIRS^}
+or @option{^-D^/DIR_FILES^} switch.
+Several switches @option{^-d^/SOURCE_DIRS^} may be specified.
+If @file{dir} is a relative path, it is relative to the directory of
+the configuration pragmas file specified with switch
+@option{^-c^/CONFIG_FILE^},
+or to the directory of the project file specified with switch
+@option{^-P^/PROJECT_FILE^} or,
+if neither switch @option{^-c^/CONFIG_FILE^}
+nor switch @option{^-P^/PROJECT_FILE^} are specified, it is relative to the
+current working directory. The directory
+specified with switch @option{^-d^/SOURCE_DIRS^} must exist and be readable.
+
+@item ^-D^/DIRS_FILE=^@file{file}
+@cindex @option{^-D^/DIRS_FILE^} (@code{gnatname})
+Look for source files in all directories listed in text file @file{file}.
+There may be zero, one or more spaces between @option{^-D^/DIRS_FILE=^}
+and @file{file}.
+@file{file} must be an existing, readable text file.
+Each non empty line in @file{file} must be a directory.
+Specifying switch @option{^-D^/DIRS_FILE^} is equivalent to specifying as many
+switches @option{^-d^/SOURCE_DIRS^} as there are non empty lines in
+@file{file}.
+
+@item ^-f^/FOREIGN_PATTERN=^@file{pattern}
+@cindex @option{^-f^/FOREIGN_PATTERN^} (@code{gnatname})
+Foreign patterns. Using this switch, it is possible to add sources of languages
+other than Ada to the list of sources of a project file.
+It is only useful if a ^-P^/PROJECT_FILE^ switch is used.
+For example,
+@smallexample
+gnatname ^-Pprj -f"*.c"^/PROJECT_FILE=PRJ /FOREIGN_PATTERN=*.C^ "*.ada"
+@end smallexample
+@noindent
+will look for Ada units in all files with the @file{.ada} extension,
+and will add to the list of file for project @file{prj.gpr} the C files
+with extension ".^c^C^".
+
+@item ^-h^/HELP^
+@cindex @option{^-h^/HELP^} (@code{gnatname})
+Output usage (help) information. The output is written to @file{stdout}.
+
+@item ^-P^/PROJECT_FILE=^@file{proj}
+@cindex @option{^-P^/PROJECT_FILE^} (@code{gnatname})
+Create or update project file @file{proj}. There may be zero, one or more space
+between @option{-P} and @file{proj}. @file{proj} may include directory
+information. @file{proj} must be writable.
+There may be only one switch @option{^-P^/PROJECT_FILE^}.
+When a switch @option{^-P^/PROJECT_FILE^} is specified,
+no switch @option{^-c^/CONFIG_FILE^} may be specified.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@code{gnatname})
+Verbose mode. Output detailed explanation of behavior to @file{stdout}.
+This includes name of the file written, the name of the directories to search
+and, for each file in those directories whose name matches at least one of
+the Naming Patterns, an indication of whether the file contains a unit,
+and if so the name of the unit.
+
+@item ^-v -v^/VERBOSE /VERBOSE^
+@cindex @option{^-v -v^/VERBOSE /VERBOSE^} (@code{gnatname})
+Very Verbose mode. In addition to the output produced in verbose mode,
+for each file in the searched directories whose name matches none of
+the Naming Patterns, an indication is given that there is no match.
+
+@item ^-x^/EXCLUDED_PATTERN=^@file{pattern}
+@cindex @option{^-x^/EXCLUDED_PATTERN^} (@code{gnatname})
+Excluded patterns. Using this switch, it is possible to exclude some files
+that would match the name patterns. For example,
+@smallexample
+gnatname ^-x "*_nt.ada"^/EXCLUDED_PATTERN=*_nt.ada^ "*.ada"
+@end smallexample
+@noindent
+will look for Ada units in all files with the @file{.ada} extension,
+except those whose names end with @file{_nt.ada}.
+
+@end table
+
+@node Examples of gnatname Usage
+@section Examples of @code{gnatname} Usage
+
+@ifset vms
+@smallexample
+$ gnatname /CONFIG_FILE=[HOME.ME]NAMES.ADC /SOURCE_DIRS=SOURCES "[a-z]*.ada*"
+@end smallexample
+@end ifset
+
+@ifclear vms
+@smallexample
+$ gnatname -c /home/me/names.adc -d sources "[a-z]*.ada*"
+@end smallexample
+@end ifclear
+
+@noindent
+In this example, the directory @file{^/home/me^[HOME.ME]^} must already exist
+and be writable. In addition, the directory
+@file{^/home/me/sources^[HOME.ME.SOURCES]^} (specified by
+@option{^-d sources^/SOURCE_DIRS=SOURCES^}) must exist and be readable.
+
+@ifclear vms
+Note the optional spaces after @option{-c} and @option{-d}.
+@end ifclear
+
+@smallexample
+@ifclear vms
+$ gnatname -P/home/me/proj -x "*_nt_body.ada"
+ -dsources -dsources/plus -Dcommon_dirs.txt "body_*" "spec_*"
+@end ifclear
+@ifset vms
+$ gnatname /PROJECT_FILE=[HOME.ME]PROJ
+ /EXCLUDED_PATTERN=*_nt_body.ada
+ /SOURCE_DIRS=(SOURCES,[SOURCES.PLUS])
+ /DIRS_FILE=COMMON_DIRS.TXT "body_*" "spec_*"
+@end ifset
+@end smallexample
+
+Note that several switches @option{^-d^/SOURCE_DIRS^} may be used,
+even in conjunction with one or several switches
+@option{^-D^/DIRS_FILE^}. Several Naming Patterns and one excluded pattern
+are used in this example.
+
+
+@c *****************************************
+@c * G N A T P r o j e c t M a n a g e r *
+@c *****************************************
+@node GNAT Project Manager
+@chapter GNAT Project Manager
+
+@menu
+* Introduction::
+* Examples of Project Files::
+* Project File Syntax::
+* Objects and Sources in Project Files::
+* Importing Projects::
+* Project Extension::
+* External References in Project Files::
+* Packages in Project Files::
+* Variables from Imported Projects::
+* Naming Schemes::
+* Library Projects::
+* Using Third-Party Libraries through Projects::
+* Stand-alone Library Projects::
+* Switches Related to Project Files::
+* Tools Supporting Project Files::
+* An Extended Example::
+* Project File Complete Syntax::
+@end menu
+
+@c ****************
+@c * Introduction *
+@c ****************
+
+@node Introduction
+@section Introduction
+
+@noindent
+This chapter describes GNAT's @emph{Project Manager}, a facility that allows
+you to manage complex builds involving a number of source files, directories,
+and compilation options for different system configurations. In particular,
+project files allow you to specify:
+@itemize @bullet
+@item
+The directory or set of directories containing the source files, and/or the
+names of the specific source files themselves
+@item
+The directory in which the compiler's output
+(@file{ALI} files, object files, tree files) is to be placed
+@item
+The directory in which the executable programs is to be placed
+@item
+^Switch^Switch^ settings for any of the project-enabled tools
+(@command{gnatmake}, compiler, binder, linker, @code{gnatls}, @code{gnatxref},
+@code{gnatfind}); you can apply these settings either globally or to individual
+compilation units.
+@item
+The source files containing the main subprogram(s) to be built
+@item
+The source programming language(s) (currently Ada and/or C)
+@item
+Source file naming conventions; you can specify these either globally or for
+individual compilation units
+@end itemize
+
+@menu
+* Project Files::
+@end menu
+
+@node Project Files
+@subsection Project Files
+
+@noindent
+Project files are written in a syntax close to that of Ada, using familiar
+notions such as packages, context clauses, declarations, default values,
+assignments, and inheritance. Finally, project files can be built
+hierarchically from other project files, simplifying complex system
+integration and project reuse.
+
+A @dfn{project} is a specific set of values for various compilation properties.
+The settings for a given project are described by means of
+a @dfn{project file}, which is a text file written in an Ada-like syntax.
+Property values in project files are either strings or lists of strings.
+Properties that are not explicitly set receive default values. A project
+file may interrogate the values of @dfn{external variables} (user-defined
+command-line switches or environment variables), and it may specify property
+settings conditionally, based on the value of such variables.
+
+In simple cases, a project's source files depend only on other source files
+in the same project, or on the predefined libraries. (@emph{Dependence} is
+used in
+the Ada technical sense; as in one Ada unit @code{with}ing another.) However,
+the Project Manager also allows more sophisticated arrangements,
+where the source files in one project depend on source files in other
+projects:
+@itemize @bullet
+@item
+One project can @emph{import} other projects containing needed source files.
+@item
+You can organize GNAT projects in a hierarchy: a @emph{child} project
+can extend a @emph{parent} project, inheriting the parent's source files and
+optionally overriding any of them with alternative versions
+@end itemize
+
+@noindent
+More generally, the Project Manager lets you structure large development
+efforts into hierarchical subsystems, where build decisions are delegated
+to the subsystem level, and thus different compilation environments
+(^switch^switch^ settings) used for different subsystems.
+
+The Project Manager is invoked through the
+@option{^-P^/PROJECT_FILE=^@emph{projectfile}}
+switch to @command{gnatmake} or to the @command{^gnat^GNAT^} front driver.
+@ifclear vms
+There may be zero, one or more spaces between @option{-P} and
+@option{@emph{projectfile}}.
+@end ifclear
+If you want to define (on the command line) an external variable that is
+queried by the project file, you must use the
+@option{^-X^/EXTERNAT_REFERENCE=^@emph{vbl}=@emph{value}} switch.
+The Project Manager parses and interprets the project file, and drives the
+invoked tool based on the project settings.
+
+The Project Manager supports a wide range of development strategies,
+for systems of all sizes. Here are some typical practices that are
+easily handled:
+@itemize @bullet
+@item
+Using a common set of source files, but generating object files in different
+directories via different ^switch^switch^ settings
+@item
+Using a mostly-shared set of source files, but with different versions of
+some unit or units
+@end itemize
+
+@noindent
+The destination of an executable can be controlled inside a project file
+using the @option{^-o^-o^}
+^switch^switch^.
+In the absence of such a ^switch^switch^ either inside
+the project file or on the command line, any executable files generated by
+@command{gnatmake} are placed in the directory @code{Exec_Dir} specified
+in the project file. If no @code{Exec_Dir} is specified, they will be placed
+in the object directory of the project.
+
+You can use project files to achieve some of the effects of a source
+versioning system (for example, defining separate projects for
+the different sets of sources that comprise different releases) but the
+Project Manager is independent of any source configuration management tools
+that might be used by the developers.
+
+The next section introduces the main features of GNAT's project facility
+through a sequence of examples; subsequent sections will present the syntax
+and semantics in more detail. A more formal description of the project
+facility appears in the GNAT Reference Manual.
+
+@c *****************************
+@c * Examples of Project Files *
+@c *****************************
+
+@node Examples of Project Files
+@section Examples of Project Files
+@noindent
+This section illustrates some of the typical uses of project files and
+explains their basic structure and behavior.
+
+@menu
+* Common Sources with Different ^Switches^Switches^ and Directories::
+* Using External Variables::
+* Importing Other Projects::
+* Extending a Project::
+@end menu
+
+@node Common Sources with Different ^Switches^Switches^ and Directories
+@subsection Common Sources with Different ^Switches^Switches^ and Directories
+
+@menu
+* Source Files::
+* Specifying the Object Directory::
+* Specifying the Exec Directory::
+* Project File Packages::
+* Specifying ^Switch^Switch^ Settings::
+* Main Subprograms::
+* Executable File Names::
+* Source File Naming Conventions::
+* Source Language(s)::
+@end menu
+
+@noindent
+Suppose that the Ada source files @file{pack.ads}, @file{pack.adb}, and
+@file{proc.adb} are in the @file{/common} directory. The file
+@file{proc.adb} contains an Ada main subprogram @code{Proc} that @code{with}s
+package @code{Pack}. We want to compile these source files under two sets
+of ^switches^switches^:
+@itemize @bullet
+@item
+When debugging, we want to pass the @option{-g} switch to @command{gnatmake},
+and the @option{^-gnata^-gnata^},
+@option{^-gnato^-gnato^},
+and @option{^-gnatE^-gnatE^} switches to the
+compiler; the compiler's output is to appear in @file{/common/debug}
+@item
+When preparing a release version, we want to pass the @option{^-O2^O2^} switch
+to the compiler; the compiler's output is to appear in @file{/common/release}
+@end itemize
+
+@noindent
+The GNAT project files shown below, respectively @file{debug.gpr} and
+@file{release.gpr} in the @file{/common} directory, achieve these effects.
+
+Schematically:
+@smallexample
+@group
+^/common^[COMMON]^
+ debug.gpr
+ release.gpr
+ pack.ads
+ pack.adb
+ proc.adb
+@end group
+@group
+^/common/debug^[COMMON.DEBUG]^
+ proc.ali, proc.o
+ pack.ali, pack.o
+@end group
+@group
+^/common/release^[COMMON.RELEASE]^
+ proc.ali, proc.o
+ pack.ali, pack.o
+@end group
+@end smallexample
+Here are the corresponding project files:
+
+@smallexample @c projectfile
+@group
+project Debug is
+ for Object_Dir use "debug";
+ for Main use ("proc");
+
+ package Builder is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-g^-g^");
+ for Executable ("proc.adb") use "proc1";
+ end Builder;
+@end group
+
+@group
+ package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("-fstack-check",
+ "^-gnata^-gnata^",
+ "^-gnato^-gnato^",
+ "^-gnatE^-gnatE^");
+ end Compiler;
+end Debug;
+@end group
+@end smallexample
+
+@smallexample @c projectfile
+@group
+project Release is
+ for Object_Dir use "release";
+ for Exec_Dir use ".";
+ for Main use ("proc");
+
+ package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-O2^-O2^");
+ end Compiler;
+end Release;
+@end group
+@end smallexample
+
+@noindent
+The name of the project defined by @file{debug.gpr} is @code{"Debug"} (case
+insensitive), and analogously the project defined by @file{release.gpr} is
+@code{"Release"}. For consistency the file should have the same name as the
+project, and the project file's extension should be @code{"gpr"}. These
+conventions are not required, but a warning is issued if they are not followed.
+
+If the current directory is @file{^/temp^[TEMP]^}, then the command
+@smallexample
+gnatmake ^-P/common/debug.gpr^/PROJECT_FILE=[COMMON]DEBUG^
+@end smallexample
+
+@noindent
+generates object and ALI files in @file{^/common/debug^[COMMON.DEBUG]^},
+as well as the @code{^proc1^PROC1.EXE^} executable,
+using the ^switch^switch^ settings defined in the project file.
+
+Likewise, the command
+@smallexample
+gnatmake ^-P/common/release.gpr^/PROJECT_FILE=[COMMON]RELEASE^
+@end smallexample
+
+@noindent
+generates object and ALI files in @file{^/common/release^[COMMON.RELEASE]^},
+and the @code{^proc^PROC.EXE^}
+executable in @file{^/common^[COMMON]^},
+using the ^switch^switch^ settings from the project file.
+
+@node Source Files
+@unnumberedsubsubsec Source Files
+
+@noindent
+If a project file does not explicitly specify a set of source directories or
+a set of source files, then by default the project's source files are the
+Ada source files in the project file directory. Thus @file{pack.ads},
+@file{pack.adb}, and @file{proc.adb} are the source files for both projects.
+
+@node Specifying the Object Directory
+@unnumberedsubsubsec Specifying the Object Directory
+
+@noindent
+Several project properties are modeled by Ada-style @emph{attributes};
+a property is defined by supplying the equivalent of an Ada attribute
+definition clause in the project file.
+A project's object directory is another such a property; the corresponding
+attribute is @code{Object_Dir}, and its value is also a string expression,
+specified either as absolute or relative. In the later case,
+it is relative to the project file directory. Thus the compiler's
+output is directed to @file{^/common/debug^[COMMON.DEBUG]^}
+(for the @code{Debug} project)
+and to @file{^/common/release^[COMMON.RELEASE]^}
+(for the @code{Release} project).
+If @code{Object_Dir} is not specified, then the default is the project file
+directory itself.
+
+@node Specifying the Exec Directory
+@unnumberedsubsubsec Specifying the Exec Directory
+
+@noindent
+A project's exec directory is another property; the corresponding
+attribute is @code{Exec_Dir}, and its value is also a string expression,
+either specified as relative or absolute. If @code{Exec_Dir} is not specified,
+then the default is the object directory (which may also be the project file
+directory if attribute @code{Object_Dir} is not specified). Thus the executable
+is placed in @file{^/common/debug^[COMMON.DEBUG]^}
+for the @code{Debug} project (attribute @code{Exec_Dir} not specified)
+and in @file{^/common^[COMMON]^} for the @code{Release} project.
+
+@node Project File Packages
+@unnumberedsubsubsec Project File Packages
+
+@noindent
+A GNAT tool that is integrated with the Project Manager is modeled by a
+corresponding package in the project file. In the example above,
+The @code{Debug} project defines the packages @code{Builder}
+(for @command{gnatmake}) and @code{Compiler};
+the @code{Release} project defines only the @code{Compiler} package.
+
+The Ada-like package syntax is not to be taken literally. Although packages in
+project files bear a surface resemblance to packages in Ada source code, the
+notation is simply a way to convey a grouping of properties for a named
+entity. Indeed, the package names permitted in project files are restricted
+to a predefined set, corresponding to the project-aware tools, and the contents
+of packages are limited to a small set of constructs.
+The packages in the example above contain attribute definitions.
+
+@node Specifying ^Switch^Switch^ Settings
+@unnumberedsubsubsec Specifying ^Switch^Switch^ Settings
+
+@noindent
+^Switch^Switch^ settings for a project-aware tool can be specified through
+attributes in the package that corresponds to the tool.
+The example above illustrates one of the relevant attributes,
+@code{^Default_Switches^Default_Switches^}, which is defined in packages
+in both project files.
+Unlike simple attributes like @code{Source_Dirs},
+@code{^Default_Switches^Default_Switches^} is
+known as an @emph{associative array}. When you define this attribute, you must
+supply an ``index'' (a literal string), and the effect of the attribute
+definition is to set the value of the array at the specified index.
+For the @code{^Default_Switches^Default_Switches^} attribute,
+the index is a programming language (in our case, Ada),
+and the value specified (after @code{use}) must be a list
+of string expressions.
+
+The attributes permitted in project files are restricted to a predefined set.
+Some may appear at project level, others in packages.
+For any attribute that is an associative array, the index must always be a
+literal string, but the restrictions on this string (e.g., a file name or a
+language name) depend on the individual attribute.
+Also depending on the attribute, its specified value will need to be either a
+string or a string list.
+
+In the @code{Debug} project, we set the switches for two tools,
+@command{gnatmake} and the compiler, and thus we include the two corresponding
+packages; each package defines the @code{^Default_Switches^Default_Switches^}
+attribute with index @code{"Ada"}.
+Note that the package corresponding to
+@command{gnatmake} is named @code{Builder}. The @code{Release} project is
+similar, but only includes the @code{Compiler} package.
+
+In project @code{Debug} above, the ^switches^switches^ starting with
+@option{-gnat} that are specified in package @code{Compiler}
+could have been placed in package @code{Builder}, since @command{gnatmake}
+transmits all such ^switches^switches^ to the compiler.
+
+@node Main Subprograms
+@unnumberedsubsubsec Main Subprograms
+
+@noindent
+One of the specifiable properties of a project is a list of files that contain
+main subprograms. This property is captured in the @code{Main} attribute,
+whose value is a list of strings. If a project defines the @code{Main}
+attribute, it is not necessary to identify the main subprogram(s) when
+invoking @command{gnatmake} (see @ref{gnatmake and Project Files}).
+
+@node Executable File Names
+@unnumberedsubsubsec Executable File Names
+
+@noindent
+By default, the executable file name corresponding to a main source is
+deducted from the main source file name. Through the attributes
+@code{Executable} and @code{Executable_Suffix} of package @code{Builder},
+it is possible to change this default.
+In project @code{Debug} above, the executable file name
+for main source @file{^proc.adb^PROC.ADB^} is
+@file{^proc1^PROC1.EXE^}.
+Attribute @code{Executable_Suffix}, when specified, may change the suffix
+of the the executable files, when no attribute @code{Executable} applies:
+its value replace the platform-specific executable suffix.
+Attributes @code{Executable} and @code{Executable_Suffix} are the only ways to
+specify a non default executable file name when several mains are built at once
+in a single @command{gnatmake} command.
+
+@node Source File Naming Conventions
+@unnumberedsubsubsec Source File Naming Conventions
+
+@noindent
+Since the project files above do not specify any source file naming
+conventions, the GNAT defaults are used. The mechanism for defining source
+file naming conventions -- a package named @code{Naming} --
+is described below (@pxref{Naming Schemes}).
+
+@node Source Language(s)
+@unnumberedsubsubsec Source Language(s)
+
+@noindent
+Since the project files do not specify a @code{Languages} attribute, by
+default the GNAT tools assume that the language of the project file is Ada.
+More generally, a project can comprise source files
+in Ada, C, and/or other languages.
+
+@node Using External Variables
+@subsection Using External Variables
+
+@noindent
+Instead of supplying different project files for debug and release, we can
+define a single project file that queries an external variable (set either
+on the command line or via an ^environment variable^logical name^) in order to
+conditionally define the appropriate settings. Again, assume that the
+source files @file{pack.ads}, @file{pack.adb}, and @file{proc.adb} are
+located in directory @file{^/common^[COMMON]^}. The following project file,
+@file{build.gpr}, queries the external variable named @code{STYLE} and
+defines an object directory and ^switch^switch^ settings based on whether
+the value is @code{"deb"} (debug) or @code{"rel"} (release), and where
+the default is @code{"deb"}.
+
+@smallexample @c projectfile
+@group
+project Build is
+ for Main use ("proc");
+
+ type Style_Type is ("deb", "rel");
+ Style : Style_Type := external ("STYLE", "deb");
+
+ case Style is
+ when "deb" =>
+ for Object_Dir use "debug";
+
+ when "rel" =>
+ for Object_Dir use "release";
+ for Exec_Dir use ".";
+ end case;
+@end group
+
+@group
+ package Builder is
+
+ case Style is
+ when "deb" =>
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-g^-g^");
+ for Executable ("proc") use "proc1";
+ when others =>
+ null;
+ end case;
+
+ end Builder;
+@end group
+
+@group
+ package Compiler is
+
+ case Style is
+ when "deb" =>
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-gnata^-gnata^",
+ "^-gnato^-gnato^",
+ "^-gnatE^-gnatE^");
+
+ when "rel" =>
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-O2^-O2^");
+ end case;
+
+ end Compiler;
+
+end Build;
+@end group
+@end smallexample
+
+@noindent
+@code{Style_Type} is an example of a @emph{string type}, which is the project
+file analog of an Ada enumeration type but whose components are string literals
+rather than identifiers. @code{Style} is declared as a variable of this type.
+
+The form @code{external("STYLE", "deb")} is known as an
+@emph{external reference}; its first argument is the name of an
+@emph{external variable}, and the second argument is a default value to be
+used if the external variable doesn't exist. You can define an external
+variable on the command line via the @option{^-X^/EXTERNAL_REFERENCE^} switch,
+or you can use ^an environment variable^a logical name^
+as an external variable.
+
+Each @code{case} construct is expanded by the Project Manager based on the
+value of @code{Style}. Thus the command
+@ifclear vms
+@smallexample
+gnatmake -P/common/build.gpr -XSTYLE=deb
+@end smallexample
+@end ifclear
+
+@ifset vms
+@smallexample
+gnatmake /PROJECT_FILE=[COMMON]BUILD.GPR /EXTERNAL_REFERENCE=STYLE=deb
+@end smallexample
+@end ifset
+
+@noindent
+is equivalent to the @command{gnatmake} invocation using the project file
+@file{debug.gpr} in the earlier example. So is the command
+@smallexample
+gnatmake ^-P/common/build.gpr^/PROJECT_FILE=[COMMON]BUILD.GPR^
+@end smallexample
+
+@noindent
+since @code{"deb"} is the default for @code{STYLE}.
+
+Analogously,
+
+@ifclear vms
+@smallexample
+gnatmake -P/common/build.gpr -XSTYLE=rel
+@end smallexample
+@end ifclear
+
+@ifset vms
+@smallexample
+GNAT MAKE /PROJECT_FILE=[COMMON]BUILD.GPR /EXTERNAL_REFERENCE=STYLE=rel
+@end smallexample
+@end ifset
+
+@noindent
+is equivalent to the @command{gnatmake} invocation using the project file
+@file{release.gpr} in the earlier example.
+
+@node Importing Other Projects
+@subsection Importing Other Projects
+
+@noindent
+A compilation unit in a source file in one project may depend on compilation
+units in source files in other projects. To compile this unit under
+control of a project file, the
+dependent project must @emph{import} the projects containing the needed source
+files.
+This effect is obtained using syntax similar to an Ada @code{with} clause,
+but where @code{with}ed entities are strings that denote project files.
+
+As an example, suppose that the two projects @code{GUI_Proj} and
+@code{Comm_Proj} are defined in the project files @file{gui_proj.gpr} and
+@file{comm_proj.gpr} in directories @file{^/gui^[GUI]^}
+and @file{^/comm^[COMM]^}, respectively.
+Suppose that the source files for @code{GUI_Proj} are
+@file{gui.ads} and @file{gui.adb}, and that the source files for
+@code{Comm_Proj} are @file{comm.ads} and @file{comm.adb}, where each set of
+files is located in its respective project file directory. Schematically:
+
+@smallexample
+@group
+^/gui^[GUI]^
+ gui_proj.gpr
+ gui.ads
+ gui.adb
+@end group
+
+@group
+^/comm^[COMM]^
+ comm_proj.gpr
+ comm.ads
+ comm.adb
+@end group
+@end smallexample
+
+@noindent
+We want to develop an application in directory @file{^/app^[APP]^} that
+@code{with} the packages @code{GUI} and @code{Comm}, using the properties of
+the corresponding project files (e.g. the ^switch^switch^ settings
+and object directory).
+Skeletal code for a main procedure might be something like the following:
+
+@smallexample @c ada
+@group
+with GUI, Comm;
+procedure App_Main is
+ ...
+begin
+ ...
+end App_Main;
+@end group
+@end smallexample
+
+@noindent
+Here is a project file, @file{app_proj.gpr}, that achieves the desired
+effect:
+
+@smallexample @c projectfile
+@group
+with "/gui/gui_proj", "/comm/comm_proj";
+project App_Proj is
+ for Main use ("app_main");
+end App_Proj;
+@end group
+@end smallexample
+
+@noindent
+Building an executable is achieved through the command:
+@smallexample
+gnatmake ^-P/app/app_proj^/PROJECT_FILE=[APP]APP_PROJ^
+@end smallexample
+@noindent
+which will generate the @code{^app_main^APP_MAIN.EXE^} executable
+in the directory where @file{app_proj.gpr} resides.
+
+If an imported project file uses the standard extension (@code{^gpr^GPR^}) then
+(as illustrated above) the @code{with} clause can omit the extension.
+
+Our example specified an absolute path for each imported project file.
+Alternatively, the directory name of an imported object can be omitted
+if either
+@itemize @bullet
+@item
+The imported project file is in the same directory as the importing project
+file, or
+@item
+You have defined ^an environment variable^a logical name^
+that includes the directory containing
+the needed project file. The syntax of @code{ADA_PROJECT_PATH} is the same as
+the syntax of @code{ADA_INCLUDE_PATH} and @code{ADA_OBJECTS_PATH}: a list of
+directory names separated by colons (semicolons on Windows).
+@end itemize
+
+@noindent
+Thus, if we define @code{ADA_PROJECT_PATH} to include @file{^/gui^[GUI]^} and
+@file{^/comm^[COMM]^}, then our project file @file{app_proj.gpr} can be written
+as follows:
+
+@smallexample @c projectfile
+@group
+with "gui_proj", "comm_proj";
+project App_Proj is
+ for Main use ("app_main");
+end App_Proj;
+@end group
+@end smallexample
+
+@noindent
+Importing other projects can create ambiguities.
+For example, the same unit might be present in different imported projects, or
+it might be present in both the importing project and in an imported project.
+Both of these conditions are errors. Note that in the current version of
+the Project Manager, it is illegal to have an ambiguous unit even if the
+unit is never referenced by the importing project. This restriction may be
+relaxed in a future release.
+
+@node Extending a Project
+@subsection Extending a Project
+
+@noindent
+In large software systems it is common to have multiple
+implementations of a common interface; in Ada terms, multiple versions of a
+package body for the same specification. For example, one implementation
+might be safe for use in tasking programs, while another might only be used
+in sequential applications. This can be modeled in GNAT using the concept
+of @emph{project extension}. If one project (the ``child'') @emph{extends}
+another project (the ``parent'') then by default all source files of the
+parent project are inherited by the child, but the child project can
+override any of the parent's source files with new versions, and can also
+add new files. This facility is the project analog of a type extension in
+Object-Oriented Programming. Project hierarchies are permitted (a child
+project may be the parent of yet another project), and a project that
+inherits one project can also import other projects.
+
+As an example, suppose that directory @file{^/seq^[SEQ]^} contains the project
+file @file{seq_proj.gpr} as well as the source files @file{pack.ads},
+@file{pack.adb}, and @file{proc.adb}:
+
+@smallexample
+@group
+^/seq^[SEQ]^
+ pack.ads
+ pack.adb
+ proc.adb
+ seq_proj.gpr
+@end group
+@end smallexample
+
+@noindent
+Note that the project file can simply be empty (that is, no attribute or
+package is defined):
+
+@smallexample @c projectfile
+@group
+project Seq_Proj is
+end Seq_Proj;
+@end group
+@end smallexample
+
+@noindent
+implying that its source files are all the Ada source files in the project
+directory.
+
+Suppose we want to supply an alternate version of @file{pack.adb}, in
+directory @file{^/tasking^[TASKING]^}, but use the existing versions of
+@file{pack.ads} and @file{proc.adb}. We can define a project
+@code{Tasking_Proj} that inherits @code{Seq_Proj}:
+
+@smallexample
+@group
+^/tasking^[TASKING]^
+ pack.adb
+ tasking_proj.gpr
+@end group
+
+@group
+project Tasking_Proj extends "/seq/seq_proj" is
+end Tasking_Proj;
+@end group
+@end smallexample
+
+@noindent
+The version of @file{pack.adb} used in a build depends on which project file
+is specified.
+
+Note that we could have obtained the desired behavior using project import
+rather than project inheritance; a @code{base} project would contain the
+sources for @file{pack.ads} and @file{proc.adb}, a sequential project would
+import @code{base} and add @file{pack.adb}, and likewise a tasking project
+would import @code{base} and add a different version of @file{pack.adb}. The
+choice depends on whether other sources in the original project need to be
+overridden. If they do, then project extension is necessary, otherwise,
+importing is sufficient.
+
+@noindent
+In a project file that extends another project file, it is possible to
+indicate that an inherited source is not part of the sources of the extending
+project. This is necessary sometimes when a package spec has been overloaded
+and no longer requires a body: in this case, it is necessary to indicate that
+the inherited body is not part of the sources of the project, otherwise there
+will be a compilation error when compiling the spec.
+
+For that purpose, the attribute @code{Locally_Removed_Files} is used.
+Its value is a string list: a list of file names.
+
+@smallexample @c @projectfile
+project B extends "a" is
+ for Source_Files use ("pkg.ads");
+ -- New spec of Pkg does not need a completion
+ for Locally_Removed_Files use ("pkg.adb");
+end B;
+@end smallexample
+
+Attribute @code{Locally_Removed_Files} may also be used to check if a source
+is still needed: if it is possible to build using @code{gnatmake} when such
+a source is put in attribute @code{Locally_Removed_Files} of a project P, then
+it is possible to remove the source completely from a system that includes
+project P.
+
+@c ***********************
+@c * Project File Syntax *
+@c ***********************
+
+@node Project File Syntax
+@section Project File Syntax
+
+@menu
+* Basic Syntax::
+* Packages::
+* Expressions::
+* String Types::
+* Variables::
+* Attributes::
+* Associative Array Attributes::
+* case Constructions::
+@end menu
+
+@noindent
+This section describes the structure of project files.
+
+A project may be an @emph{independent project}, entirely defined by a single
+project file. Any Ada source file in an independent project depends only
+on the predefined library and other Ada source files in the same project.
+
+@noindent
+A project may also @dfn{depend on} other projects, in either or both of
+the following ways:
+@itemize @bullet
+@item It may import any number of projects
+@item It may extend at most one other project
+@end itemize
+
+@noindent
+The dependence relation is a directed acyclic graph (the subgraph reflecting
+the ``extends'' relation is a tree).
+
+A project's @dfn{immediate sources} are the source files directly defined by
+that project, either implicitly by residing in the project file's directory,
+or explicitly through any of the source-related attributes described below.
+More generally, a project @var{proj}'s @dfn{sources} are the immediate sources
+of @var{proj} together with the immediate sources (unless overridden) of any
+project on which @var{proj} depends (either directly or indirectly).
+
+@node Basic Syntax
+@subsection Basic Syntax
+
+@noindent
+As seen in the earlier examples, project files have an Ada-like syntax.
+The minimal project file is:
+@smallexample @c projectfile
+@group
+project Empty is
+
+end Empty;
+@end group
+@end smallexample
+
+@noindent
+The identifier @code{Empty} is the name of the project.
+This project name must be present after the reserved
+word @code{end} at the end of the project file, followed by a semi-colon.
+
+Any name in a project file, such as the project name or a variable name,
+has the same syntax as an Ada identifier.
+
+The reserved words of project files are the Ada reserved words plus
+@code{extends}, @code{external}, and @code{project}. Note that the only Ada
+reserved words currently used in project file syntax are:
+
+@itemize @bullet
+@item
+@code{case}
+@item
+@code{end}
+@item
+@code{for}
+@item
+@code{is}
+@item
+@code{others}
+@item
+@code{package}
+@item
+@code{renames}
+@item
+@code{type}
+@item
+@code{use}
+@item
+@code{when}
+@item
+@code{with}
+@end itemize
+
+@noindent
+Comments in project files have the same syntax as in Ada, two consecutives
+hyphens through the end of the line.
+
+@node Packages
+@subsection Packages
+
+@noindent
+A project file may contain @emph{packages}. The name of a package must be one
+of the identifiers from the following list. A package
+with a given name may only appear once in a project file. Package names are
+case insensitive. The following package names are legal:
+
+@itemize @bullet
+@item
+@code{Naming}
+@item
+@code{Builder}
+@item
+@code{Compiler}
+@item
+@code{Binder}
+@item
+@code{Linker}
+@item
+@code{Finder}
+@item
+@code{Cross_Reference}
+@item
+@code{Eliminate}
+@item
+@code{gnatls}
+@item
+@code{gnatstub}
+@item
+@code{IDE}
+@end itemize
+
+@noindent
+In its simplest form, a package may be empty:
+
+@smallexample @c projectfile
+@group
+project Simple is
+ package Builder is
+ end Builder;
+end Simple;
+@end group
+@end smallexample
+
+@noindent
+A package may contain @emph{attribute declarations},
+@emph{variable declarations} and @emph{case constructions}, as will be
+described below.
+
+When there is ambiguity between a project name and a package name,
+the name always designates the project. To avoid possible confusion, it is
+always a good idea to avoid naming a project with one of the
+names allowed for packages or any name that starts with @code{gnat}.
+
+@node Expressions
+@subsection Expressions
+
+@noindent
+An @emph{expression} is either a @emph{string expression} or a
+@emph{string list expression}.
+
+A @emph{string expression} is either a @emph{simple string expression} or a
+@emph{compound string expression}.
+
+A @emph{simple string expression} is one of the following:
+@itemize @bullet
+@item A literal string; e.g.@code{"comm/my_proj.gpr"}
+@item A string-valued variable reference (see @ref{Variables})
+@item A string-valued attribute reference (see @ref{Attributes})
+@item An external reference (see @ref{External References in Project Files})
+@end itemize
+
+@noindent
+A @emph{compound string expression} is a concatenation of string expressions,
+using the operator @code{"&"}
+@smallexample
+ Path & "/" & File_Name & ".ads"
+@end smallexample
+
+@noindent
+A @emph{string list expression} is either a
+@emph{simple string list expression} or a
+@emph{compound string list expression}.
+
+A @emph{simple string list expression} is one of the following:
+@itemize @bullet
+@item A parenthesized list of zero or more string expressions,
+separated by commas
+@smallexample
+ File_Names := (File_Name, "gnat.adc", File_Name & ".orig");
+ Empty_List := ();
+@end smallexample
+@item A string list-valued variable reference
+@item A string list-valued attribute reference
+@end itemize
+
+@noindent
+A @emph{compound string list expression} is the concatenation (using
+@code{"&"}) of a simple string list expression and an expression. Note that
+each term in a compound string list expression, except the first, may be
+either a string expression or a string list expression.
+
+@smallexample @c projectfile
+@group
+ File_Name_List := () & File_Name; -- One string in this list
+ Extended_File_Name_List := File_Name_List & (File_Name & ".orig");
+ -- Two strings
+ Big_List := File_Name_List & Extended_File_Name_List;
+ -- Concatenation of two string lists: three strings
+ Illegal_List := "gnat.adc" & Extended_File_Name_List;
+ -- Illegal: must start with a string list
+@end group
+@end smallexample
+
+@node String Types
+@subsection String Types
+
+@noindent
+A @emph{string type declaration} introduces a discrete set of string literals.
+If a string variable is declared to have this type, its value
+is restricted to the given set of literals.
+
+Here is an example of a string type declaration:
+
+@smallexample @c projectfile
+ type OS is ("NT", "nt", "Unix", "GNU/Linux", "other OS");
+@end smallexample
+
+@noindent
+Variables of a string type are called @emph{typed variables}; all other
+variables are called @emph{untyped variables}. Typed variables are
+particularly useful in @code{case} constructions, to support conditional
+attribute declarations.
+(see @ref{case Constructions}).
+
+The string literals in the list are case sensitive and must all be different.
+They may include any graphic characters allowed in Ada, including spaces.
+
+A string type may only be declared at the project level, not inside a package.
+
+A string type may be referenced by its name if it has been declared in the same
+project file, or by an expanded name whose prefix is the name of the project
+in which it is declared.
+
+@node Variables
+@subsection Variables
+
+@noindent
+A variable may be declared at the project file level, or within a package.
+Here are some examples of variable declarations:
+
+@smallexample @c projectfile
+@group
+ This_OS : OS := external ("OS"); -- a typed variable declaration
+ That_OS := "GNU/Linux"; -- an untyped variable declaration
+@end group
+@end smallexample
+
+@noindent
+The syntax of a @emph{typed variable declaration} is identical to the Ada
+syntax for an object declaration. By contrast, the syntax of an untyped
+variable declaration is identical to an Ada assignment statement. In fact,
+variable declarations in project files have some of the characteristics of
+an assignment, in that successive declarations for the same variable are
+allowed. Untyped variable declarations do establish the expected kind of the
+variable (string or string list), and successive declarations for it must
+respect the initial kind.
+
+@noindent
+A string variable declaration (typed or untyped) declares a variable
+whose value is a string. This variable may be used as a string expression.
+@smallexample @c projectfile
+ File_Name := "readme.txt";
+ Saved_File_Name := File_Name & ".saved";
+@end smallexample
+
+@noindent
+A string list variable declaration declares a variable whose value is a list
+of strings. The list may contain any number (zero or more) of strings.
+
+@smallexample @c projectfile
+ Empty_List := ();
+ List_With_One_Element := ("^-gnaty^-gnaty^");
+ List_With_Two_Elements := List_With_One_Element & "^-gnatg^-gnatg^";
+ Long_List := ("main.ada", "pack1_.ada", "pack1.ada", "pack2_.ada"
+ "pack2.ada", "util_.ada", "util.ada");
+@end smallexample
+
+@noindent
+The same typed variable may not be declared more than once at project level,
+and it may not be declared more than once in any package; it is in effect
+a constant.
+
+The same untyped variable may be declared several times. Declarations are
+elaborated in the order in which they appear, so the new value replaces
+the old one, and any subsequent reference to the variable uses the new value.
+However, as noted above, if a variable has been declared as a string, all
+subsequent
+declarations must give it a string value. Similarly, if a variable has
+been declared as a string list, all subsequent declarations
+must give it a string list value.
+
+A @emph{variable reference} may take several forms:
+
+@itemize @bullet
+@item The simple variable name, for a variable in the current package (if any)
+or in the current project
+@item An expanded name, whose prefix is a context name.
+@end itemize
+
+@noindent
+A @emph{context} may be one of the following:
+
+@itemize @bullet
+@item The name of an existing package in the current project
+@item The name of an imported project of the current project
+@item The name of an ancestor project (i.e., a project extended by the current
+project, either directly or indirectly)
+@item An expanded name whose prefix is an imported/parent project name, and
+whose selector is a package name in that project.
+@end itemize
+
+@noindent
+A variable reference may be used in an expression.
+
+@node Attributes
+@subsection Attributes
+
+@noindent
+A project (and its packages) may have @emph{attributes} that define
+the project's properties. Some attributes have values that are strings;
+others have values that are string lists.
+
+There are two categories of attributes: @emph{simple attributes}
+and @emph{associative arrays} (see @ref{Associative Array Attributes}).
+
+Legal project attribute names, and attribute names for each legal package are
+listed below. Attributes names are case-insensitive.
+
+The following attributes are defined on projects (all are simple attributes):
+
+@multitable @columnfractions .4 .3
+@item @emph{Attribute Name}
+@tab @emph{Value}
+@item @code{Source_Files}
+@tab string list
+@item @code{Source_Dirs}
+@tab string list
+@item @code{Source_List_File}
+@tab string
+@item @code{Object_Dir}
+@tab string
+@item @code{Exec_Dir}
+@tab string
+@item @code{Locally_Removed_Files}
+@tab string list
+@item @code{Main}
+@tab string list
+@item @code{Languages}
+@tab string list
+@item @code{Main_Language}
+@tab string
+@item @code{Library_Dir}
+@tab string
+@item @code{Library_Name}
+@tab string
+@item @code{Library_Kind}
+@tab string
+@item @code{Library_Version}
+@tab string
+@item @code{Library_Interface}
+@tab string
+@item @code{Library_Auto_Init}
+@tab string
+@item @code{Library_Options}
+@tab string list
+@item @code{Library_GCC}
+@tab string
+@end multitable
+
+@noindent
+The following attributes are defined for package @code{Naming}
+(see @ref{Naming Schemes}):
+
+@multitable @columnfractions .4 .2 .2 .2
+@item Attribute Name @tab Category @tab Index @tab Value
+@item @code{Spec_Suffix}
+@tab associative array
+@tab language name
+@tab string
+@item @code{Body_Suffix}
+@tab associative array
+@tab language name
+@tab string
+@item @code{Separate_Suffix}
+@tab simple attribute
+@tab n/a
+@tab string
+@item @code{Casing}
+@tab simple attribute
+@tab n/a
+@tab string
+@item @code{Dot_Replacement}
+@tab simple attribute
+@tab n/a
+@tab string
+@item @code{Spec}
+@tab associative array
+@tab Ada unit name
+@tab string
+@item @code{Body}
+@tab associative array
+@tab Ada unit name
+@tab string
+@item @code{Specification_Exceptions}
+@tab associative array
+@tab language name
+@tab string list
+@item @code{Implementation_Exceptions}
+@tab associative array
+@tab language name
+@tab string list
+@end multitable
+
+@noindent
+The following attributes are defined for packages @code{Builder},
+@code{Compiler}, @code{Binder},
+@code{Linker}, @code{Cross_Reference}, and @code{Finder}
+(see @ref{^Switches^Switches^ and Project Files}).
+
+@multitable @columnfractions .4 .2 .2 .2
+@item Attribute Name @tab Category @tab Index @tab Value
+@item @code{^Default_Switches^Default_Switches^}
+@tab associative array
+@tab language name
+@tab string list
+@item @code{^Switches^Switches^}
+@tab associative array
+@tab file name
+@tab string list
+@end multitable
+
+@noindent
+In addition, package @code{Compiler} has a single string attribute
+@code{Local_Configuration_Pragmas} and package @code{Builder} has a single
+string attribute @code{Global_Configuration_Pragmas}.
+
+@noindent
+Each simple attribute has a default value: the empty string (for string-valued
+attributes) and the empty list (for string list-valued attributes).
+
+An attribute declaration defines a new value for an attribute.
+
+Examples of simple attribute declarations:
+
+@smallexample @c projectfile
+ for Object_Dir use "objects";
+ for Source_Dirs use ("units", "test/drivers");
+@end smallexample
+
+@noindent
+The syntax of a @dfn{simple attribute declaration} is similar to that of an
+attribute definition clause in Ada.
+
+Attributes references may be appear in expressions.
+The general form for such a reference is @code{<entity>'<attribute>}:
+Associative array attributes are functions. Associative
+array attribute references must have an argument that is a string literal.
+
+Examples are:
+
+@smallexample @c projectfile
+ project'Object_Dir
+ Naming'Dot_Replacement
+ Imported_Project'Source_Dirs
+ Imported_Project.Naming'Casing
+ Builder'^Default_Switches^Default_Switches^("Ada")
+@end smallexample
+
+@noindent
+The prefix of an attribute may be:
+@itemize @bullet
+@item @code{project} for an attribute of the current project
+@item The name of an existing package of the current project
+@item The name of an imported project
+@item The name of a parent project that is extended by the current project
+@item An expanded name whose prefix is imported/parent project name,
+ and whose selector is a package name
+@end itemize
+
+@noindent
+Example:
+@smallexample @c projectfile
+@group
+ project Prj is
+ for Source_Dirs use project'Source_Dirs & "units";
+ for Source_Dirs use project'Source_Dirs & "test/drivers"
+ end Prj;
+@end group
+@end smallexample
+
+@noindent
+In the first attribute declaration, initially the attribute @code{Source_Dirs}
+has the default value: an empty string list. After this declaration,
+@code{Source_Dirs} is a string list of one element: @code{"units"}.
+After the second attribute declaration @code{Source_Dirs} is a string list of
+two elements: @code{"units"} and @code{"test/drivers"}.
+
+Note: this example is for illustration only. In practice,
+the project file would contain only one attribute declaration:
+
+@smallexample @c projectfile
+ for Source_Dirs use ("units", "test/drivers");
+@end smallexample
+
+@node Associative Array Attributes
+@subsection Associative Array Attributes
+
+@noindent
+Some attributes are defined as @emph{associative arrays}. An associative
+array may be regarded as a function that takes a string as a parameter
+and delivers a string or string list value as its result.
+
+Here are some examples of single associative array attribute associations:
+
+@smallexample @c projectfile
+ for Body ("main") use "Main.ada";
+ for ^Switches^Switches^ ("main.ada")
+ use ("^-v^-v^",
+ "^-gnatv^-gnatv^");
+ for ^Switches^Switches^ ("main.ada")
+ use Builder'^Switches^Switches^ ("main.ada")
+ & "^-g^-g^";
+@end smallexample
+
+@noindent
+Like untyped variables and simple attributes, associative array attributes
+may be declared several times. Each declaration supplies a new value for the
+attribute, and replaces the previous setting.
+
+@noindent
+An associative array attribute may be declared as a full associative array
+declaration, with the value of the same attribute in an imported or extended
+project.
+
+@smallexample @c projectfile
+ package Builder is
+ for Default_Switches use Default.Builder'Default_Switches;
+ end Builder;
+@end smallexample
+
+@noindent
+In this example, @code{Default} must be either an project imported by the
+current project, or the project that the current project extends. If the
+attribute is in a package (in this case, in package @code{Builder}), the same
+package needs to be specified.
+
+@noindent
+A full associative array declaration replaces any other declaration for the
+attribute, including other full associative array declaration. Single
+associative array associations may be declare after a full associative
+declaration, modifying the value for a single association of the attribute.
+
+@node case Constructions
+@subsection @code{case} Constructions
+
+@noindent
+A @code{case} construction is used in a project file to effect conditional
+behavior.
+Here is a typical example:
+
+@smallexample @c projectfile
+@group
+project MyProj is
+ type OS_Type is ("GNU/Linux", "Unix", "NT", "VMS");
+
+ OS : OS_Type := external ("OS", "GNU/Linux");
+@end group
+
+@group
+ package Compiler is
+ case OS is
+ when "GNU/Linux" | "Unix" =>
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-gnath^-gnath^");
+ when "NT" =>
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-gnatP^-gnatP^");
+ when others =>
+ end case;
+ end Compiler;
+end MyProj;
+@end group
+@end smallexample
+
+@noindent
+The syntax of a @code{case} construction is based on the Ada case statement
+(although there is no @code{null} construction for empty alternatives).
+
+The case expression must a typed string variable.
+Each alternative comprises the reserved word @code{when}, either a list of
+literal strings separated by the @code{"|"} character or the reserved word
+@code{others}, and the @code{"=>"} token.
+Each literal string must belong to the string type that is the type of the
+case variable.
+An @code{others} alternative, if present, must occur last.
+
+After each @code{=>}, there are zero or more constructions. The only
+constructions allowed in a case construction are other case constructions and
+attribute declarations. String type declarations, variable declarations and
+package declarations are not allowed.
+
+The value of the case variable is often given by an external reference
+(see @ref{External References in Project Files}).
+
+@c ****************************************
+@c * Objects and Sources in Project Files *
+@c ****************************************
+
+@node Objects and Sources in Project Files
+@section Objects and Sources in Project Files
+
+@menu
+* Object Directory::
+* Exec Directory::
+* Source Directories::
+* Source File Names::
+@end menu
+
+@noindent
+Each project has exactly one object directory and one or more source
+directories. The source directories must contain at least one source file,
+unless the project file explicitly specifies that no source files are present
+(see @ref{Source File Names}).
+
+@node Object Directory
+@subsection Object Directory
+
+@noindent
+The object directory for a project is the directory containing the compiler's
+output (such as @file{ALI} files and object files) for the project's immediate
+sources.
+
+The object directory is given by the value of the attribute @code{Object_Dir}
+in the project file.
+
+@smallexample @c projectfile
+ for Object_Dir use "objects";
+@end smallexample
+
+@noindent
+The attribute @var{Object_Dir} has a string value, the path name of the object
+directory. The path name may be absolute or relative to the directory of the
+project file. This directory must already exist, and be readable and writable.
+
+By default, when the attribute @code{Object_Dir} is not given an explicit value
+or when its value is the empty string, the object directory is the same as the
+directory containing the project file.
+
+@node Exec Directory
+@subsection Exec Directory
+
+@noindent
+The exec directory for a project is the directory containing the executables
+for the project's main subprograms.
+
+The exec directory is given by the value of the attribute @code{Exec_Dir}
+in the project file.
+
+@smallexample @c projectfile
+ for Exec_Dir use "executables";
+@end smallexample
+
+@noindent
+The attribute @var{Exec_Dir} has a string value, the path name of the exec
+directory. The path name may be absolute or relative to the directory of the
+project file. This directory must already exist, and be writable.
+
+By default, when the attribute @code{Exec_Dir} is not given an explicit value
+or when its value is the empty string, the exec directory is the same as the
+object directory of the project file.
+
+@node Source Directories
+@subsection Source Directories
+
+@noindent
+The source directories of a project are specified by the project file
+attribute @code{Source_Dirs}.
+
+This attribute's value is a string list. If the attribute is not given an
+explicit value, then there is only one source directory, the one where the
+project file resides.
+
+A @code{Source_Dirs} attribute that is explicitly defined to be the empty list,
+as in
+
+@smallexample @c projectfile
+ for Source_Dirs use ();
+@end smallexample
+
+@noindent
+indicates that the project contains no source files.
+
+Otherwise, each string in the string list designates one or more
+source directories.
+
+@smallexample @c projectfile
+ for Source_Dirs use ("sources", "test/drivers");
+@end smallexample
+
+@noindent
+If a string in the list ends with @code{"/**"}, then the directory whose path
+name precedes the two asterisks, as well as all its subdirectories
+(recursively), are source directories.
+
+@smallexample @c projectfile
+ for Source_Dirs use ("/system/sources/**");
+@end smallexample
+
+@noindent
+Here the directory @code{/system/sources} and all of its subdirectories
+(recursively) are source directories.
+
+To specify that the source directories are the directory of the project file
+and all of its subdirectories, you can declare @code{Source_Dirs} as follows:
+@smallexample @c projectfile
+ for Source_Dirs use ("./**");
+@end smallexample
+
+@noindent
+Each of the source directories must exist and be readable.
+
+@node Source File Names
+@subsection Source File Names
+
+@noindent
+In a project that contains source files, their names may be specified by the
+attributes @code{Source_Files} (a string list) or @code{Source_List_File}
+(a string). Source file names never include any directory information.
+
+If the attribute @code{Source_Files} is given an explicit value, then each
+element of the list is a source file name.
+
+@smallexample @c projectfile
+ for Source_Files use ("main.adb");
+ for Source_Files use ("main.adb", "pack1.ads", "pack2.adb");
+@end smallexample
+
+@noindent
+If the attribute @code{Source_Files} is not given an explicit value,
+but the attribute @code{Source_List_File} is given a string value,
+then the source file names are contained in the text file whose path name
+(absolute or relative to the directory of the project file) is the
+value of the attribute @code{Source_List_File}.
+
+Each line in the file that is not empty or is not a comment
+contains a source file name.
+
+@smallexample @c projectfile
+ for Source_List_File use "source_list.txt";
+@end smallexample
+
+@noindent
+By default, if neither the attribute @code{Source_Files} nor the attribute
+@code{Source_List_File} is given an explicit value, then each file in the
+source directories that conforms to the project's naming scheme
+(see @ref{Naming Schemes}) is an immediate source of the project.
+
+A warning is issued if both attributes @code{Source_Files} and
+@code{Source_List_File} are given explicit values. In this case, the attribute
+@code{Source_Files} prevails.
+
+Each source file name must be the name of one existing source file
+in one of the source directories.
+
+A @code{Source_Files} attribute whose value is an empty list
+indicates that there are no source files in the project.
+
+If the order of the source directories is known statically, that is if
+@code{"/**"} is not used in the string list @code{Source_Dirs}, then there may
+be several files with the same source file name. In this case, only the file
+in the first directory is considered as an immediate source of the project
+file. If the order of the source directories is not known statically, it is
+an error to have several files with the same source file name.
+
+Projects can be specified to have no Ada source
+files: the value of (@code{Source_Dirs} or @code{Source_Files} may be an empty
+list, or the @code{"Ada"} may be absent from @code{Languages}:
+
+@smallexample @c projectfile
+ for Source_Dirs use ();
+ for Source_Files use ();
+ for Languages use ("C", "C++");
+@end smallexample
+
+@noindent
+Otherwise, a project must contain at least one immediate source.
+
+Projects with no source files are useful as template packages
+(see @ref{Packages in Project Files}) for other projects; in particular to
+define a package @code{Naming} (see @ref{Naming Schemes}).
+
+@c ****************************
+@c * Importing Projects *
+@c ****************************
+
+@node Importing Projects
+@section Importing Projects
+
+@noindent
+An immediate source of a project P may depend on source files that
+are neither immediate sources of P nor in the predefined library.
+To get this effect, P must @emph{import} the projects that contain the needed
+source files.
+
+@smallexample @c projectfile
+@group
+ with "project1", "utilities.gpr";
+ with "/namings/apex.gpr";
+ project Main is
+ ...
+@end group
+@end smallexample
+
+@noindent
+As can be seen in this example, the syntax for importing projects is similar
+to the syntax for importing compilation units in Ada. However, project files
+use literal strings instead of names, and the @code{with} clause identifies
+project files rather than packages.
+
+Each literal string is the file name or path name (absolute or relative) of a
+project file. If a string is simply a file name, with no path, then its
+location is determined by the @emph{project path}:
+
+@itemize @bullet
+@item
+If the ^environment variable^logical name^ @env{ADA_PROJECT_PATH} exists,
+then the project path includes all the directories in this
+^environment variable^logical name^, plus the directory of the project file.
+
+@item
+If the ^environment variable^logical name^ @env{ADA_PROJECT_PATH} does not
+exist, then the project path contains only one directory, namely the one where
+the project file is located.
+@end itemize
+
+@noindent
+If a relative pathname is used, as in
+
+@smallexample @c projectfile
+ with "tests/proj";
+@end smallexample
+
+@noindent
+then the path is relative to the directory where the importing project file is
+located. Any symbolic link will be fully resolved in the directory
+of the importing project file before the imported project file is examined.
+
+If the @code{with}'ed project file name does not have an extension,
+the default is @file{^.gpr^.GPR^}. If a file with this extension is not found,
+then the file name as specified in the @code{with} clause (no extension) will
+be used. In the above example, if a file @code{project1.gpr} is found, then it
+will be used; otherwise, if a file @code{^project1^PROJECT1^} exists
+then it will be used; if neither file exists, this is an error.
+
+A warning is issued if the name of the project file does not match the
+name of the project; this check is case insensitive.
+
+Any source file that is an immediate source of the imported project can be
+used by the immediate sources of the importing project, transitively. Thus
+if @code{A} imports @code{B}, and @code{B} imports @code{C}, the immediate
+sources of @code{A} may depend on the immediate sources of @code{C}, even if
+@code{A} does not import @code{C} explicitly. However, this is not recommended,
+because if and when @code{B} ceases to import @code{C}, some sources in
+@code{A} will no longer compile.
+
+A side effect of this capability is that normally cyclic dependencies are not
+permitted: if @code{A} imports @code{B} (directly or indirectly) then @code{B}
+is not allowed to import @code{A}. However, there are cases when cyclic
+dependencies would be beneficial. For these cases, another form of import
+between projects exists, the @code{limited with}: a project @code{A} that
+imports a project @code{B} with a straigh @code{with} may also be imported,
+directly or indirectly, by @code{B} on the condition that imports from @code{B}
+to @code{A} include at least one @code{limited with}.
+
+@smallexample @c 0projectfile
+with "../b/b.gpr";
+with "../c/c.gpr";
+project A is
+end A;
+
+limited with "../a/a.gpr";
+project B is
+end B;
+
+with "../d/d.gpr";
+project C is
+end C;
+
+limited with "../a/a.gpr";
+project D is
+end D;
+@end smallexample
+
+@noindent
+In the above legal example, there are two project cycles:
+@itemize @bullet
+@item A-> B-> A
+@item A -> C -> D -> A
+@end itemize
+
+@noindent
+In each of these cycle there is one @code{limited with}: import of @code{A}
+from @code{B} and import of @code{A} from @code{D}.
+
+The difference between straight @code{with} and @code{limited with} is that
+the name of a project imported with a @code{limited with} cannot be used in the
+project that imports it. In particular, its packages cannot be renamed and
+its variables cannot be referred to.
+
+An exception to the above rules for @code{limited with} is that for the main
+project specified to @command{gnatmake} or to the @command{GNAT} driver a
+@code{limited with} is equivalent to a straight @code{with}. For example,
+in the example above, projects @code{B} and @code{D} could not be main
+projects for @command{gnatmake} or to the @command{GNAT} driver, because they
+each have a @code{limited with} that is the only one in a cycle of importing
+projects.
+
+@c *********************
+@c * Project Extension *
+@c *********************
+
+@node Project Extension
+@section Project Extension
+
+@noindent
+During development of a large system, it is sometimes necessary to use
+modified versions of some of the source files, without changing the original
+sources. This can be achieved through the @emph{project extension} facility.
+
+@smallexample @c projectfile
+ project Modified_Utilities extends "/baseline/utilities.gpr" is ...
+@end smallexample
+
+@noindent
+A project extension declaration introduces an extending project
+(the @emph{child}) and a project being extended (the @emph{parent}).
+
+By default, a child project inherits all the sources of its parent.
+However, inherited sources can be overridden: a unit in a parent is hidden
+by a unit of the same name in the child.
+
+Inherited sources are considered to be sources (but not immediate sources)
+of the child project; see @ref{Project File Syntax}.
+
+An inherited source file retains any switches specified in the parent project.
+
+For example if the project @code{Utilities} contains the specification and the
+body of an Ada package @code{Util_IO}, then the project
+@code{Modified_Utilities} can contain a new body for package @code{Util_IO}.
+The original body of @code{Util_IO} will not be considered in program builds.
+However, the package specification will still be found in the project
+@code{Utilities}.
+
+A child project can have only one parent but it may import any number of other
+projects.
+
+A project is not allowed to import directly or indirectly at the same time a
+child project and any of its ancestors.
+
+@c ****************************************
+@c * External References in Project Files *
+@c ****************************************
+
+@node External References in Project Files
+@section External References in Project Files
+
+@noindent
+A project file may contain references to external variables; such references
+are called @emph{external references}.
+
+An external variable is either defined as part of the environment (an
+environment variable in Unix, for example) or else specified on the command
+line via the @option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}} switch.
+If both, then the command line value is used.
+
+The value of an external reference is obtained by means of the built-in
+function @code{external}, which returns a string value.
+This function has two forms:
+@itemize @bullet
+@item @code{external (external_variable_name)}
+@item @code{external (external_variable_name, default_value)}
+@end itemize
+
+@noindent
+Each parameter must be a string literal. For example:
+
+@smallexample @c projectfile
+ external ("USER")
+ external ("OS", "GNU/Linux")
+@end smallexample
+
+@noindent
+In the form with one parameter, the function returns the value of
+the external variable given as parameter. If this name is not present in the
+environment, the function returns an empty string.
+
+In the form with two string parameters, the second argument is
+the value returned when the variable given as the first argument is not
+present in the environment. In the example above, if @code{"OS"} is not
+the name of ^an environment variable^a logical name^ and is not passed on
+the command line, then the returned value is @code{"GNU/Linux"}.
+
+An external reference may be part of a string expression or of a string
+list expression, and can therefore appear in a variable declaration or
+an attribute declaration.
+
+@smallexample @c projectfile
+@group
+ type Mode_Type is ("Debug", "Release");
+ Mode : Mode_Type := external ("MODE");
+ case Mode is
+ when "Debug" =>
+ ...
+@end group
+@end smallexample
+
+@c *****************************
+@c * Packages in Project Files *
+@c *****************************
+
+@node Packages in Project Files
+@section Packages in Project Files
+
+@noindent
+A @emph{package} defines the settings for project-aware tools within a
+project.
+For each such tool one can declare a package; the names for these
+packages are preset (see @ref{Packages}).
+A package may contain variable declarations, attribute declarations, and case
+constructions.
+
+@smallexample @c projectfile
+@group
+ project Proj is
+ package Builder is -- used by gnatmake
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-v^-v^",
+ "^-g^-g^");
+ end Builder;
+ end Proj;
+@end group
+@end smallexample
+
+@noindent
+The syntax of package declarations mimics that of package in Ada.
+
+Most of the packages have an attribute
+@code{^Default_Switches^Default_Switches^}.
+This attribute is an associative array, and its value is a string list.
+The index of the associative array is the name of a programming language (case
+insensitive). This attribute indicates the ^switch^switch^
+or ^switches^switches^ to be used
+with the corresponding tool.
+
+Some packages also have another attribute, @code{^Switches^Switches^},
+an associative array whose value is a string list.
+The index is the name of a source file.
+This attribute indicates the ^switch^switch^
+or ^switches^switches^ to be used by the corresponding
+tool when dealing with this specific file.
+
+Further information on these ^switch^switch^-related attributes is found in
+@ref{^Switches^Switches^ and Project Files}.
+
+A package may be declared as a @emph{renaming} of another package; e.g., from
+the project file for an imported project.
+
+@smallexample @c projectfile
+@group
+ with "/global/apex.gpr";
+ project Example is
+ package Naming renames Apex.Naming;
+ ...
+ end Example;
+@end group
+@end smallexample
+
+@noindent
+Packages that are renamed in other project files often come from project files
+that have no sources: they are just used as templates. Any modification in the
+template will be reflected automatically in all the project files that rename
+a package from the template.
+
+In addition to the tool-oriented packages, you can also declare a package
+named @code{Naming} to establish specialized source file naming conventions
+(see @ref{Naming Schemes}).
+
+@c ************************************
+@c * Variables from Imported Projects *
+@c ************************************
+
+@node Variables from Imported Projects
+@section Variables from Imported Projects
+
+@noindent
+An attribute or variable defined in an imported or parent project can
+be used in expressions in the importing / extending project.
+Such an attribute or variable is denoted by an expanded name whose prefix
+is either the name of the project or the expanded name of a package within
+a project.
+
+@smallexample @c projectfile
+@group
+ with "imported";
+ project Main extends "base" is
+ Var1 := Imported.Var;
+ Var2 := Base.Var & ".new";
+@end group
+
+@group
+ package Builder is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use Imported.Builder.Ada_^Switches^Switches^ &
+ "^-gnatg^-gnatg^" &
+ "^-v^-v^";
+ end Builder;
+@end group
+
+@group
+ package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use Base.Compiler.Ada_^Switches^Switches^;
+ end Compiler;
+ end Main;
+@end group
+@end smallexample
+
+@noindent
+In this example:
+
+@itemize @bullet
+@item
+The value of @code{Var1} is a copy of the variable @code{Var} defined
+in the project file @file{"imported.gpr"}
+@item
+the value of @code{Var2} is a copy of the value of variable @code{Var}
+defined in the project file @file{base.gpr}, concatenated with @code{".new"}
+@item
+attribute @code{^Default_Switches^Default_Switches^ ("Ada")} in package
+@code{Builder} is a string list that includes in its value a copy of the value
+of @code{Ada_^Switches^Switches^} defined in the @code{Builder} package
+in project file @file{imported.gpr} plus two new elements:
+@option{"^-gnatg^-gnatg^"}
+and @option{"^-v^-v^"};
+@item
+attribute @code{^Default_Switches^Default_Switches^ ("Ada")} in package
+@code{Compiler} is a copy of the variable @code{Ada_^Switches^Switches^}
+defined in the @code{Compiler} package in project file @file{base.gpr},
+the project being extended.
+@end itemize
+
+@c ******************
+@c * Naming Schemes *
+@c ******************
+
+@node Naming Schemes
+@section Naming Schemes
+
+@noindent
+Sometimes an Ada software system is ported from a foreign compilation
+environment to GNAT, and the file names do not use the default GNAT
+conventions. Instead of changing all the file names (which for a variety
+of reasons might not be possible), you can define the relevant file
+naming scheme in the @code{Naming} package in your project file.
+
+@noindent
+Note that the use of pragmas described in @ref{Alternative
+File Naming Schemes} by mean of a configuration pragmas file is not
+supported when using project files. You must use the features described
+in this paragraph. You can however use specify other configuration
+pragmas (see @ref{Specifying Configuration Pragmas}).
+
+@ifclear vms
+For example, the following
+package models the Apex file naming rules:
+
+@smallexample @c projectfile
+@group
+ package Naming is
+ for Casing use "lowercase";
+ for Dot_Replacement use ".";
+ for Spec_Suffix ("Ada") use ".1.ada";
+ for Body_Suffix ("Ada") use ".2.ada";
+ end Naming;
+@end group
+@end smallexample
+@end ifclear
+
+@ifset vms
+For example, the following package models the DEC Ada file naming rules:
+
+@smallexample @c projectfile
+@group
+ package Naming is
+ for Casing use "lowercase";
+ for Dot_Replacement use "__";
+ for Spec_Suffix ("Ada") use "_.^ada^ada^";
+ for Body_Suffix ("Ada") use ".^ada^ada^";
+ end Naming;
+@end group
+@end smallexample
+
+@noindent
+(Note that @code{Casing} is @code{"lowercase"} because GNAT gets the file
+names in lower case)
+@end ifset
+
+@noindent
+You can define the following attributes in package @code{Naming}:
+
+@table @code
+
+@item @var{Casing}
+This must be a string with one of the three values @code{"lowercase"},
+@code{"uppercase"} or @code{"mixedcase"}; these strings are case insensitive.
+
+@noindent
+If @var{Casing} is not specified, then the default is @code{"lowercase"}.
+
+@item @var{Dot_Replacement}
+This must be a string whose value satisfies the following conditions:
+
+@itemize @bullet
+@item It must not be empty
+@item It cannot start or end with an alphanumeric character
+@item It cannot be a single underscore
+@item It cannot start with an underscore followed by an alphanumeric
+@item It cannot contain a dot @code{'.'} except if the entire string
+is @code{"."}
+@end itemize
+
+@noindent
+If @code{Dot_Replacement} is not specified, then the default is @code{"-"}.
+
+@item @var{Spec_Suffix}
+This is an associative array (indexed by the programming language name, case
+insensitive) whose value is a string that must satisfy the following
+conditions:
+
+@itemize @bullet
+@item It must not be empty
+@item It must include at least one dot
+@end itemize
+@noindent
+If @code{Spec_Suffix ("Ada")} is not specified, then the default is
+@code{"^.ads^.ADS^"}.
+
+@item @var{Body_Suffix}
+This is an associative array (indexed by the programming language name, case
+insensitive) whose value is a string that must satisfy the following
+conditions:
+
+@itemize @bullet
+@item It must not be empty
+@item It must include at least one dot
+@item It cannot end with the same string as @code{Spec_Suffix ("Ada")}
+@end itemize
+@noindent
+If @code{Body_Suffix ("Ada")} is not specified, then the default is
+@code{"^.adb^.ADB^"}.
+
+@item @var{Separate_Suffix}
+This must be a string whose value satisfies the same conditions as
+@code{Body_Suffix}.
+
+@noindent
+If @code{Separate_Suffix ("Ada")} is not specified, then it defaults to same
+value as @code{Body_Suffix ("Ada")}.
+
+@item @var{Spec}
+@noindent
+You can use the associative array attribute @code{Spec} to define
+the source file name for an individual Ada compilation unit's spec. The array
+index must be a string literal that identifies the Ada unit (case insensitive).
+The value of this attribute must be a string that identifies the file that
+contains this unit's spec (case sensitive or insensitive depending on the
+operating system).
+
+@smallexample @c projectfile
+ for Spec ("MyPack.MyChild") use "mypack.mychild.spec";
+@end smallexample
+
+@item @var{Body}
+
+You can use the associative array attribute @code{Body} to
+define the source file name for an individual Ada compilation unit's body
+(possibly a subunit). The array index must be a string literal that identifies
+the Ada unit (case insensitive). The value of this attribute must be a string
+that identifies the file that contains this unit's body or subunit (case
+sensitive or insensitive depending on the operating system).
+
+@smallexample @c projectfile
+ for Body ("MyPack.MyChild") use "mypack.mychild.body";
+@end smallexample
+@end table
+
+@c ********************
+@c * Library Projects *
+@c ********************
+
+@node Library Projects
+@section Library Projects
+
+@noindent
+@emph{Library projects} are projects whose object code is placed in a library.
+(Note that this facility is not yet supported on all platforms)
+
+To create a library project, you need to define in its project file
+two project-level attributes: @code{Library_Name} and @code{Library_Dir}.
+Additionally, you may define the library-related attributes
+@code{Library_Kind}, @code{Library_Version}, @code{Library_Interface},
+@code{Library_Auto_Init}, @code{Library_Options} and @code{Library_GCC}.
+
+The @code{Library_Name} attribute has a string value. There is no restriction
+on the name of a library. It is the responsability of the developer to
+choose a name that will be accepted by the platform. It is recommanded to
+choose names that could be Ada identifiers; such names are almost guaranteed
+to be acceptable on all platforms.
+
+The @code{Library_Dir} attribute has a string value that designates the path
+(absolute or relative) of the directory where the library will reside.
+It must designate an existing directory, and this directory must be
+different from the project's object directory. It also needs to be writable.
+The directory should only be used for one library; the reason is that all
+files contained in this directory may be deleted by the Project Manager.
+
+If both @code{Library_Name} and @code{Library_Dir} are specified and
+are legal, then the project file defines a library project. The optional
+library-related attributes are checked only for such project files.
+
+The @code{Library_Kind} attribute has a string value that must be one of the
+following (case insensitive): @code{"static"}, @code{"dynamic"} or
+@code{"relocatable"} (which is a synonym for @code{"dynamic"}). If this
+attribute is not specified, the library is a static library, that is
+an archive of object files that can be potentially linked into an
+static executable. Otherwise, the library may be dynamic or
+relocatable, that is a library that is loaded only at the start of execution.
+
+If you need to build both a static and a dynamic library, you should use two
+different object directories, since in some cases some extra code needs to
+be generated for the latter. For such cases, it is recommended to either use
+two different project files, or a single one which uses external variables
+to indicate what kind of library should be build.
+
+The @code{Library_Version} attribute has a string value whose interpretation
+is platform dependent. It has no effect on VMS and Windows. On Unix, it is
+used only for dynamic/relocatable libraries as the internal name of the
+library (the @code{"soname"}). If the library file name (built from the
+@code{Library_Name}) is different from the @code{Library_Version}, then the
+library file will be a symbolic link to the actual file whose name will be
+@code{Library_Version}.
+
+Example (on Unix):
+
+@smallexample @c projectfile
+@group
+project Plib is
+
+ Version := "1";
+
+ for Library_Dir use "lib_dir";
+ for Library_Name use "dummy";
+ for Library_Kind use "relocatable";
+ for Library_Version use "libdummy.so." & Version;
+
+end Plib;
+@end group
+@end smallexample
+
+@noindent
+Directory @file{lib_dir} will contain the internal library file whose name
+will be @file{libdummy.so.1}, and @file{libdummy.so} will be a symbolic link to
+@file{libdummy.so.1}.
+
+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.
+
+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.
+
+
+@c **********************************************
+@c * Using Third-Party Libraries through Projects
+@c **********************************************
+@node Using Third-Party Libraries through Projects
+@section Using Third-Party Libraries through Projects
+
+Whether you are exporting your own library to make it available to
+clients, or you are using a library provided by a third party, it is
+convenient to have project files that automatically set the correct
+command line switches for the compiler and linker.
+
+Such project files are very similar to the library project files;
+@xref{Library Projects}. The only difference is that you set the
+@code{Source_Dirs} and @code{Object_Dir} attribute so that they point to the
+directories where, respectively, the sources and the read-only ALI files have
+been installed.
+
+If you need to interface with a set of libraries, as opposed to a
+single one, you need to create one library project for each of the
+libraries. In addition, a top-level project that imports all these
+library projects should be provided, so that the user of your library
+has a single @code{with} clause to add to his own projects.
+
+For instance, let's assume you are providing two static libraries
+@file{liba.a} and @file{libb.a}. The user needs to link with
+both of these libraries. Each of these is associated with its
+own set of header files. Let's assume furthermore that all the
+header files for the two libraries have been installed in the same
+directory @file{headers}. The @file{ALI} files are found in the same
+@file{headers} directory.
+
+In this case, you should provide the following three projects:
+
+@smallexample @c projectfile
+@group
+with "liba", "libb";
+project My_Library is
+ for Source_Dirs use ("headers");
+ for Object_Dir use "headers";
+end My_Library;
+@end group
+
+@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
+
+@group
+project Libb is
+ for Source_Dirs use ();
+ for Library_Dir use "lib";
+ for Library_Name use "b";
+ for Library_Kind use "static";
+end Libb;
+@end group
+@end smallexample
+
+@c *******************************
+@c * Stand-alone Library Projects *
+@c *******************************
+
+@node Stand-alone Library Projects
+@section Stand-alone Library Projects
+
+@noindent
+A Stand-alone Library is a library that contains the necessary code to
+elaborate the Ada units that are included in the library. A Stand-alone
+Library is suitable to be used in an executable when the main is not
+in Ada. However, Stand-alone Libraries may also be used with an Ada main
+subprogram.
+
+A Stand-alone Library Project is a Library Project where the library is
+a Stand-alone Library.
+
+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.
+
+@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
+
+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.
+
+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.
+
+A dynamic or relocatable Stand-alone Library is automatically initialized
+if automatic initialization of Stand-alone Libraries is supported on the
+platform and if attribute @code{Library_Auto_Init} is not specified or
+is specified with the value "true". A static Stand-alone Library is never
+automatically initialized.
+
+Single string attribute @code{Library_Auto_Init} may be specified with only
+two possible values: "false" or "true" (case-insensitive). Specifying
+"false" for attribute @code{Library_Auto_Init} will prevent automatic
+initialization of dynamic or relocatable libraries.
+
+When a non automatically initialized Stand-alone Library is used
+in an executable, its initialization procedure must be called before
+any service of the library is used.
+When the main subprogram is in Ada, it may mean that the initialization
+procedure has to be called during elaboration of another package.
+
+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.
+
+When a Stand-Alone Library is bound, the switches that are specified in
+the attribute @code{Default_Switches ("Ada")} in package @code{Binder} are
+used in the call to @command{gnatbind}.
+
+The string list attribute @code{Library_Options} may be used to specified
+additional switches to the call to @command{gcc} to link 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.
+
+@c *************************************
+@c * Switches Related to Project Files *
+@c *************************************
+@node Switches Related to Project Files
+@section Switches Related to Project Files
+
+@noindent
+The following switches are used by GNAT tools that support project files:
+
+@table @option
+
+@item ^-P^/PROJECT_FILE=^@var{project}
+@cindex @option{^-P^/PROJECT_FILE^} (any tool supporting project files)
+Indicates the name of a project file. This project file will be parsed with
+the verbosity indicated by @option{^-vP^MESSAGE_PROJECT_FILES=^@emph{x}},
+if any, and using the external references indicated
+by @option{^-X^/EXTERNAL_REFERENCE^} switches, if any.
+@ifclear vms
+There may zero, one or more spaces between @option{-P} and @var{project}.
+@end ifclear
+
+@noindent
+There must be only one @option{^-P^/PROJECT_FILE^} switch on the command line.
+
+@noindent
+Since the Project Manager parses the project file only after all the switches
+on the command line are checked, the order of the switches
+@option{^-P^/PROJECT_FILE^},
+@option{^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}}
+or @option{^-X^/EXTERNAL_REFERENCE^} is not significant.
+
+@item ^-X^/EXTERNAL_REFERENCE=^@var{name=value}
+@cindex @option{^-X^/EXTERNAL_REFERENCE^} (any tool supporting project files)
+Indicates that external variable @var{name} has the value @var{value}.
+The Project Manager will use this value for occurrences of
+@code{external(name)} when parsing the project file.
+
+@ifclear vms
+@noindent
+If @var{name} or @var{value} includes a space, then @var{name=value} should be
+put between quotes.
+@smallexample
+ -XOS=NT
+ -X"user=John Doe"
+@end smallexample
+@end ifclear
+
+@noindent
+Several @option{^-X^/EXTERNAL_REFERENCE^} switches can be used simultaneously.
+If several @option{^-X^/EXTERNAL_REFERENCE^} switches specify the same
+@var{name}, only the last one is used.
+
+@noindent
+An external variable specified with a @option{^-X^/EXTERNAL_REFERENCE^} switch
+takes precedence over the value of the same name in the environment.
+
+@item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}
+@cindex @code{^-vP^/MESSAGES_PROJECT_FILE^} (any tool supporting project files)
+@c Previous line uses code vs option command, to stay less than 80 chars
+Indicates the verbosity of the parsing of GNAT project files.
+
+@ifclear vms
+@option{-vP0} means Default;
+@option{-vP1} means Medium;
+@option{-vP2} means High.
+@end ifclear
+
+@ifset vms
+There are three possible options for this qualifier: DEFAULT, MEDIUM and
+HIGH.
+@end ifset
+
+@noindent
+The default is ^Default^DEFAULT^: no output for syntactically correct
+project files.
+@noindent
+If several @option{^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}} switches are present,
+only the last one is used.
+
+@end table
+
+@c **********************************
+@c * Tools Supporting Project Files *
+@c **********************************
+
+@node Tools Supporting Project Files
+@section Tools Supporting Project Files
+
+@menu
+* gnatmake and Project Files::
+* The GNAT Driver and Project Files::
+@ifclear vms
+* Glide and Project Files::
+@end ifclear
+@end menu
+
+@node gnatmake and Project Files
+@subsection gnatmake and Project Files
+
+@noindent
+This section covers several topics related to @command{gnatmake} and
+project files: defining ^switches^switches^ for @command{gnatmake}
+and for the tools that it invokes; specifying configuration pragmas;
+the use of the @code{Main} attribute; building and rebuilding library project
+files.
+
+@menu
+* ^Switches^Switches^ and Project Files::
+* Specifying Configuration Pragmas::
+* Project Files and Main Subprograms::
+* Library Project Files::
+@end menu
+
+@node ^Switches^Switches^ and Project Files
+@subsubsection ^Switches^Switches^ and Project Files
+
+@ifset vms
+It is not currently possible to specify VMS style qualifiers in the project
+files; only Unix style ^switches^switches^ may be specified.
+@end ifset
+
+@noindent
+For each of the packages @code{Builder}, @code{Compiler}, @code{Binder}, and
+@code{Linker}, you can specify a @code{^Default_Switches^Default_Switches^}
+attribute, a @code{^Switches^Switches^} attribute, or both;
+as their names imply, these ^switch^switch^-related
+attributes affect the ^switches^switches^ that are used for each of these GNAT
+components when
+@command{gnatmake} is invoked. As will be explained below, these
+component-specific ^switches^switches^ precede
+the ^switches^switches^ provided on the @command{gnatmake} command line.
+
+The @code{^Default_Switches^Default_Switches^} attribute is an associative
+array indexed by language name (case insensitive) whose value is a string list.
+For example:
+
+@smallexample @c projectfile
+@group
+package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-gnaty^-gnaty^",
+ "^-v^-v^");
+end Compiler;
+@end group
+@end smallexample
+
+@noindent
+The @code{^Switches^Switches^} attribute is also an associative array,
+indexed by a file name (which may or may not be case sensitive, depending
+on the operating system) whose value is a string list. For example:
+
+@smallexample @c projectfile
+@group
+package Builder is
+ for ^Switches^Switches^ ("main1.adb")
+ use ("^-O2^-O2^");
+ for ^Switches^Switches^ ("main2.adb")
+ use ("^-g^-g^");
+end Builder;
+@end group
+@end smallexample
+
+@noindent
+For the @code{Builder} package, the file names must designate source files
+for main subprograms. For the @code{Binder} and @code{Linker} packages, the
+file names must designate @file{ALI} or source files for main subprograms.
+In each case just the file name without an explicit extension is acceptable.
+
+For each tool used in a program build (@command{gnatmake}, the compiler, the
+binder, and the linker), the corresponding package @dfn{contributes} a set of
+^switches^switches^ for each file on which the tool is invoked, based on the
+^switch^switch^-related attributes defined in the package.
+In particular, the ^switches^switches^
+that each of these packages contributes for a given file @var{f} comprise:
+
+@itemize @bullet
+@item
+the value of attribute @code{^Switches^Switches^ (@var{f})},
+if it is specified in the package for the given file,
+@item
+otherwise, the value of @code{^Default_Switches^Default_Switches^ ("Ada")},
+if it is specified in the package.
+@end itemize
+
+@noindent
+If neither of these attributes is defined in the package, then the package does
+not contribute any ^switches^switches^ for the given file.
+
+When @command{gnatmake} is invoked on a file, the ^switches^switches^ comprise
+two sets, in the following order: those contributed for the file
+by the @code{Builder} package;
+and the switches passed on the command line.
+
+When @command{gnatmake} invokes a tool (compiler, binder, linker) on a file,
+the ^switches^switches^ passed to the tool comprise three sets,
+in the following order:
+
+@enumerate
+@item
+the applicable ^switches^switches^ contributed for the file
+by the @code{Builder} package in the project file supplied on the command line;
+
+@item
+those contributed for the file by the package (in the relevant project file --
+see below) corresponding to the tool; and
+
+@item
+the applicable switches passed on the command line.
+@end enumerate
+
+@noindent
+The term @emph{applicable ^switches^switches^} reflects the fact that
+@command{gnatmake} ^switches^switches^ may or may not be passed to individual
+tools, depending on the individual ^switch^switch^.
+
+@command{gnatmake} may invoke the compiler on source files from different
+projects. The Project Manager will use the appropriate project file to
+determine the @code{Compiler} package for each source file being compiled.
+Likewise for the @code{Binder} and @code{Linker} packages.
+
+As an example, consider the following package in a project file:
+
+@smallexample @c projectfile
+@group
+project Proj1 is
+ package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-g^-g^");
+ for ^Switches^Switches^ ("a.adb")
+ use ("^-O1^-O1^");
+ for ^Switches^Switches^ ("b.adb")
+ use ("^-O2^-O2^",
+ "^-gnaty^-gnaty^");
+ end Compiler;
+end Proj1;
+@end group
+@end smallexample
+
+@noindent
+If @command{gnatmake} is invoked with this project file, and it needs to
+compile, say, the files @file{a.adb}, @file{b.adb}, and @file{c.adb}, then
+@file{a.adb} will be compiled with the ^switch^switch^
+@option{^-O1^-O1^},
+@file{b.adb} with ^switches^switches^
+@option{^-O2^-O2^}
+and @option{^-gnaty^-gnaty^},
+and @file{c.adb} with @option{^-g^-g^}.
+
+The following example illustrates the ordering of the ^switches^switches^
+contributed by different packages:
+
+@smallexample @c projectfile
+@group
+project Proj2 is
+ package Builder is
+ for ^Switches^Switches^ ("main.adb")
+ use ("^-g^-g^",
+ "^-O1^-)1^",
+ "^-f^-f^");
+ end Builder;
+@end group
+
+@group
+ package Compiler is
+ for ^Switches^Switches^ ("main.adb")
+ use ("^-O2^-O2^");
+ end Compiler;
+end Proj2;
+@end group
+@end smallexample
+
+@noindent
+If you issue the command:
+
+@smallexample
+ gnatmake ^-Pproj2^/PROJECT_FILE=PROJ2^ -O0 main
+@end smallexample
+
+@noindent
+then the compiler will be invoked on @file{main.adb} with the following
+sequence of ^switches^switches^
+
+@smallexample
+ ^-g -O1 -O2 -O0^-g -O1 -O2 -O0^
+@end smallexample
+
+with the last @option{^-O^-O^}
+^switch^switch^ having precedence over the earlier ones;
+several other ^switches^switches^
+(such as @option{^-c^-c^}) are added implicitly.
+
+The ^switches^switches^
+@option{^-g^-g^}
+and @option{^-O1^-O1^} are contributed by package
+@code{Builder}, @option{^-O2^-O2^} is contributed
+by the package @code{Compiler}
+and @option{^-O0^-O0^} comes from the command line.
+
+The @option{^-g^-g^}
+^switch^switch^ will also be passed in the invocation of
+@command{Gnatlink.}
+
+A final example illustrates switch contributions from packages in different
+project files:
+
+@smallexample @c projectfile
+@group
+project Proj3 is
+ for Source_Files use ("pack.ads", "pack.adb");
+ package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-gnata^-gnata^");
+ end Compiler;
+end Proj3;
+@end group
+
+@group
+with "Proj3";
+project Proj4 is
+ for Source_Files use ("foo_main.adb", "bar_main.adb");
+ package Builder is
+ for ^Switches^Switches^ ("foo_main.adb")
+ use ("^-s^-s^",
+ "^-g^-g^");
+ end Builder;
+end Proj4;
+@end group
+
+@group
+-- Ada source file:
+with Pack;
+procedure Foo_Main is
+ ...
+end Foo_Main;
+@end group
+@end smallexample
+
+If the command is
+@smallexample
+gnatmake ^-PProj4^/PROJECT_FILE=PROJ4^ foo_main.adb -cargs -gnato
+@end smallexample
+
+@noindent
+then the ^switches^switches^ passed to the compiler for @file{foo_main.adb} are
+@option{^-g^-g^} (contributed by the package @code{Proj4.Builder}) and
+@option{^-gnato^-gnato^} (passed on the command line).
+When the imported package @code{Pack} is compiled, the ^switches^switches^ used
+are @option{^-g^-g^} from @code{Proj4.Builder},
+@option{^-gnata^-gnata^} (contributed from package @code{Proj3.Compiler},
+and @option{^-gnato^-gnato^} from the command line.
+
+@noindent
+When using @command{gnatmake} with project files, some ^switches^switches^ or
+arguments may be expressed as relative paths. As the working directory where
+compilation occurs may change, these relative paths are converted to absolute
+paths. For the ^switches^switches^ found in a project file, the relative paths
+are relative to the project file directory, for the switches on the command
+line, they are relative to the directory where @command{gnatmake} is invoked.
+The ^switches^switches^ for which this occurs are:
+^-I^-I^,
+^-A^-A^,
+^-L^-L^,
+^-aO^-aO^,
+^-aL^-aL^,
+^-aI^-aI^, as well as all arguments that are not switches (arguments to
+^switch^switch^
+^-o^-o^, object files specified in package @code{Linker} or after
+-largs on the command line). The exception to this rule is the ^switch^switch^
+^--RTS=^--RTS=^ for which a relative path argument is never converted.
+
+@node Specifying Configuration Pragmas
+@subsubsection Specifying Configuration Pragmas
+
+When using @command{gnatmake} with project files, if there exists a file
+@file{gnat.adc} that contains configuration pragmas, this file will be
+ignored.
+
+Configuration pragmas can be defined by means of the following attributes in
+project files: @code{Global_Configuration_Pragmas} in package @code{Builder}
+and @code{Local_Configuration_Pragmas} in package @code{Compiler}.
+
+Both these attributes are single string attributes. Their values is the path
+name of a file containing configuration pragmas. If a path name is relative,
+then it is relative to the project directory of the project file where the
+attribute is defined.
+
+When compiling a source, the configuration pragmas used are, in order,
+those listed in the file designated by attribute
+@code{Global_Configuration_Pragmas} in package @code{Builder} of the main
+project file, if it is specified, and those listed in the file designated by
+attribute @code{Local_Configuration_Pragmas} in package @code{Compiler} of
+the project file of the source, if it exists.
+
+@node Project Files and Main Subprograms
+@subsubsection Project Files and Main Subprograms
+
+@noindent
+When using a project file, you can invoke @command{gnatmake}
+with one or several main subprograms, by specifying their source files on the
+command line.
+
+@smallexample
+ gnatmake ^-P^/PROJECT_FILE=^prj main1 main2 main3
+@end smallexample
+
+@noindent
+Each of these needs to be a source file of the same project, except
+when the switch ^-u^/UNIQUE^ is used.
+
+@noindent
+When ^-u^/UNIQUE^ is not used, all the mains need to be sources of the
+same project, one of the project in the tree rooted at the project specified
+on the command line. The package @code{Builder} of this common project, the
+"main project" is the one that is considered by @command{gnatmake}.
+
+@noindent
+When ^-u^/UNIQUE^ is used, the specified source files may be in projects
+imported directly or indirectly by the project specified on the command line.
+Note that if such a source file is not part of the project specified on the
+command line, the ^switches^switches^ found in package @code{Builder} of the
+project specified on the command line, if any, that are transmitted
+to the compiler will still be used, not those found in the project file of
+the source file.
+
+@noindent
+When using a project file, you can also invoke @command{gnatmake} without
+explicitly specifying any main, and the effect depends on whether you have
+defined the @code{Main} attribute. This attribute has a string list value,
+where each element in the list is the name of a source file (the file
+extension is optional) that contains a unit that can be a main subprogram.
+
+If the @code{Main} attribute is defined in a project file as a non-empty
+string list and the switch @option{^-u^/UNIQUE^} is not used on the command
+line, then invoking @command{gnatmake} with this project file but without any
+main on the command line is equivalent to invoking @command{gnatmake} with all
+the file names in the @code{Main} attribute on the command line.
+
+Example:
+@smallexample @c projectfile
+@group
+ project Prj is
+ for Main use ("main1", "main2", "main3");
+ end Prj;
+@end group
+@end smallexample
+
+@noindent
+With this project file, @code{"gnatmake ^-Pprj^/PROJECT_FILE=PRJ^"}
+is equivalent to
+@code{"gnatmake ^-Pprj^/PROJECT_FILE=PRJ^ main1 main2 main3"}.
+
+When the project attribute @code{Main} is not specified, or is specified
+as an empty string list, or when the switch @option{-u} is used on the command
+line, then invoking @command{gnatmake} with no main on the command line will
+result in all immediate sources of the project file being checked, and
+potentially recompiled. Depending on the presence of the switch @option{-u},
+sources from other project files on which the immediate sources of the main
+project file depend are also checked and potentially recompiled. In other
+words, the @option{-u} switch is applied to all of the immediate sources of the
+main project file.
+
+When no main is specified on the command line and attribute @code{Main} exists
+and includes several mains, or when several mains are specified on the
+command line, the default ^switches^switches^ in package @code{Builder} will
+be used for all mains, even if there are specific ^switches^switches^
+specified for one or several mains.
+
+But the ^switches^switches^ from package @code{Binder} or @code{Linker} will be
+the specific ^switches^switches^ for each main, if they are specified.
+
+@node Library Project Files
+@subsubsection Library Project Files
+
+@noindent
+When @command{gnatmake} is invoked with a main project file that is a library
+project file, it is not allowed to specify one or more mains on the command
+line.
+
+@noindent
+When a library project file is specified, switches ^-b^/ACTION=BIND^ and
+^-l^/ACTION=LINK^ have special meanings.
+
+@itemize @bullet
+@item ^-b^/ACTION=BIND^ is only allowed for stand-alone libraries. It indicates
+to @command{gnatmake} that @command{gnatbind} should be invoked for the
+library.
+
+@item ^-l^/ACTION=LINK^ may be used for all library projects. It indicates
+to @command{gnatmake} that the binder generated file should be compiled
+(in the case of a stand-alone library) and that the library should be built.
+
+@end itemize
+
+@node The GNAT Driver and Project Files
+@subsection The GNAT Driver and Project Files
+
+@noindent
+A number of GNAT tools, other than @command{^gnatmake^gnatmake^}
+are project-aware:
+@command{^gnatbind^gnatbind^},
+@command{^gnatfind^gnatfind^},
+@command{^gnatlink^gnatlink^},
+@command{^gnatls^gnatls^},
+@command{^gnatelim^gnatelim^},
+@command{^gnatpp^gnatpp^},
+and @command{^gnatxref^gnatxref^}. However, none of these tools can be invoked
+directly with a project file switch (@option{^-P^/PROJECT_FILE=^}).
+They must be invoked through the @command{gnat} driver.
+
+The @command{gnat} driver is a front-end that accepts a number of commands and
+call the corresponding tool. It has been designed initially for VMS to convert
+VMS style qualifiers to Unix style switches, but it is now available to all
+the GNAT supported platforms.
+
+On non VMS platforms, the @command{gnat} driver accepts the following commands
+(case insensitive):
+
+@itemize @bullet
+@item
+BIND to invoke @command{^gnatbind^gnatbind^}
+@item
+CHOP to invoke @command{^gnatchop^gnatchop^}
+@item
+CLEAN to invoke @command{^gnatclean^gnatclean^}
+@item
+COMP or COMPILE to invoke the compiler
+@item
+ELIM to invoke @command{^gnatelim^gnatelim^}
+@item
+FIND to invoke @command{^gnatfind^gnatfind^}
+@item
+KR or KRUNCH to invoke @command{^gnatkr^gnatkr^}
+@item
+LINK to invoke @command{^gnatlink^gnatlink^}
+@item
+LS or LIST to invoke @command{^gnatls^gnatls^}
+@item
+MAKE to invoke @command{^gnatmake^gnatmake^}
+@item
+NAME to invoke @command{^gnatname^gnatname^}
+@item
+PREP or PREPROCESS to invoke @command{^gnatprep^gnatprep^}
+@item
+PP or PRETTY to invoke @command{^gnatpp^gnatpp^}
+@item
+STUB to invoke @command{^gnatstub^gnatstub^}
+@item
+XREF to invoke @command{^gnatxref^gnatxref^}
+@end itemize
+
+@noindent
+(note that the compiler is invoked using the command
+@command{^gnatmake -f -u -c^gnatmake -f -u -c^}).
+
+@noindent
+On non VMS platforms, between @command{gnat} and the command, two
+special switches may be used:
+
+@itemize @bullet
+@item
+@command{-v} to display the invocation of the tool.
+@item
+@command{-dn} to prevent the @command{gnat} driver from removing
+the temporary files it has created. These temporary files are
+configuration files and temporary file list files.
+@end itemize
+
+@noindent
+The command may be followed by switches and arguments for the invoked
+tool.
+
+@smallexample
+ gnat bind -C main.ali
+ gnat ls -a main
+ gnat chop foo.txt
+@end smallexample
+
+@noindent
+Switches may also be put in text files, one switch per line, and the text
+files may be specified with their path name preceded by '@@'.
+
+@smallexample
+ gnat bind @@args.txt main.ali
+@end smallexample
+
+@noindent
+In addition, for command BIND, COMP or COMPILE, FIND, ELIM, LS or LIST, LINK,
+PP or PRETTY and XREF, the project file related switches
+(@option{^-P^/PROJECT_FILE^},
+@option{^-X^/EXTERNAL_REFERENCE^} and
+@option{^-vP^/MESSAGES_PROJECT_FILE=^x}) may be used in addition to
+the switches of the invoking tool.
+
+@noindent
+When GNAT PP or GNAT PRETTY is used with a project file, but with no source
+specified on the command line, it invokes @command{^gnatpp^gnatpp^} with all
+the immediate sources of the specified project file.
+
+@noindent
+For each of these commands, there is optionally a corresponding package
+in the main project.
+
+@itemize @bullet
+@item
+package @code{Binder} for command BIND (invoking @code{^gnatbind^gnatbind^})
+
+@item
+package @code{Compiler} for command COMP or COMPILE (invoking the compiler)
+
+@item
+package @code{Finder} for command FIND (invoking @code{^gnatfind^gnatfind^})
+
+@item
+package @code{Eliminate} for command ELIM (invoking
+@code{^gnatelim^gnatelim^})
+
+@item
+package @code{Gnatls} for command LS or LIST (invoking @code{^gnatls^gnatls^})
+
+@item
+package @code{Linker} for command LINK (invoking @code{^gnatlink^gnatlink^})
+
+@item
+package @code{Pretty_Printer} for command PP or PRETTY
+(invoking @code{^gnatpp^gnatpp^})
+
+@item
+package @code{Cross_Reference} for command XREF (invoking
+@code{^gnatxref^gnatxref^})
+
+@end itemize
+
+@noindent
+Package @code{Gnatls} has a unique attribute @code{^Switches^Switches^},
+a simple variable with a string list value. It contains ^switches^switches^
+for the invocation of @code{^gnatls^gnatls^}.
+
+@smallexample @c projectfile
+@group
+project Proj1 is
+ package gnatls is
+ for ^Switches^Switches^
+ use ("^-a^-a^",
+ "^-v^-v^");
+ end gnatls;
+end Proj1;
+@end group
+@end smallexample
+
+@noindent
+All other packages have two attribute @code{^Switches^Switches^} and
+@code{^Default_Switches^Default_Switches^}.
+
+@noindent
+@code{^Switches^Switches^} is an associated array attribute, indexed by the
+source file name, that has a string list value: the ^switches^switches^ to be
+used when the tool corresponding to the package is invoked for the specific
+source file.
+
+@noindent
+@code{^Default_Switches^Default_Switches^} is an associative array attribute,
+indexed by the programming language that has a string list value.
+@code{^Default_Switches^Default_Switches^ ("Ada")} contains the
+^switches^switches^ for the invocation of the tool corresponding
+to the package, except if a specific @code{^Switches^Switches^} attribute
+is specified for the source file.
+
+@smallexample @c projectfile
+@group
+project Proj is
+
+ for Source_Dirs use ("./**");
+
+ package gnatls is
+ for ^Switches^Switches^ use
+ ("^-a^-a^",
+ "^-v^-v^");
+ end gnatls;
+@end group
+@group
+
+ package Compiler is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-gnatv^-gnatv^",
+ "^-gnatwa^-gnatwa^");
+ end Binder;
+@end group
+@group
+
+ package Binder is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-C^-C^",
+ "^-e^-e^");
+ end Binder;
+@end group
+@group
+
+ package Linker is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-C^-C^");
+ for ^Switches^Switches^ ("main.adb")
+ use ("^-C^-C^",
+ "^-v^-v^",
+ "^-v^-v^");
+ end Linker;
+@end group
+@group
+
+ package Finder is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-a^-a^",
+ "^-f^-f^");
+ end Finder;
+@end group
+@group
+
+ package Cross_Reference is
+ for ^Default_Switches^Default_Switches^ ("Ada")
+ use ("^-a^-a^",
+ "^-f^-f^",
+ "^-d^-d^",
+ "^-u^-u^");
+ end Cross_Reference;
+end Proj;
+@end group
+@end smallexample
+
+@noindent
+With the above project file, commands such as
+
+@smallexample
+ ^gnat comp -Pproj main^GNAT COMP /PROJECT_FILE=PROJ MAIN^
+ ^gnat ls -Pproj main^GNAT LIST /PROJECT_FILE=PROJ MAIN^
+ ^gnat xref -Pproj main^GNAT XREF /PROJECT_FILE=PROJ MAIN^
+ ^gnat bind -Pproj main.ali^GNAT BIND /PROJECT_FILE=PROJ MAIN.ALI^
+ ^gnat link -Pproj main.ali^GNAT LINK /PROJECT_FILE=PROJ MAIN.ALI^
+@end smallexample
+
+@noindent
+will set up the environment properly and invoke the tool with the switches
+found in the package corresponding to the tool:
+@code{^Default_Switches^Default_Switches^ ("Ada")} for all tools,
+except @code{^Switches^Switches^ ("main.adb")}
+for @code{^gnatlink^gnatlink^}.
+
+@ifclear vms
+@node Glide and Project Files
+@subsection Glide and Project Files
+
+@noindent
+Glide will automatically recognize the @file{.gpr} extension for
+project files, and will
+convert them to its own internal format automatically. However, it
+doesn't provide a syntax-oriented editor for modifying these
+files.
+The project file will be loaded as text when you select the menu item
+@code{Ada} @result{} @code{Project} @result{} @code{Edit}.
+You can edit this text and save the @file{gpr} file;
+when you next select this project file in Glide it
+will be automatically reloaded.
+@end ifclear
+
+@c **********************
+@node An Extended Example
+@section An Extended Example
+
+@noindent
+Suppose that we have two programs, @var{prog1} and @var{prog2},
+whose sources are in corresponding directories. We would like
+to build them with a single @command{gnatmake} command, and we want to place
+their object files into @file{build} subdirectories of the source directories.
+Furthermore, we want to have to have two separate subdirectories
+in @file{build} -- @file{release} and @file{debug} -- which will contain
+the object files compiled with different set of compilation flags.
+
+In other words, we have the following structure:
+
+@smallexample
+@group
+ main
+ |- prog1
+ | |- build
+ | | debug
+ | | release
+ |- prog2
+ |- build
+ | debug
+ | release
+@end group
+@end smallexample
+
+@noindent
+Here are the project files that we must place in a directory @file{main}
+to maintain this structure:
+
+@enumerate
+
+@item We create a @code{Common} project with a package @code{Compiler} that
+specifies the compilation ^switches^switches^:
+
+@smallexample
+File "common.gpr":
+@group
+@b{project} Common @b{is}
+
+ @b{for} Source_Dirs @b{use} (); -- No source files
+@end group
+
+@group
+ @b{type} Build_Type @b{is} ("release", "debug");
+ Build : Build_Type := External ("BUILD", "debug");
+@end group
+@group
+ @b{package} Compiler @b{is}
+ @b{case} Build @b{is}
+ @b{when} "release" =>
+ @b{for} ^Default_Switches^Default_Switches^ ("Ada")
+ @b{use} ("^-O2^-O2^");
+ @b{when} "debug" =>
+ @b{for} ^Default_Switches^Default_Switches^ ("Ada")
+ @b{use} ("^-g^-g^");
+ @b{end case};
+ @b{end} Compiler;
+
+@b{end} Common;
+@end group
+@end smallexample
+
+@item We create separate projects for the two programs:
+
+@smallexample
+@group
+File "prog1.gpr":
+
+@b{with} "common";
+@b{project} Prog1 @b{is}
+
+ @b{for} Source_Dirs @b{use} ("prog1");
+ @b{for} Object_Dir @b{use} "prog1/build/" & Common.Build;
+
+ @b{package} Compiler @b{renames} Common.Compiler;
+
+@b{end} Prog1;
+@end group
+@end smallexample
+
+@smallexample
+@group
+File "prog2.gpr":
+
+@b{with} "common";
+@b{project} Prog2 @b{is}
+
+ @b{for} Source_Dirs @b{use} ("prog2");
+ @b{for} Object_Dir @b{use} "prog2/build/" & Common.Build;
+
+ @b{package} Compiler @b{renames} Common.Compiler;
+
+@end group
+@b{end} Prog2;
+@end smallexample
+
+@item We create a wrapping project @code{Main}:
+
+@smallexample
+@group
+File "main.gpr":
+
+@b{with} "common";
+@b{with} "prog1";
+@b{with} "prog2";
+@b{project} Main @b{is}
+
+ @b{package} Compiler @b{renames} Common.Compiler;
+
+@b{end} Main;
+@end group
+@end smallexample
+
+@item Finally we need to create a dummy procedure that @code{with}s (either
+explicitly or implicitly) all the sources of our two programs.
+
+@end enumerate
+
+@noindent
+Now we can build the programs using the command
+
+@smallexample
+ gnatmake ^-P^/PROJECT_FILE=^main dummy
+@end smallexample
+
+@noindent
+for the Debug mode, or
+
+@ifclear vms
+@smallexample
+ gnatmake -Pmain -XBUILD=release
+@end smallexample
+@end ifclear
+
+@ifset vms
+@smallexample
+ GNAT MAKE /PROJECT_FILE=main /EXTERNAL_REFERENCE=BUILD=release
+@end smallexample
+@end ifset
+
+@noindent
+for the Release mode.
+
+@c ********************************
+@c * Project File Complete Syntax *
+@c ********************************
+
+@node Project File Complete Syntax
+@section Project File Complete Syntax
+
+@smallexample
+project ::=
+ context_clause project_declaration
+
+context_clause ::=
+ @{with_clause@}
+
+with_clause ::=
+ @b{with} path_name @{ , path_name @} ;
+
+path_name ::=
+ string_literal
+
+project_declaration ::=
+ simple_project_declaration | project_extension
+
+simple_project_declaration ::=
+ @b{project} <project_>simple_name @b{is}
+ @{declarative_item@}
+ @b{end} <project_>simple_name;
+
+project_extension ::=
+ @b{project} <project_>simple_name @b{extends} path_name @b{is}
+ @{declarative_item@}
+ @b{end} <project_>simple_name;
+
+declarative_item ::=
+ package_declaration |
+ typed_string_declaration |
+ other_declarative_item
+
+package_declaration ::=
+ package_specification | package_renaming
+
+package_specification ::=
+ @b{package} package_identifier @b{is}
+ @{simple_declarative_item@}
+ @b{end} package_identifier ;
+
+package_identifier ::=
+ @code{Naming} | @code{Builder} | @code{Compiler} | @code{Binder} |
+ @code{Linker} | @code{Finder} | @code{Cross_Reference} |
+ @code{^gnatls^gnatls^} | @code{IDE} | @code{Pretty_Printer}
+
+package_renaming ::==
+ @b{package} package_identifier @b{renames}
+ <project_>simple_name.package_identifier ;
+
+typed_string_declaration ::=
+ @b{type} <typed_string_>_simple_name @b{is}
+ ( string_literal @{, string_literal@} );
+
+other_declarative_item ::=
+ attribute_declaration |
+ typed_variable_declaration |
+ variable_declaration |
+ case_construction
+
+attribute_declaration ::=
+ full_associative_array_declaration |
+ @b{for} attribute_designator @b{use} expression ;
+
+full_associative_array_declaration ::=
+ @b{for} <associative_array_attribute_>simple_name @b{use}
+ <project_>simple_name [ . <package_>simple_Name ] ' <attribute_>simple_name ;
+
+attribute_designator ::=
+ <simple_attribute_>simple_name |
+ <associative_array_attribute_>simple_name ( string_literal )
+
+typed_variable_declaration ::=
+ <typed_variable_>simple_name : <typed_string_>name := string_expression ;
+
+variable_declaration ::=
+ <variable_>simple_name := expression;
+
+expression ::=
+ term @{& term@}
+
+term ::=
+ literal_string |
+ string_list |
+ <variable_>name |
+ external_value |
+ attribute_reference
+
+string_literal ::=
+ (same as Ada)
+
+string_list ::=
+ ( <string_>expression @{ , <string_>expression @} )
+
+external_value ::=
+ @b{external} ( string_literal [, string_literal] )
+
+attribute_reference ::=
+ attribute_prefix ' <simple_attribute_>simple_name [ ( literal_string ) ]
+
+attribute_prefix ::=
+ @b{project} |
+ <project_>simple_name | package_identifier |
+ <project_>simple_name . package_identifier
+
+case_construction ::=
+ @b{case} <typed_variable_>name @b{is}
+ @{case_item@}
+ @b{end case} ;
+
+case_item ::=
+ @b{when} discrete_choice_list =>
+ @{case_construction | attribute_declaration@}
+
+discrete_choice_list ::=
+ string_literal @{| string_literal@} |
+ @b{others}
+
+name ::=
+ simple_name @{. simple_name@}
+
+simple_name ::=
+ identifier (same as Ada)
+
+@end smallexample
+
+
+@node The Cross-Referencing Tools gnatxref and gnatfind
+@chapter The Cross-Referencing Tools @code{gnatxref} and @code{gnatfind}
+@findex gnatxref
+@findex gnatfind
+
+@noindent
+The compiler generates cross-referencing information (unless
+you set the @samp{-gnatx} switch), which are saved in the @file{.ali} files.
+This information indicates where in the source each entity is declared and
+referenced. Note that entities in package Standard are not included, but
+entities in all other predefined units are included in the output.
+
+Before using any of these two tools, you need to compile successfully your
+application, so that GNAT gets a chance to generate the cross-referencing
+information.
+
+The two tools @code{gnatxref} and @code{gnatfind} take advantage of this
+information to provide the user with the capability to easily locate the
+declaration and references to an entity. These tools are quite similar,
+the difference being that @code{gnatfind} is intended for locating
+definitions and/or references to a specified entity or entities, whereas
+@code{gnatxref} is oriented to generating a full report of all
+cross-references.
+
+To use these tools, you must not compile your application using the
+@option{-gnatx} switch on the @file{gnatmake} command line
+(see @ref{The GNAT Make Program gnatmake}). Otherwise, cross-referencing
+information will not be generated.
+
+@menu
+* gnatxref Switches::
+* gnatfind Switches::
+* Project Files for gnatxref and gnatfind::
+* Regular Expressions in gnatfind and gnatxref::
+* Examples of gnatxref Usage::
+* Examples of gnatfind Usage::
+@end menu
+
+@node gnatxref Switches
+@section @code{gnatxref} Switches
+
+@noindent
+The command invocation for @code{gnatxref} is:
+@smallexample
+$ gnatxref [switches] sourcefile1 [sourcefile2 ...]
+@end smallexample
+
+@noindent
+where
+
+@table @code
+@item sourcefile1, sourcefile2
+identifies the source files for which a report is to be generated. The
+``with''ed units will be processed too. You must provide at least one file.
+
+These file names are considered to be regular expressions, so for instance
+specifying @file{source*.adb} is the same as giving every file in the current
+directory whose name starts with @file{source} and whose extension is
+@file{adb}.
+
+You shouldn't specify any directory name, just base names. @command{gnatxref}
+and @command{gnatfind} will be able to locate these files by themselves using
+the source path. If you specify directories, no result is produced.
+
+@end table
+
+@noindent
+The switches can be :
+@table @option
+@c !sort!
+@item ^-a^/ALL_FILES^
+@cindex @option{^-a^/ALL_FILES^} (@command{gnatxref})
+If this switch is present, @code{gnatfind} and @code{gnatxref} will parse
+the read-only files found in the library search path. Otherwise, these files
+will be ignored. This option can be used to protect Gnat sources or your own
+libraries from being parsed, thus making @code{gnatfind} and @code{gnatxref}
+much faster, and their output much smaller. Read-only here refers to access
+or permissions status in the file system for the current user.
+
+@item -aIDIR
+@cindex @option{-aIDIR} (@command{gnatxref})
+When looking for source files also look in directory DIR. The order in which
+source file search is undertaken is the same as for @file{gnatmake}.
+
+@item -aODIR
+@cindex @option{-aODIR} (@command{gnatxref})
+When searching for library and object files, look in directory
+DIR. The order in which library files are searched is the same as for
+@file{gnatmake}.
+
+@item -nostdinc
+@cindex @option{-nostdinc} (@command{gnatxref})
+Do not look for sources in the system default directory.
+
+@item -nostdlib
+@cindex @option{-nostdlib} (@command{gnatxref})
+Do not look for library files in the system default directory.
+
+@item --RTS=@var{rts-path}
+@cindex @option{--RTS} (@command{gnatxref})
+Specifies the default location of the runtime library. Same meaning as the
+equivalent @code{gnatmake} flag (see @ref{Switches for gnatmake}).
+
+@item ^-d^/DERIVED_TYPES^
+@cindex @option{^-d^/DERIVED_TYPES^} (@command{gnatxref})
+If this switch is set @code{gnatxref} will output the parent type
+reference for each matching derived types.
+
+@item ^-f^/FULL_PATHNAME^
+@cindex @option{^-f^/FULL_PATHNAME^} (@command{gnatxref})
+If this switch is set, the output file names will be preceded by their
+directory (if the file was found in the search path). If this switch is
+not set, the directory will not be printed.
+
+@item ^-g^/IGNORE_LOCALS^
+@cindex @option{^-g^/IGNORE_LOCALS^} (@command{gnatxref})
+If this switch is set, information is output only for library-level
+entities, ignoring local entities. The use of this switch may accelerate
+@code{gnatfind} and @code{gnatxref}.
+
+@item -IDIR
+@cindex @option{-IDIR} (@command{gnatxref})
+Equivalent to @samp{-aODIR -aIDIR}.
+
+@item -pFILE
+@cindex @option{-pFILE} (@command{gnatxref})
+Specify a project file to use @xref{Project Files}. These project files are
+the @file{.adp} files used by Glide. If you need to use the @file{.gpr}
+project files, you should use gnatxref through the GNAT driver
+(@command{gnat xref -Pproject}).
+
+By default, @code{gnatxref} and @code{gnatfind} will try to locate a
+project file in the current directory.
+
+If a project file is either specified or found by the tools, then the content
+of the source directory and object directory lines are added as if they
+had been specified respectively by @samp{^-aI^/SOURCE_SEARCH^}
+and @samp{^-aO^OBJECT_SEARCH^}.
+@item ^-u^/UNUSED^
+Output only unused symbols. This may be really useful if you give your
+main compilation unit on the command line, as @code{gnatxref} will then
+display every unused entity and 'with'ed package.
+
+@ifclear vms
+@item -v
+Instead of producing the default output, @code{gnatxref} will generate a
+@file{tags} file that can be used by vi. For examples how to use this
+feature, see @xref{Examples of gnatxref Usage}. The tags file is output
+to the standard output, thus you will have to redirect it to a file.
+@end ifclear
+
+@end table
+
+@noindent
+All these switches may be in any order on the command line, and may even
+appear after the file names. They need not be separated by spaces, thus
+you can say @samp{gnatxref ^-ag^/ALL_FILES/IGNORE_LOCALS^} instead of
+@samp{gnatxref ^-a -g^/ALL_FILES /IGNORE_LOCALS^}.
+
+@node gnatfind Switches
+@section @code{gnatfind} Switches
+
+@noindent
+The command line for @code{gnatfind} is:
+
+@smallexample
+$ gnatfind [switches] pattern[:sourcefile[:line[:column]]]
+ [file1 file2 ...]
+@end smallexample
+
+@noindent
+where
+
+@table @code
+@item pattern
+An entity will be output only if it matches the regular expression found
+in @samp{pattern}, see @xref{Regular Expressions in gnatfind and gnatxref}.
+
+Omitting the pattern is equivalent to specifying @samp{*}, which
+will match any entity. Note that if you do not provide a pattern, you
+have to provide both a sourcefile and a line.
+
+Entity names are given in Latin-1, with uppercase/lowercase equivalence
+for matching purposes. At the current time there is no support for
+8-bit codes other than Latin-1, or for wide characters in identifiers.
+
+@item sourcefile
+@code{gnatfind} will look for references, bodies or declarations
+of symbols referenced in @file{sourcefile}, at line @samp{line}
+and column @samp{column}. See @pxref{Examples of gnatfind Usage}
+for syntax examples.
+
+@item line
+is a decimal integer identifying the line number containing
+the reference to the entity (or entities) to be located.
+
+@item column
+is a decimal integer identifying the exact location on the
+line of the first character of the identifier for the
+entity reference. Columns are numbered from 1.
+
+@item file1 file2 ...
+The search will be restricted to these source files. If none are given, then
+the search will be done for every library file in the search path.
+These file must appear only after the pattern or sourcefile.
+
+These file names are considered to be regular expressions, so for instance
+specifying 'source*.adb' is the same as giving every file in the current
+directory whose name starts with 'source' and whose extension is 'adb'.
+
+The location of the spec of the entity will always be displayed, even if it
+isn't in one of file1, file2,... The occurrences of the entity in the
+separate units of the ones given on the command line will also be displayed.
+
+Note that if you specify at least one file in this part, @code{gnatfind} may
+sometimes not be able to find the body of the subprograms...
+
+@end table
+
+@noindent
+At least one of 'sourcefile' or 'pattern' has to be present on
+the command line.
+
+The following switches are available:
+@table @option
+@c !sort!
+
+@item ^-a^/ALL_FILES^
+@cindex @option{^-a^/ALL_FILES^} (@command{gnatfind})
+If this switch is present, @code{gnatfind} and @code{gnatxref} will parse
+the read-only files found in the library search path. Otherwise, these files
+will be ignored. This option can be used to protect Gnat sources or your own
+libraries from being parsed, thus making @code{gnatfind} and @code{gnatxref}
+much faster, and their output much smaller. Read-only here refers to access
+or permission status in the file system for the current user.
+
+@item -aIDIR
+@cindex @option{-aIDIR} (@command{gnatfind})
+When looking for source files also look in directory DIR. The order in which
+source file search is undertaken is the same as for @file{gnatmake}.
+
+@item -aODIR
+@cindex @option{-aODIR} (@command{gnatfind})
+When searching for library and object files, look in directory
+DIR. The order in which library files are searched is the same as for
+@file{gnatmake}.
+
+@item -nostdinc
+@cindex @option{-nostdinc} (@command{gnatfind})
+Do not look for sources in the system default directory.
+
+@item -nostdlib
+@cindex @option{-nostdlib} (@command{gnatfind})
+Do not look for library files in the system default directory.
+
+@item --RTS=@var{rts-path}
+@cindex @option{--RTS} (@command{gnatfind})
+Specifies the default location of the runtime library. Same meaning as the
+equivalent @code{gnatmake} flag (see @ref{Switches for gnatmake}).
+
+@item ^-d^/DERIVED_TYPE_INFORMATION^
+@cindex @option{^-d^/DERIVED_TYPE_INFORMATION^} (@code{gnatfind})
+If this switch is set, then @code{gnatfind} will output the parent type
+reference for each matching derived types.
+
+@item ^-e^/EXPRESSIONS^
+@cindex @option{^-e^/EXPRESSIONS^} (@command{gnatfind})
+By default, @code{gnatfind} accept the simple regular expression set for
+@samp{pattern}. If this switch is set, then the pattern will be
+considered as full Unix-style regular expression.
+
+@item ^-f^/FULL_PATHNAME^
+@cindex @option{^-f^/FULL_PATHNAME^} (@command{gnatfind})
+If this switch is set, the output file names will be preceded by their
+directory (if the file was found in the search path). If this switch is
+not set, the directory will not be printed.
+
+@item ^-g^/IGNORE_LOCALS^
+@cindex @option{^-g^/IGNORE_LOCALS^} (@command{gnatfind})
+If this switch is set, information is output only for library-level
+entities, ignoring local entities. The use of this switch may accelerate
+@code{gnatfind} and @code{gnatxref}.
+
+@item -IDIR
+@cindex @option{-IDIR} (@command{gnatfind})
+Equivalent to @samp{-aODIR -aIDIR}.
+
+@item -pFILE
+@cindex @option{-pFILE} (@command{gnatfind})
+Specify a project file (@pxref{Project Files}) to use.
+By default, @code{gnatxref} and @code{gnatfind} will try to locate a
+project file in the current directory.
+
+If a project file is either specified or found by the tools, then the content
+of the source directory and object directory lines are added as if they
+had been specified respectively by @samp{^-aI^/SOURCE_SEARCH^} and
+@samp{^-aO^/OBJECT_SEARCH^}.
+
+@item ^-r^/REFERENCES^
+@cindex @option{^-r^/REFERENCES^} (@command{gnatfind})
+By default, @code{gnatfind} will output only the information about the
+declaration, body or type completion of the entities. If this switch is
+set, the @code{gnatfind} will locate every reference to the entities in
+the files specified on the command line (or in every file in the search
+path if no file is given on the command line).
+
+@item ^-s^/PRINT_LINES^
+@cindex @option{^-s^/PRINT_LINES^} (@command{gnatfind})
+If this switch is set, then @code{gnatfind} will output the content
+of the Ada source file lines were the entity was found.
+
+@item ^-t^/TYPE_HIERARCHY^
+@cindex @option{^-t^/TYPE_HIERARCHY^} (@command{gnatfind})
+If this switch is set, then @code{gnatfind} will output the type hierarchy for
+the specified type. It act like -d option but recursively from parent
+type to parent type. When this switch is set it is not possible to
+specify more than one file.
+
+@end table
+
+@noindent
+All these switches may be in any order on the command line, and may even
+appear after the file names. They need not be separated by spaces, thus
+you can say @samp{gnatxref ^-ag^/ALL_FILES/IGNORE_LOCALS^} instead of
+@samp{gnatxref ^-a -g^/ALL_FILES /IGNORE_LOCALS^}.
+
+As stated previously, gnatfind will search in every directory in the
+search path. You can force it to look only in the current directory if
+you specify @code{*} at the end of the command line.
+
+@node Project Files for gnatxref and gnatfind
+@section Project Files for @command{gnatxref} and @command{gnatfind}
+
+@noindent
+Project files allow a programmer to specify how to compile its
+application, where to find sources, etc. These files are used
+@ifclear vms
+primarily by the Glide Ada mode, but they can also be used
+@end ifclear
+by the two tools
+@code{gnatxref} and @code{gnatfind}.
+
+A project file name must end with @file{.gpr}. If a single one is
+present in the current directory, then @code{gnatxref} and @code{gnatfind} will
+extract the information from it. If multiple project files are found, none of
+them is read, and you have to use the @samp{-p} switch to specify the one
+you want to use.
+
+The following lines can be included, even though most of them have default
+values which can be used in most cases.
+The lines can be entered in any order in the file.
+Except for @file{src_dir} and @file{obj_dir}, you can only have one instance of
+each line. If you have multiple instances, only the last one is taken into
+account.
+
+@table @code
+@item src_dir=DIR
+[default: @code{"^./^[]^"}]
+specifies a directory where to look for source files. Multiple @code{src_dir}
+lines can be specified and they will be searched in the order they
+are specified.
+
+@item obj_dir=DIR
+[default: @code{"^./^[]^"}]
+specifies a directory where to look for object and library files. Multiple
+@code{obj_dir} lines can be specified, and they will be searched in the order
+they are specified
+
+@item comp_opt=SWITCHES
+[default: @code{""}]
+creates a variable which can be referred to subsequently by using
+the @code{$@{comp_opt@}} notation. This is intended to store the default
+switches given to @command{gnatmake} and @command{gcc}.
+
+@item bind_opt=SWITCHES
+[default: @code{""}]
+creates a variable which can be referred to subsequently by using
+the @samp{$@{bind_opt@}} notation. This is intended to store the default
+switches given to @command{gnatbind}.
+
+@item link_opt=SWITCHES
+[default: @code{""}]
+creates a variable which can be referred to subsequently by using
+the @samp{$@{link_opt@}} notation. This is intended to store the default
+switches given to @command{gnatlink}.
+
+@item main=EXECUTABLE
+[default: @code{""}]
+specifies the name of the executable for the application. This variable can
+be referred to in the following lines by using the @samp{$@{main@}} notation.
+
+@ifset vms
+@item comp_cmd=COMMAND
+[default: @code{"GNAT COMPILE /SEARCH=$@{src_dir@} /DEBUG /TRY_SEMANTICS"}]
+@end ifset
+@ifclear vms
+@item comp_cmd=COMMAND
+[default: @code{"gcc -c -I$@{src_dir@} -g -gnatq"}]
+@end ifclear
+specifies the command used to compile a single file in the application.
+
+@ifset vms
+@item make_cmd=COMMAND
+[default: @code{"GNAT MAKE $@{main@}
+/SOURCE_SEARCH=$@{src_dir@} /OBJECT_SEARCH=$@{obj_dir@}
+/DEBUG /TRY_SEMANTICS /COMPILER_QUALIFIERS $@{comp_opt@}
+/BINDER_QUALIFIERS $@{bind_opt@} /LINKER_QUALIFIERS $@{link_opt@}"}]
+@end ifset
+@ifclear vms
+@item make_cmd=COMMAND
+[default: @code{"gnatmake $@{main@} -aI$@{src_dir@}
+ -aO$@{obj_dir@} -g -gnatq -cargs $@{comp_opt@}
+ -bargs $@{bind_opt@} -largs $@{link_opt@}"}]
+@end ifclear
+specifies the command used to recompile the whole application.
+
+@item run_cmd=COMMAND
+[default: @code{"$@{main@}"}]
+specifies the command used to run the application.
+
+@item debug_cmd=COMMAND
+[default: @code{"gdb $@{main@}"}]
+specifies the command used to debug the application
+
+@end table
+
+@noindent
+@command{gnatxref} and @command{gnatfind} only take into account the
+@code{src_dir} and @code{obj_dir} lines, and ignore the others.
+
+@node Regular Expressions in gnatfind and gnatxref
+@section Regular Expressions in @code{gnatfind} and @code{gnatxref}
+
+@noindent
+As specified in the section about @command{gnatfind}, the pattern can be a
+regular expression. Actually, there are to set of regular expressions
+which are recognized by the program :
+
+@table @code
+@item globbing patterns
+These are the most usual regular expression. They are the same that you
+generally used in a Unix shell command line, or in a DOS session.
+
+Here is a more formal grammar :
+@smallexample
+@group
+@iftex
+@leftskip=.5cm
+@end iftex
+regexp ::= term
+term ::= elmt -- matches elmt
+term ::= elmt elmt -- concatenation (elmt then elmt)
+term ::= * -- any string of 0 or more characters
+term ::= ? -- matches any character
+term ::= [char @{char@}] -- matches any character listed
+term ::= [char - char] -- matches any character in range
+@end group
+@end smallexample
+
+@item full regular expression
+The second set of regular expressions is much more powerful. This is the
+type of regular expressions recognized by utilities such a @file{grep}.
+
+The following is the form of a regular expression, expressed in Ada
+reference manual style BNF is as follows
+
+@smallexample
+@iftex
+@leftskip=.5cm
+@end iftex
+@group
+regexp ::= term @{| term@} -- alternation (term or term ...)
+
+term ::= item @{item@} -- concatenation (item then item)
+
+item ::= elmt -- match elmt
+item ::= elmt * -- zero or more elmt's
+item ::= elmt + -- one or more elmt's
+item ::= elmt ? -- matches elmt or nothing
+@end group
+@group
+elmt ::= nschar -- matches given character
+elmt ::= [nschar @{nschar@}] -- matches any character listed
+elmt ::= [^^^ nschar @{nschar@}] -- matches any character not listed
+elmt ::= [char - char] -- matches chars in given range
+elmt ::= \ char -- matches given character
+elmt ::= . -- matches any single character
+elmt ::= ( regexp ) -- parens used for grouping
+
+char ::= any character, including special characters
+nschar ::= any character except ()[].*+?^^^
+@end group
+@end smallexample
+
+Following are a few examples :
+
+@table @samp
+@item abcde|fghi
+will match any of the two strings 'abcde' and 'fghi'.
+
+@item abc*d
+will match any string like 'abd', 'abcd', 'abccd', 'abcccd', and so on
+
+@item [a-z]+
+will match any string which has only lowercase characters in it (and at
+least one character
+
+@end table
+@end table
+
+@node Examples of gnatxref Usage
+@section Examples of @code{gnatxref} Usage
+
+@subsection General Usage
+
+@noindent
+For the following examples, we will consider the following units :
+
+@smallexample @c ada
+@group
+@cartouche
+main.ads:
+1: with Bar;
+2: package Main is
+3: procedure Foo (B : in Integer);
+4: C : Integer;
+5: private
+6: D : Integer;
+7: end Main;
+
+main.adb:
+1: package body Main is
+2: procedure Foo (B : in Integer) is
+3: begin
+4: C := B;
+5: D := B;
+6: Bar.Print (B);
+7: Bar.Print (C);
+8: end Foo;
+9: end Main;
+
+bar.ads:
+1: package Bar is
+2: procedure Print (B : Integer);
+3: end bar;
+@end cartouche
+@end group
+@end smallexample
+
+@table @code
+
+@noindent
+The first thing to do is to recompile your application (for instance, in
+that case just by doing a @samp{gnatmake main}, so that GNAT generates
+the cross-referencing information.
+You can then issue any of the following commands:
+
+@item gnatxref main.adb
+@code{gnatxref} generates cross-reference information for main.adb
+and every unit 'with'ed by main.adb.
+
+The output would be:
+@smallexample
+@iftex
+@leftskip=0cm
+@end iftex
+B Type: Integer
+ Decl: bar.ads 2:22
+B Type: Integer
+ Decl: main.ads 3:20
+ Body: main.adb 2:20
+ Ref: main.adb 4:13 5:13 6:19
+Bar Type: Unit
+ Decl: bar.ads 1:9
+ Ref: main.adb 6:8 7:8
+ main.ads 1:6
+C Type: Integer
+ Decl: main.ads 4:5
+ Modi: main.adb 4:8
+ Ref: main.adb 7:19
+D Type: Integer
+ Decl: main.ads 6:5
+ Modi: main.adb 5:8
+Foo Type: Unit
+ Decl: main.ads 3:15
+ Body: main.adb 2:15
+Main Type: Unit
+ Decl: main.ads 2:9
+ Body: main.adb 1:14
+Print Type: Unit
+ Decl: bar.ads 2:15
+ Ref: main.adb 6:12 7:12
+@end smallexample
+
+@noindent
+that is the entity @code{Main} is declared in main.ads, line 2, column 9,
+its body is in main.adb, line 1, column 14 and is not referenced any where.
+
+The entity @code{Print} is declared in bar.ads, line 2, column 15 and it
+it referenced in main.adb, line 6 column 12 and line 7 column 12.
+
+@item gnatxref package1.adb package2.ads
+@code{gnatxref} will generates cross-reference information for
+package1.adb, package2.ads and any other package 'with'ed by any
+of these.
+
+@end table
+
+@ifclear vms
+@subsection Using gnatxref with vi
+
+@code{gnatxref} can generate a tags file output, which can be used
+directly from @file{vi}. Note that the standard version of @file{vi}
+will not work properly with overloaded symbols. Consider using another
+free implementation of @file{vi}, such as @file{vim}.
+
+@smallexample
+$ gnatxref -v gnatfind.adb > tags
+@end smallexample
+
+@noindent
+will generate the tags file for @code{gnatfind} itself (if the sources
+are in the search path!).
+
+From @file{vi}, you can then use the command @samp{:tag @i{entity}}
+(replacing @i{entity} by whatever you are looking for), and vi will
+display a new file with the corresponding declaration of entity.
+@end ifclear
+
+@node Examples of gnatfind Usage
+@section Examples of @code{gnatfind} Usage
+
+@table @code
+
+@item gnatfind ^-f^/FULL_PATHNAME^ xyz:main.adb
+Find declarations for all entities xyz referenced at least once in
+main.adb. The references are search in every library file in the search
+path.
+
+The directories will be printed as well (as the @samp{^-f^/FULL_PATHNAME^}
+switch is set)
+
+The output will look like:
+@smallexample
+^directory/^[directory]^main.ads:106:14: xyz <= declaration
+^directory/^[directory]^main.adb:24:10: xyz <= body
+^directory/^[directory]^foo.ads:45:23: xyz <= declaration
+@end smallexample
+
+@noindent
+that is to say, one of the entities xyz found in main.adb is declared at
+line 12 of main.ads (and its body is in main.adb), and another one is
+declared at line 45 of foo.ads
+
+@item gnatfind ^-fs^/FULL_PATHNAME/SOURCE_LINE^ xyz:main.adb
+This is the same command as the previous one, instead @code{gnatfind} will
+display the content of the Ada source file lines.
+
+The output will look like:
+
+@smallexample
+^directory/^[directory]^main.ads:106:14: xyz <= declaration
+ procedure xyz;
+^directory/^[directory]^main.adb:24:10: xyz <= body
+ procedure xyz is
+^directory/^[directory]^foo.ads:45:23: xyz <= declaration
+ xyz : Integer;
+@end smallexample
+
+@noindent
+This can make it easier to find exactly the location your are looking
+for.
+
+@item gnatfind ^-r^/REFERENCES^ "*x*":main.ads:123 foo.adb
+Find references to all entities containing an x that are
+referenced on line 123 of main.ads.
+The references will be searched only in main.ads and foo.adb.
+
+@item gnatfind main.ads:123
+Find declarations and bodies for all entities that are referenced on
+line 123 of main.ads.
+
+This is the same as @code{gnatfind "*":main.adb:123}.
+
+@item gnatfind ^mydir/^[mydir]^main.adb:123:45
+Find the declaration for the entity referenced at column 45 in
+line 123 of file main.adb in directory mydir. Note that it
+is usual to omit the identifier name when the column is given,
+since the column position identifies a unique reference.
+
+The column has to be the beginning of the identifier, and should not
+point to any character in the middle of the identifier.
+
+@end table
+
+
+@c *********************************
+@node The GNAT Pretty-Printer gnatpp
+@chapter The GNAT Pretty-Printer @command{gnatpp}
+@findex gnatpp
+@cindex Pretty-Printer
+
+@noindent
+^The @command{gnatpp} tool^GNAT PRETTY^ is an ASIS-based utility
+for source reformatting / pretty-printing.
+It takes an Ada source file as input and generates a reformatted
+version as output.
+You can specify various style directives via switches; e.g.,
+identifier case conventions, rules of indentation, and comment layout.
+
+To produce a reformatted file, @command{gnatpp} generates and uses the ASIS
+tree for the input source and thus requires the input to be syntactically and
+semantically legal.
+If this condition is not met, @command{gnatpp} will terminate with an
+error message; no output file will be generated.
+
+If the compilation unit
+contained in the input source depends semantically upon units located
+outside the current directory, you have to provide the source search path
+when invoking @command{gnatpp}, if these units are contained in files with
+names that do not follow the GNAT file naming rules, you have to provide
+the configuration file describing the corresponding naming scheme;
+see the description of the @command{gnatpp}
+switches below. Another possibility is to use a project file and to
+call @command{gnatpp} through the @command{gnat} driver
+
+The @command{gnatpp} command has the form
+
+@smallexample
+$ gnatpp [@var{switches}] @var{filename}
+@end smallexample
+
+@noindent
+where
+@itemize @bullet
+@item
+@var{switches} is an optional sequence of switches defining such properties as
+the formatting rules, the source search path, and the destination for the
+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
+@end itemize
+
+
+@menu
+* Switches for gnatpp::
+* Formatting Rules::
+@end menu
+
+@node Switches for gnatpp
+@section Switches for @command{gnatpp}
+
+@noindent
+The following subsections describe the various switches accepted by
+@command{gnatpp}, organized by category.
+
+@ifclear vms
+You specify a switch by supplying a name and generally also a value.
+In many cases the values for a switch with a given name are incompatible with
+each other
+(for example the switch that controls the casing of a reserved word may have
+exactly one value: upper case, lower case, or
+mixed case) and thus exactly one such switch can be in effect for an
+invocation of @command{gnatpp}.
+If more than one is supplied, the last one is used.
+However, some values for the same switch are mutually compatible.
+You may supply several such switches to @command{gnatpp}, but then
+each must be specified in full, with both the name and the value.
+Abbreviated forms (the name appearing once, followed by each value) are
+not permitted.
+For example, to set
+the alignment of the assignment delimiter both in declarations and in
+assignment statements, you must write @option{-A2A3}
+(or @option{-A2 -A3}), but not @option{-A23}.
+@end ifclear
+
+@ifset vms
+In many cases the set of options for a given qualifier are incompatible with
+each other (for example the qualifier that controls the casing of a reserved
+word may have exactly one option, which specifies either upper case, lower
+case, or mixed case), and thus exactly one such option can be in effect for
+an invocation of @command{gnatpp}.
+If more than one is supplied, the last one is used.
+However, some qualifiers have options that are mutually compatible,
+and then you may then supply several such options when invoking
+@command{gnatpp}.
+@end ifset
+
+In most cases, it is obvious whether or not the
+^values for a switch with a given name^options for a given qualifier^
+are compatible with each other.
+When the semantics might not be evident, the summaries below explicitly
+indicate the effect.
+
+@menu
+* Alignment Control::
+* Casing Control::
+* Construct Layout Control::
+* General Text Layout Control::
+* Other Formatting Options::
+* Setting the Source Search Path::
+* Output File Control::
+* Other gnatpp Switches::
+@end menu
+
+
+@node Alignment Control
+@subsection Alignment Control
+@cindex Alignment control in @command{gnatpp}
+
+@noindent
+Programs can be easier to read if certain constructs are vertically aligned.
+By default all alignments are set ON.
+Through the @option{^-A0^/ALIGN=OFF^} switch you may reset the default to
+OFF, and then use one or more of the other
+^@option{-A@var{n}} switches^@option{/ALIGN} options^
+to activate alignment for specific constructs.
+
+@table @option
+@cindex @option{^-A@var{n}^/ALIGN^} (@command{gnatpp})
+
+@ifset vms
+@item /ALIGN=ON
+Set all alignments to ON
+@end ifset
+
+@item ^-A0^/ALIGN=OFF^
+Set all alignments to OFF
+
+@item ^-A1^/ALIGN=COLONS^
+Align @code{:} in declarations
+
+@item ^-A2^/ALIGN=DECLARATIONS^
+Align @code{:=} in initializations in declarations
+
+@item ^-A3^/ALIGN=STATEMENTS^
+Align @code{:=} in assignment statements
+
+@item ^-A4^/ALIGN=ARROWS^
+Align @code{=>} in associations
+@end table
+
+@noindent
+The @option{^-A^/ALIGN^} switches are mutually compatible; any combination
+is allowed.
+
+
+@node Casing Control
+@subsection Casing Control
+@cindex Casing control in @command{gnatpp}
+
+@noindent
+@command{gnatpp} allows you to specify the casing for reserved words,
+pragma names, attribute designators and identifiers.
+For identifiers you may define a
+general rule for name casing but also override this rule
+via a set of dictionary files.
+
+Three types of casing are supported: lower case, upper case, and mixed case.
+Lower and upper case are self-explanatory (but since some letters in
+Latin1 and other GNAT-supported character sets
+exist only in lower-case form, an upper case conversion will have no
+effect on them.)
+``Mixed case'' means that the first letter, and also each letter immediately
+following an underscore, are converted to their uppercase forms;
+all the other letters are converted to their lowercase forms.
+
+@table @option
+@cindex @option{^-a@var{x}^/ATTRIBUTE^} (@command{gnatpp})
+@item ^-aL^/ATTRIBUTE_CASING=LOWER_CASE^
+Attribute designators are lower case
+
+@item ^-aU^/ATTRIBUTE_CASING=UPPER_CASE^
+Attribute designators are upper case
+
+@item ^-aM^/ATTRIBUTE_CASING=MIXED_CASE^
+Attribute designators are mixed case (this is the default)
+
+@cindex @option{^-k@var{x}^/KEYWORD_CASING^} (@command{gnatpp})
+@item ^-kL^/KEYWORD_CASING=LOWER_CASE^
+Keywords (technically, these are known in Ada as @emph{reserved words}) are
+lower case (this is the default)
+
+@item ^-kU^/KEYWORD_CASING=UPPER_CASE^
+Keywords are upper case
+
+@cindex @option{^-n@var{x}^/NAME_CASING^} (@command{gnatpp})
+@item ^-nD^/NAME_CASING=AS_DECLARED^
+Name casing for defining occurrences are as they appear in the source file
+(this is the default)
+
+@item ^-nU^/NAME_CASING=UPPER_CASE^
+Names are in upper case
+
+@item ^-nL^/NAME_CASING=LOWER_CASE^
+Names are in lower case
+
+@item ^-nM^/NAME_CASING=MIXED_CASE^
+Names are in mixed case
+
+@cindex @option{^-p@var{x}^/PRAGMA_CASING^} (@command{gnatpp})
+@item ^-pL^/PRAGMA_CASING=LOWER_CASE^
+Pragma names are lower case
+
+@item ^-pU^/PRAGMA_CASING=UPPER_CASE^
+Pragma names are upper case
+
+@item ^-pM^/PRAGMA_CASING=MIXED_CASE^
+Pragma names are mixed case (this is the default)
+
+@item ^-D@var{file}^/DICTIONARY=@var{file}^
+@cindex @option{^-D^/DICTIONARY^} (@command{gnatpp})
+Use @var{file} as a @emph{dictionary file} that defines
+the casing for a set of specified names,
+thereby overriding the effect on these names by
+any explicit or implicit
+^-n^/NAME_CASING^ switch.
+To supply more than one dictionary file,
+use ^several @option{-D} switches^a list of files as options^.
+
+@noindent
+@option{gnatpp} implicitly uses a @emph{default dictionary file}
+to define the casing for the Ada predefined names and
+the names declared in the GNAT libraries.
+
+@item ^-D-^/SPECIFIC_CASING^
+@cindex @option{^-D-^/SPECIFIC_CASING^} (@command{gnatpp})
+Do not use the default dictionary file;
+instead, use the casing
+defined by a @option{^-n^/NAME_CASING^} switch and any explicit
+dictionary file(s)
+@end table
+
+@noindent
+The structure of a dictionary file, and details on the conventions
+used in the default dictionary file, are defined in @ref{Name Casing}.
+
+The @option{^-D-^/SPECIFIC_CASING^} and
+@option{^-D@var{file}^/DICTIONARY=@var{file}^} switches are mutually
+compatible.
+
+
+@node Construct Layout Control
+@subsection Construct Layout Control
+@cindex Layout control in @command{gnatpp}
+
+@noindent
+This group of @command{gnatpp} switches controls the layout of comments and
+complex syntactic constructs. See @ref{Formatting Comments}, for details
+on their effect.
+
+@table @option
+@cindex @option{^-c@var{n}^/COMMENTS_LAYOUT^} (@command{gnatpp})
+@item ^-c0^/COMMENTS_LAYOUT=UNTOUCHED^
+All the comments remain unchanged
+
+@item ^-c1^/COMMENTS_LAYOUT=DEFAULT^
+GNAT-style comment line indentation (this is the default).
+
+@item ^-c2^/COMMENTS_LAYOUT=STANDARD_INDENT^
+Reference-manual comment line indentation.
+
+@item ^-c3^/COMMENTS_LAYOUT=GNAT_BEGINNING^
+GNAT-style comment beginning
+
+@item ^-c4^/COMMENTS_LAYOUT=REFORMAT^
+Reformat comment blocks
+
+@cindex @option{^-l@var{n}^/CONSTRUCT_LAYOUT^} (@command{gnatpp})
+@item ^-l1^/CONSTRUCT_LAYOUT=GNAT^
+GNAT-style layout (this is the default)
+
+@item ^-l2^/CONSTRUCT_LAYOUT=COMPACT^
+Compact layout
+
+@item ^-l3^/CONSTRUCT_LAYOUT=UNCOMPACT^
+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.
+
+@end table
+
+@ifclear vms
+@noindent
+The @option{-c1} and @option{-c2} switches are incompatible.
+The @option{-c3} and @option{-c4} switches are compatible with each other and
+also with @option{-c1} and @option{-c2}. The @option{-c0} switch disables all
+the other comment formatting switches.
+
+The @option{-l1}, @option{-l2}, and @option{-l3} switches are incompatible.
+@end ifclear
+
+@ifset vms
+@noindent
+For the @option{/COMMENTS_LAYOUT} qualifier:
+@itemize @bullet
+@item
+The @option{DEFAULT} and @option{STANDARD_INDENT} options are incompatible.
+@item
+The @option{GNAT_BEGINNING} and @option{REFORMAT} options are compatible with
+each other and also with @option{DEFAULT} and @option{STANDARD_INDENT}.
+@end itemize
+
+@noindent
+The @option{GNAT}, @option{COMPACT}, and @option{UNCOMPACT} options for the
+@option{/CONSTRUCT_LAYOUT} qualifier are incompatible.
+@end ifset
+
+@node General Text Layout Control
+@subsection General Text Layout Control
+
+@noindent
+These switches allow control over line length and indentation.
+
+@table @option
+@item ^-M@i{nnn}^/LINE_LENGTH_MAX=@i{nnn}^
+@cindex @option{^-M^/LINE_LENGTH^} (@command{gnatpp})
+Maximum line length, @i{nnn} from 32 ..256, the default value is 79
+
+@item ^-i@i{nnn}^/INDENTATION_LEVEL=@i{nnn}^
+@cindex @option{^-i^/INDENTATION_LEVEL^} (@command{gnatpp})
+Indentation level, @i{nnn} from 1 .. 9, the default value is 3
+
+@item ^-cl@i{nnn}^/CONTINUATION_INDENT=@i{nnn}^
+@cindex @option{^-cl^/CONTINUATION_INDENT^} (@command{gnatpp})
+Indentation level for continuation lines (relative to the line being
+continued), @i{nnn} from 1 .. 9.
+The default
+value is one less then the (normal) indentation level, unless the
+indentation is set to 1 (in which case the default value for continuation
+line indentation is also 1)
+@end table
+
+
+@node Other Formatting Options
+@subsection Other Formatting Options
+
+@noindent
+These switches control the inclusion of missing end/exit labels, and
+the indentation level in @b{case} statements.
+
+@table @option
+@item ^-e^/NO_MISSED_LABELS^
+@cindex @option{^-e^/NO_MISSED_LABELS^} (@command{gnatpp})
+Do not insert missing end/exit labels. An end label is the name of
+a construct that may optionally be repeated at the end of the
+construct's declaration;
+e.g., the names of packages, subprograms, and tasks.
+An exit label is the name of a loop that may appear as target
+of an exit statement within the loop.
+By default, @command{gnatpp} inserts these end/exit labels when
+they are absent from the original source. This option suppresses such
+insertion, so that the formatted source reflects the original.
+
+@item ^-ff^/FORM_FEED_AFTER_PRAGMA_PAGE^
+@cindex @option{^-ff^/FORM_FEED_AFTER_PRAGMA_PAGE^} (@command{gnatpp})
+Insert a Form Feed character after a pragma Page.
+
+@item ^-T@i{nnn}^/MAX_INDENT=@i{nnn}^
+@cindex @option{^-T^/MAX_INDENT^} (@command{gnatpp})
+Do not use an additional indentation level for @b{case} alternatives
+and variants if there are @i{nnn} or more (the default
+value is 10).
+If @i{nnn} is 0, an additional indentation level is
+used for @b{case} alternatives and variants regardless of their number.
+@end table
+
+@node Setting the Source Search Path
+@subsection Setting the Source Search Path
+
+@noindent
+To define the search path for the input source file, @command{gnatpp}
+uses the same switches as the GNAT compiler, with the same effects.
+
+@table @option
+@item ^-I^/SEARCH=^@var{dir}
+@cindex @option{^-I^/SEARCH^} (@code{gnatpp})
+The same as the corresponding gcc switch
+
+@item ^-I-^/NOCURRENT_DIRECTORY^
+@cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatpp})
+The same as the corresponding gcc switch
+
+@item ^-gnatec^/CONFIGURATION_PRAGMAS_FILE^=@var{path}
+@cindex @option{^-gnatec^/CONFIGURATION_PRAGMAS_FILE^} (@code{gnatpp})
+The same as the corresponding gcc switch
+
+@item ^--RTS^/RUNTIME_SYSTEM^=@var{path}
+@cindex @option{^--RTS^/RUNTIME_SYSTEM^} (@code{gnatpp})
+The same as the corresponding gcc switch
+
+@end table
+
+
+@node Output File Control
+@subsection Output File Control
+
+@noindent
+By default the output is sent to the file whose name is obtained by appending
+the ^@file{.pp}^@file{$PP}^ suffix to the name of the input file
+(if the file with this name already exists, it is unconditionally overwritten).
+Thus if the input file is @file{^my_ada_proc.adb^MY_ADA_PROC.ADB^} then
+@command{gnatpp} will produce @file{^my_ada_proc.adb.pp^MY_ADA_PROC.ADB$PP^}
+as output file.
+The output may be redirected by the following switches:
+
+@table @option
+@item ^-pipe^/STANDARD_OUTPUT^
+@cindex @option{^-pipe^/STANDARD_OUTPUT^} (@code{gnatpp})
+Send the output to @code{Standard_Output}
+
+@item ^-o @var{output_file}^/OUTPUT=@var{output_file}^
+@cindex @option{^-o^/OUTPUT^} (@code{gnatpp})
+Write the output into @var{output_file}.
+If @var{output_file} already exists, @command{gnatpp} terminates without
+reading or processing the input file.
+
+@item ^-of ^/FORCED_OUTPUT=^@var{output_file}
+@cindex @option{^-of^/FORCED_OUTPUT^} (@code{gnatpp})
+Write the output into @var{output_file}, overwriting the existing file
+(if one is present).
+
+@item ^-r^/REPLACE^
+@cindex @option{^-r^/REPLACE^} (@code{gnatpp})
+Replace the input source file with the reformatted output, and copy the
+original input source into the file whose name is obtained by appending the
+^@file{.npp}^@file{$NPP}^ suffix to the name of the input file.
+If a file with this name already exists, @command{gnatpp} terminates without
+reading or processing the input file.
+
+@item ^-rf^/OVERRIDING_REPLACE^
+@cindex @option{^-rf^/OVERRIDING_REPLACE^} (@code{gnatpp})
+Like @option{^-r^/REPLACE^} except that if the file with the specified name
+already exists, it is overwritten.
+
+@item ^-rnb^/NO_BACKUP^
+@cindex @option{^-rnb^/NO_BACKUP^} (@code{gnatpp})
+Replace the input source file with the reformatted output without
+creating any backup copy of the input source.
+@end table
+
+@noindent
+Options @option{^-pipe^/STANDARD_OUTPUT^},
+@option{^-o^/OUTPUT^} and
+@option{^-of^/FORCED_OUTPUT^} are allowed only if the call to gnatpp
+contains only one file to reformat
+
+@node Other gnatpp Switches
+@subsection Other @code{gnatpp} Switches
+
+@noindent
+The additional @command{gnatpp} switches are defined in this subsection.
+
+@table @option
+@item ^-files @var{filename}^/FILES=@var{output_file}^
+@cindex @option{^-files^/FILES^} (@code{gnatpp})
+Take the argument source files from the specified file. This file should be an
+ordinary textual file containing file names separated by spaces or
+line breaks. You can use this switch more then once in the same call to
+@command{gnatpp}. You also can combine this switch with explicit list of
+files.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@code{gnatpp})
+Verbose mode;
+@command{gnatpp} generates version information and then
+a trace of the actions it takes to produce or obtain the ASIS tree.
+
+@item ^-w^/WARNINGS^
+@cindex @option{^-w^/WARNINGS^} (@code{gnatpp})
+Warning mode;
+@command{gnatpp} generates a warning whenever it can not provide
+a required layout in the result source.
+@end table
+
+
+@node Formatting Rules
+@section Formatting Rules
+
+@noindent
+The following subsections show how @command{gnatpp} treats ``white space'',
+comments, program layout, and name casing.
+They provide the detailed descriptions of the switches shown above.
+
+@menu
+* White Space and Empty Lines::
+* Formatting Comments::
+* Construct Layout::
+* Name Casing::
+@end menu
+
+
+@node White Space and Empty Lines
+@subsection White Space and Empty Lines
+
+@noindent
+@command{gnatpp} does not have an option to control space characters.
+It will add or remove spaces according to the style illustrated by the
+examples in the @cite{Ada Reference Manual}.
+
+The only format effectors
+(see @cite{Ada Reference Manual}, paragraph 2.1(13))
+that will appear in the output file are platform-specific line breaks,
+and also format effectors within (but not at the end of) comments.
+In particular, each horizontal tab character that is not inside
+a comment will be treated as a space and thus will appear in the
+output file as zero or more spaces depending on
+the reformatting of the line in which it appears.
+The only exception is a Form Feed character, which is inserted after a
+pragma @code{Page} when @option{-ff} is set.
+
+The output file will contain no lines with trailing ``white space'' (spaces,
+format effectors).
+
+Empty lines in the original source are preserved
+only if they separate declarations or statements.
+In such contexts, a
+sequence of two or more empty lines is replaced by exactly one empty line.
+Note that a blank line will be removed if it separates two ``comment blocks''
+(a comment block is a sequence of whole-line comments).
+In order to preserve a visual separation between comment blocks, use an
+``empty comment'' (a line comprising only hyphens) rather than an empty line.
+Likewise, if for some reason you wish to have a sequence of empty lines,
+use a sequence of empty comments instead.
+
+
+@node Formatting Comments
+@subsection Formatting Comments
+
+@noindent
+Comments in Ada code are of two kinds:
+@itemize @bullet
+@item
+a @emph{whole-line comment}, which appears by itself (possibly preceded by
+``white space'') on a line
+
+@item
+an @emph{end-of-line comment}, which follows some other Ada lexical element
+on the same line.
+@end itemize
+
+@noindent
+The indentation of a whole-line comment is that of either
+the preceding or following line in
+the formatted source, depending on switch settings as will be described below.
+
+For an end-of-line comment, @command{gnatpp} leaves the same number of spaces
+between the end of the preceding Ada lexical element and the beginning
+of the comment as appear in the original source,
+unless either the comment has to be split to
+satisfy the line length limitation, or else the next line contains a
+whole line comment that is considered a continuation of this end-of-line
+comment (because it starts at the same position).
+In the latter two
+cases, the start of the end-of-line comment is moved right to the nearest
+multiple of the indentation level.
+This may result in a ``line overflow'' (the right-shifted comment extending
+beyond the maximum line length), in which case the comment is split as
+described below.
+
+There is a difference between @option{^-c1^/COMMENTS_LAYOUT=DEFAULT^}
+(GNAT-style comment line indentation)
+and @option{^-c2^/COMMENTS_LAYOUT=STANDARD_INDENT^}
+(reference-manual comment line indentation).
+With reference-manual style, a whole-line comment is indented as if it
+were a declaration or statement at the same place
+(i.e., according to the indentation of the preceding line(s)).
+With GNAT style, a whole-line comment that is immediately followed by an
+@b{if} or @b{case} statement alternative, a record variant, or the reserved
+word @b{begin}, is indented based on the construct that follows it.
+
+For example:
+@smallexample @c ada
+@cartouche
+if A then
+ null;
+ -- some comment
+else
+ null;
+end if;
+@end cartouche
+@end smallexample
+
+@noindent
+Reference-manual indentation produces:
+
+@smallexample @c ada
+@cartouche
+if A then
+ null;
+ -- some comment
+else
+ null;
+end if;
+@end cartouche
+@end smallexample
+
+@noindent
+while GNAT-style indentation produces:
+
+@smallexample @c ada
+@cartouche
+if A then
+ null;
+-- some comment
+else
+ null;
+end if;
+@end cartouche
+@end smallexample
+
+@noindent
+The @option{^-c3^/COMMENTS_LAYOUT=GNAT_BEGINNING^} switch
+(GNAT style comment beginning) has the following
+effect:
+
+@itemize @bullet
+@item
+For each whole-line comment that does not end with two hyphens,
+@command{gnatpp} inserts spaces if necessary after the starting two hyphens
+to ensure that there are at least two spaces between these hyphens and the
+first non-blank character of the comment.
+@end itemize
+
+@noindent
+For an end-of-line comment, if in the original source the next line is a
+whole-line comment that starts at the same position
+as the end-of-line comment,
+then the whole-line comment (and all whole-line comments
+that follow it and that start at the same position)
+will start at this position in the output file.
+
+@noindent
+That is, if in the original source we have:
+
+@smallexample @c ada
+@cartouche
+begin
+A := B + C; -- B must be in the range Low1..High1
+ -- C must be in the range Low2..High2
+ --B+C will be in the range Low1+Low2..High1+High2
+X := X + 1;
+@end cartouche
+@end smallexample
+
+@noindent
+Then in the formatted source we get
+
+@smallexample @c ada
+@cartouche
+begin
+ A := B + C; -- B must be in the range Low1..High1
+ -- C must be in the range Low2..High2
+ -- B+C will be in the range Low1+Low2..High1+High2
+ X := X + 1;
+@end cartouche
+@end smallexample
+
+@noindent
+A comment that exceeds the line length limit will be split.
+Unless switch
+@option{^-c4^/COMMENTS_LAYOUT=REFORMAT^} (reformat comment blocks) is set and
+the line belongs to a reformattable block, splitting the line generates a
+@command{gnatpp} warning.
+The @option{^-c4^/COMMENTS_LAYOUT=REFORMAT^} switch specifies that whole-line
+comments may be reformatted in typical
+word processor style (that is, moving words between lines and putting as
+many words in a line as possible).
+
+
+@node Construct Layout
+@subsection Construct Layout
+
+@noindent
+The difference between GNAT style @option{^-l1^/CONSTRUCT_LAYOUT=GNAT^}
+and compact @option{^-l2^/CONSTRUCT_LAYOUT=COMPACT^}
+layout on the one hand, and uncompact layout
+@option{^-l3^/CONSTRUCT_LAYOUT=UNCOMPACT^} on the other hand,
+can be illustrated by the following examples:
+
+@iftex
+@cartouche
+@multitable @columnfractions .5 .5
+@item @i{GNAT style, compact layout} @tab @i{Uncompact layout}
+
+@item
+@smallexample @c ada
+type q is record
+ a : integer;
+ b : integer;
+end record;
+@end smallexample
+@tab
+@smallexample @c ada
+type q is
+ record
+ a : integer;
+ b : integer;
+ end record;
+@end smallexample
+
+@item
+@smallexample @c ada
+Block : declare
+ A : Integer := 3;
+begin
+ Proc (A, A);
+end Block;
+@end smallexample
+@tab
+@smallexample @c ada
+Block :
+ declare
+ A : Integer := 3;
+ begin
+ Proc (A, A);
+ end Block;
+@end smallexample
+
+@item
+@smallexample @c ada
+Clear : for J in 1 .. 10 loop
+ A (J) := 0;
+end loop Clear;
+@end smallexample
+@tab
+@smallexample @c ada
+Clear :
+ for J in 1 .. 10 loop
+ A (J) := 0;
+ end loop Clear;
+@end smallexample
+@end multitable
+@end cartouche
+@end iftex
+
+@ifnottex
+@smallexample
+@cartouche
+GNAT style, compact layout Uncompact layout
+
+type q is record type q is
+ a : integer; record
+ b : integer; a : integer;
+end record; b : integer;
+ end record;
+
+
+Block : declare Block :
+ A : Integer := 3; declare
+begin A : Integer := 3;
+ Proc (A, A); begin
+end Block; Proc (A, A);
+ end Block;
+
+Clear : for J in 1 .. 10 loop Clear :
+ A (J) := 0; for J in 1 .. 10 loop
+end loop Clear; A (J) := 0;
+ end loop Clear;
+@end cartouche
+@end smallexample
+@end ifnottex
+
+@noindent
+A further difference between GNAT style layout and compact layout is that
+GNAT style layout inserts empty lines as separation for
+compound statements, return statements and bodies.
+
+
+@node Name Casing
+@subsection Name Casing
+
+@noindent
+@command{gnatpp} always converts the usage occurrence of a (simple) name to
+the same casing as the corresponding defining identifier.
+
+You control the casing for defining occurrences via the
+@option{^-n^/NAME_CASING^} switch.
+@ifclear vms
+With @option{-nD} (``as declared'', which is the default),
+@end ifclear
+@ifset vms
+With @option{/NAME_CASING=AS_DECLARED}, which is the default,
+@end ifset
+defining occurrences appear exactly as in the source file
+where they are declared.
+The other ^values for this switch^options for this qualifier^ ---
+@option{^-nU^UPPER_CASE^},
+@option{^-nL^LOWER_CASE^},
+@option{^-nM^MIXED_CASE^} ---
+result in
+^upper, lower, or mixed case, respectively^the corresponding casing^.
+If @command{gnatpp} changes the casing of a defining
+occurrence, it analogously changes the casing of all the
+usage occurrences of this name.
+
+If the defining occurrence of a name is not in the source compilation unit
+currently being processed by @command{gnatpp}, the casing of each reference to
+this name is changed according to the value of the @option{^-n^/NAME_CASING^}
+switch (subject to the dictionary file mechanism described below).
+Thus @command{gnatpp} acts as though the @option{^-n^/NAME_CASING^} switch
+had affected the
+casing for the defining occurrence of the name.
+
+Some names may need to be spelled with casing conventions that are not
+covered by the upper-, lower-, and mixed-case transformations.
+You can arrange correct casing by placing such names in a
+@emph{dictionary file},
+and then supplying a @option{^-D^/DICTIONARY^} switch.
+The casing of names from dictionary files overrides
+any @option{^-n^/NAME_CASING^} switch.
+
+To handle the casing of Ada predefined names and the names from GNAT libraries,
+@command{gnatpp} assumes a default dictionary file.
+The name of each predefined entity is spelled with the same casing as is used
+for the entity in the @cite{Ada Reference Manual}.
+The name of each entity in the GNAT libraries is spelled with the same casing
+as is used in the declaration of that entity.
+
+The @w{@option{^-D-^/SPECIFIC_CASING^}} switch suppresses the use of the
+default dictionary file.
+Instead, the casing for predefined and GNAT-defined names will be established
+by the @option{^-n^/NAME_CASING^} switch or explicit dictionary files.
+For example, by default the names @code{Ada.Text_IO} and @code{GNAT.OS_Lib}
+will appear as just shown,
+even in the presence of a @option{^-nU^/NAME_CASING=UPPER_CASE^} switch.
+To ensure that even such names are rendered in uppercase,
+additionally supply the @w{@option{^-D-^/SPECIFIC_CASING^}} switch
+(or else, less conveniently, place these names in upper case in a dictionary
+file).
+
+A dictionary file is
+a plain text file; each line in this file can be either a blank line
+(containing only space characters and ASCII.HT characters), an Ada comment
+line, or the specification of exactly one @emph{casing schema}.
+
+A casing schema is a string that has the following syntax:
+
+@smallexample
+@cartouche
+ @var{casing_schema} ::= @var{identifier} | [*]@var{simple_identifier}[*]
+
+ @var{simple_identifier} ::= @var{letter}@{@var{letter_or_digit}@}
+@end cartouche
+@end smallexample
+
+@noindent
+(The @code{[]} metanotation stands for an optional part;
+see @cite{Ada Reference Manual}, Section 2.3) for the definition of the
+@var{identifier} lexical element and the @var{letter_or_digit} category).
+
+The casing schema string can be followed by white space and/or an Ada-style
+comment; any amount of white space is allowed before the string.
+
+If a dictionary file is passed as
+@ifclear vms
+the value of a @option{-D@var{file}} switch
+@end ifclear
+@ifset vms
+an option to the @option{/DICTIONARY} qualifier
+@end ifset
+then for every
+simple name and every identifier, @command{gnatpp} checks if the dictionary
+defines the casing for the name or for some of its parts (the term ``subword''
+is used below to denote the part of a name which is delimited by ``_'' or by
+the beginning or end of the word and which does not contain any ``_'' inside):
+
+@itemize @bullet
+@item
+if the whole name is in the dictionary, @command{gnatpp} uses for this name
+the casing defined by the dictionary; no subwords are checked for this word
+
+@item
+for the first subword (that is, for the subword preceding the leftmost
+``_''), @command{gnatpp} checks if the dictionary contains the corresponding
+string of the form @code{@var{simple_identifier}*}, and if it does, the
+casing of this @var{simple_identifier} is used for this subword
+
+@item
+for the last subword (following the rightmost ``_'') @command{gnatpp}
+checks if the dictionary contains the corresponding string of the form
+@code{*@var{simple_identifier}}, and if it does, the casing of this
+@var{simple_identifier} is used for this subword
+
+@item
+for every intermediate subword (surrounded by two'_') @command{gnatpp} checks
+if the dictionary contains the corresponding string of the form
+@code{*@var{simple_identifier}*}, and if it does, the casing of this
+simple_identifier is used for this subword
+
+@item
+if more than one dictionary file is passed as @command{gnatpp} switches, each
+dictionary adds new casing exceptions and overrides all the existing casing
+exceptions set by the previous dictionaries
+
+@item
+when @command{gnatpp} checks if the word or subword is in the dictionary,
+this check is not case sensitive
+@end itemize
+
+@noindent
+For example, suppose we have the following source to reformat:
+
+@smallexample @c ada
+@cartouche
+procedure test is
+ name1 : integer := 1;
+ name4_name3_name2 : integer := 2;
+ name2_name3_name4 : Boolean;
+ name1_var : Float;
+begin
+ name2_name3_name4 := name4_name3_name2 > name1;
+end;
+@end cartouche
+@end smallexample
+
+@noindent
+And suppose we have two dictionaries:
+
+@smallexample
+@cartouche
+@i{dict1:}
+ NAME1
+ *NaMe3*
+ *NAME2
+@end cartouche
+
+@cartouche
+@i{dict2:}
+ *NAME3*
+@end cartouche
+@end smallexample
+
+@noindent
+If @command{gnatpp} is called with the following switches:
+
+@smallexample
+@ifclear vms
+@command{gnatpp -nM -D dict1 -D dict2 test.adb}
+@end ifclear
+@ifset vms
+@command{gnatpp test.adb /NAME_CASING=MIXED_CASE /DICTIONARY=(dict1, dict2)}
+@end ifset
+@end smallexample
+
+@noindent
+then we will get the following name casing in the @command{gnatpp} output:
+
+@smallexample @c ada
+@cartouche
+procedure Test is
+ NAME1 : Integer := 1;
+ Name4_NAME3_NAME2 : integer := 2;
+ Name2_NAME3_Name4 : Boolean;
+ Name1_Var : Float;
+begin
+ Name2_NAME3_Name4 := Name4_NAME3_NAME2 > NAME1;
+end Test;
+@end cartouche
+@end smallexample
+
+
+
+@c ***********************************
+@node File Name Krunching Using gnatkr
+@chapter File Name Krunching Using @code{gnatkr}
+@findex gnatkr
+
+@noindent
+This chapter discusses the method used by the compiler to shorten
+the default file names chosen for Ada units so that they do not
+exceed the maximum length permitted. It also describes the
+@code{gnatkr} utility that can be used to determine the result of
+applying this shortening.
+@menu
+* About gnatkr::
+* Using gnatkr::
+* Krunching Method::
+* Examples of gnatkr Usage::
+@end menu
+
+@node About gnatkr
+@section About @code{gnatkr}
+
+@noindent
+The default file naming rule in GNAT
+is that the file name must be derived from
+the unit name. The exact default rule is as follows:
+@itemize @bullet
+@item
+Take the unit name and replace all dots by hyphens.
+@item
+If such a replacement occurs in the
+second character position of a name, and the first character is
+^a, g, s, or i^A, G, S, or I^ then replace the dot by the character
+^~ (tilde)^$ (dollar sign)^
+instead of a minus.
+@end itemize
+The reason for this exception is to avoid clashes
+with the standard names for children of System, Ada, Interfaces,
+and GNAT, which use the prefixes ^s- a- i- and g-^S- A- I- and G-^
+respectively.
+
+The @option{^-gnatk^/FILE_NAME_MAX_LENGTH=^@var{nn}}
+switch of the compiler activates a ``krunching''
+circuit that limits file names to nn characters (where nn is a decimal
+integer). For example, using OpenVMS,
+where the maximum file name length is
+39, the value of nn is usually set to 39, but if you want to generate
+a set of files that would be usable if ported to a system with some
+different maximum file length, then a different value can be specified.
+The default value of 39 for OpenVMS need not be specified.
+
+The @code{gnatkr} utility can be used to determine the krunched name for
+a given file, when krunched to a specified maximum length.
+
+@node Using gnatkr
+@section Using @code{gnatkr}
+
+@noindent
+The @code{gnatkr} command has the form
+
+@ifclear vms
+@smallexample
+$ gnatkr @var{name} [@var{length}]
+@end smallexample
+@end ifclear
+
+@ifset vms
+@smallexample
+$ gnatkr @var{name} /COUNT=nn
+@end smallexample
+@end ifset
+
+@noindent
+@var{name} is the uncrunched file name, derived from the name of the unit
+in the standard manner described in the previous section (i.e. in particular
+all dots are replaced by hyphens). The file name may or may not have an
+extension (defined as a suffix of the form period followed by arbitrary
+characters other than period). If an extension is present then it will
+be preserved in the output. For example, when krunching @file{hellofile.ads}
+to eight characters, the result will be hellofil.ads.
+
+Note: for compatibility with previous versions of @code{gnatkr} dots may
+appear in the name instead of hyphens, but the last dot will always be
+taken as the start of an extension. So if @code{gnatkr} is given an argument
+such as @file{Hello.World.adb} it will be treated exactly as if the first
+period had been a hyphen, and for example krunching to eight characters
+gives the result @file{hellworl.adb}.
+
+Note that the result is always all lower case (except on OpenVMS where it is
+all upper case). Characters of the other case are folded as required.
+
+@var{length} represents the length of the krunched name. The default
+when no argument is given is ^8^39^ characters. A length of zero stands for
+unlimited, in other words do not chop except for system files where the
+impled crunching length is always eight characters.
+
+@noindent
+The output is the krunched name. The output has an extension only if the
+original argument was a file name with an extension.
+
+@node Krunching Method
+@section Krunching Method
+
+@noindent
+The initial file name is determined by the name of the unit that the file
+contains. The name is formed by taking the full expanded name of the
+unit and replacing the separating dots with hyphens and
+using ^lowercase^uppercase^
+for all letters, except that a hyphen in the second character position is
+replaced by a ^tilde^dollar sign^ if the first character is
+^a, i, g, or s^A, I, G, or S^.
+The extension is @code{.ads} for a
+specification and @code{.adb} for a body.
+Krunching does not affect the extension, but the file name is shortened to
+the specified length by following these rules:
+
+@itemize @bullet
+@item
+The name is divided into segments separated by hyphens, tildes or
+underscores and all hyphens, tildes, and underscores are
+eliminated. If this leaves the name short enough, we are done.
+
+@item
+If the name is too long, the longest segment is located (left-most
+if there are two of equal length), and shortened by dropping
+its last character. This is repeated until the name is short enough.
+
+As an example, consider the krunching of @*@file{our-strings-wide_fixed.adb}
+to fit the name into 8 characters as required by some operating systems.
+
+@smallexample
+our-strings-wide_fixed 22
+our strings wide fixed 19
+our string wide fixed 18
+our strin wide fixed 17
+our stri wide fixed 16
+our stri wide fixe 15
+our str wide fixe 14
+our str wid fixe 13
+our str wid fix 12
+ou str wid fix 11
+ou st wid fix 10
+ou st wi fix 9
+ou st wi fi 8
+Final file name: oustwifi.adb
+@end smallexample
+
+@item
+The file names for all predefined units are always krunched to eight
+characters. The krunching of these predefined units uses the following
+special prefix replacements:
+
+@table @file
+@item ada-
+replaced by @file{^a^A^-}
+
+@item gnat-
+replaced by @file{^g^G^-}
+
+@item interfaces-
+replaced by @file{^i^I^-}
+
+@item system-
+replaced by @file{^s^S^-}
+@end table
+
+These system files have a hyphen in the second character position. That
+is why normal user files replace such a character with a
+^tilde^dollar sign^, to
+avoid confusion with system file names.
+
+As an example of this special rule, consider
+@*@file{ada-strings-wide_fixed.adb}, which gets krunched as follows:
+
+@smallexample
+ada-strings-wide_fixed 22
+a- strings wide fixed 18
+a- string wide fixed 17
+a- strin wide fixed 16
+a- stri wide fixed 15
+a- stri wide fixe 14
+a- str wide fixe 13
+a- str wid fixe 12
+a- str wid fix 11
+a- st wid fix 10
+a- st wi fix 9
+a- st wi fi 8
+Final file name: a-stwifi.adb
+@end smallexample
+@end itemize
+
+Of course no file shortening algorithm can guarantee uniqueness over all
+possible unit names, and if file name krunching is used then it is your
+responsibility to ensure that no name clashes occur. The utility
+program @code{gnatkr} is supplied for conveniently determining the
+krunched name of a file.
+
+@node Examples of gnatkr Usage
+@section Examples of @code{gnatkr} Usage
+
+@smallexample
+@iftex
+@leftskip=0cm
+@end iftex
+@ifclear vms
+$ gnatkr very_long_unit_name.ads --> velounna.ads
+$ gnatkr grandparent-parent-child.ads --> grparchi.ads
+$ gnatkr Grandparent.Parent.Child.ads --> grparchi.ads
+$ gnatkr grandparent-parent-child --> grparchi
+@end ifclear
+$ gnatkr very_long_unit_name.ads/count=6 --> vlunna.ads
+$ gnatkr very_long_unit_name.ads/count=0 --> very_long_unit_name.ads
+@end smallexample
+
+@node Preprocessing Using gnatprep
+@chapter Preprocessing Using @code{gnatprep}
+@findex gnatprep
+
+@noindent
+The @code{gnatprep} utility provides
+a simple preprocessing capability for Ada programs.
+It is designed for use with GNAT, but is not dependent on any special
+features of GNAT.
+
+@menu
+* Using gnatprep::
+* Switches for gnatprep::
+* Form of Definitions File::
+* Form of Input Text for gnatprep::
+@end menu
+
+@node Using gnatprep
+@section Using @code{gnatprep}
+
+@noindent
+To call @code{gnatprep} use
+
+@smallexample
+$ gnatprep [-bcrsu] [-Dsymbol=value] infile outfile [deffile]
+@end smallexample
+
+@noindent
+where
+@table @code
+@item infile
+is the full name of the input file, which is an Ada source
+file containing preprocessor directives.
+
+@item outfile
+is the full name of the output file, which is an Ada source
+in standard Ada form. When used with GNAT, this file name will
+normally have an ads or adb suffix.
+
+@item deffile
+is the full name of a text file containing definitions of
+symbols to be referenced by the preprocessor. This argument is
+optional, and can be replaced by the use of the @option{-D} switch.
+
+@item switches
+is an optional sequence of switches as described in the next section.
+@end table
+
+@node Switches for gnatprep
+@section Switches for @code{gnatprep}
+
+@table @option
+@c !sort!
+
+@item ^-b^/BLANK_LINES^
+@cindex @option{^-b^/BLANK_LINES^} (@command{gnatprep})
+Causes both preprocessor lines and the lines deleted by
+preprocessing to be replaced by blank lines in the output source file,
+preserving line numbers in the output file.
+
+@item ^-c^/COMMENTS^
+@cindex @option{^-c^/COMMENTS^} (@command{gnatprep})
+Causes both preprocessor lines and the lines deleted
+by preprocessing to be retained in the output source as comments marked
+with the special string @code{"--! "}. This option will result in line numbers
+being preserved in the output file.
+
+@item ^-Dsymbol=value^/ASSOCIATE="symbol=value"^
+@cindex @option{^-D^/ASSOCIATE^} (@command{gnatprep})
+Defines a new symbol, associated with value. If no value is given on the
+command line, then symbol is considered to be @code{True}. This switch
+can be used in place of a definition file.
+
+@ifset vms
+@item /REMOVE
+@cindex @option{/REMOVE} (@command{gnatprep})
+This is the default setting which causes lines deleted by preprocessing
+to be entirely removed from the output file.
+@end ifset
+
+@item ^-r^/REFERENCE^
+@cindex @option{^-r^/REFERENCE^} (@command{gnatprep})
+Causes a @code{Source_Reference} pragma to be generated that
+references the original input file, so that error messages will use
+the file name of this original file. The use of this switch implies
+that preprocessor lines are not to be removed from the file, so its
+use will force @option{^-b^/BLANK_LINES^} mode if
+@option{^-c^/COMMENTS^}
+has not been specified explicitly.
+
+Note that if the file to be preprocessed contains multiple units, then
+it will be necessary to @code{gnatchop} the output file from
+@code{gnatprep}. If a @code{Source_Reference} pragma is present
+in the preprocessed file, it will be respected by
+@code{gnatchop ^-r^/REFERENCE^}
+so that the final chopped files will correctly refer to the original
+input source file for @code{gnatprep}.
+
+@item ^-s^/SYMBOLS^
+@cindex @option{^-s^/SYMBOLS^} (@command{gnatprep})
+Causes a sorted list of symbol names and values to be
+listed on the standard output file.
+
+@item ^-u^/UNDEFINED^
+@cindex @option{^-u^/UNDEFINED^} (@command{gnatprep})
+Causes undefined symbols to be treated as having the value FALSE in the context
+of a preprocessor test. In the absence of this option, an undefined symbol in
+a @code{#if} or @code{#elsif} test will be treated as an error.
+
+@end table
+
+@ifclear vms
+@noindent
+Note: if neither @option{-b} nor @option{-c} is present,
+then preprocessor lines and
+deleted lines are completely removed from the output, unless -r is
+specified, in which case -b is assumed.
+@end ifclear
+
+@node Form of Definitions File
+@section Form of Definitions File
+
+@noindent
+The definitions file contains lines of the form
+
+@smallexample
+symbol := value
+@end smallexample
+
+@noindent
+where symbol is an identifier, following normal Ada (case-insensitive)
+rules for its syntax, and value is one of the following:
+
+@itemize @bullet
+@item
+Empty, corresponding to a null substitution
+@item
+A string literal using normal Ada syntax
+@item
+Any sequence of characters from the set
+(letters, digits, period, underline).
+@end itemize
+
+@noindent
+Comment lines may also appear in the definitions file, starting with
+the usual @code{--},
+and comments may be added to the definitions lines.
+
+@node Form of Input Text for gnatprep
+@section Form of Input Text for @code{gnatprep}
+
+@noindent
+The input text may contain preprocessor conditional inclusion lines,
+as well as general symbol substitution sequences.
+
+The preprocessor conditional inclusion commands have the form
+
+@smallexample
+@group
+@cartouche
+#if @i{expression} [then]
+ lines
+#elsif @i{expression} [then]
+ lines
+#elsif @i{expression} [then]
+ lines
+...
+#else
+ lines
+#end if;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+In this example, @i{expression} is defined by the following grammar:
+@smallexample
+@i{expression} ::= <symbol>
+@i{expression} ::= <symbol> = "<value>"
+@i{expression} ::= <symbol> = <symbol>
+@i{expression} ::= <symbol> 'Defined
+@i{expression} ::= not @i{expression}
+@i{expression} ::= @i{expression} and @i{expression}
+@i{expression} ::= @i{expression} or @i{expression}
+@i{expression} ::= @i{expression} and then @i{expression}
+@i{expression} ::= @i{expression} or else @i{expression}
+@i{expression} ::= ( @i{expression} )
+@end smallexample
+
+@noindent
+For the first test (@i{expression} ::= <symbol>) the symbol must have
+either the value true or false, that is to say the right-hand of the
+symbol definition must be one of the (case-insensitive) literals
+@code{True} or @code{False}. If the value is true, then the
+corresponding lines are included, and if the value is false, they are
+excluded.
+
+The test (@i{expression} ::= <symbol> @code{'Defined}) is true only if
+the symbol has been defined in the definition file or by a @option{-D}
+switch on the command line. Otherwise, the test is false.
+
+The equality tests are case insensitive, as are all the preprocessor lines.
+
+If the symbol referenced is not defined in the symbol definitions file,
+then the effect depends on whether or not switch @option{-u}
+is specified. If so, then the symbol is treated as if it had the value
+false and the test fails. If this switch is not specified, then
+it is an error to reference an undefined symbol. It is also an error to
+reference a symbol that is defined with a value other than @code{True}
+or @code{False}.
+
+The use of the @code{not} operator inverts the sense of this logical test, so
+that the lines are included only if the symbol is not defined.
+The @code{then} keyword is optional as shown
+
+The @code{#} must be the first non-blank character on a line, but
+otherwise the format is free form. Spaces or tabs may appear between
+the @code{#} and the keyword. The keywords and the symbols are case
+insensitive as in normal Ada code. Comments may be used on a
+preprocessor line, but other than that, no other tokens may appear on a
+preprocessor line. Any number of @code{elsif} clauses can be present,
+including none at all. The @code{else} is optional, as in Ada.
+
+The @code{#} marking the start of a preprocessor line must be the first
+non-blank character on the line, i.e. it must be preceded only by
+spaces or horizontal tabs.
+
+Symbol substitution outside of preprocessor lines is obtained by using
+the sequence
+
+@smallexample
+$symbol
+@end smallexample
+
+@noindent
+anywhere within a source line, except in a comment or within a
+string literal. The identifier
+following the @code{$} must match one of the symbols defined in the symbol
+definition file, and the result is to substitute the value of the
+symbol in place of @code{$symbol} in the output file.
+
+Note that although the substitution of strings within a string literal
+is not possible, it is possible to have a symbol whose defined value is
+a string literal. So instead of setting XYZ to @code{hello} and writing:
+
+@smallexample
+Header : String := "$XYZ";
+@end smallexample
+
+@noindent
+you should set XYZ to @code{"hello"} and write:
+
+@smallexample
+Header : String := $XYZ;
+@end smallexample
+
+@noindent
+and then the substitution will occur as desired.
+
+@ifset vms
+@node The GNAT Run-Time Library Builder gnatlbr
+@chapter The GNAT Run-Time Library Builder @code{gnatlbr}
+@findex gnatlbr
+@cindex Library builder
+
+@noindent
+@code{gnatlbr} is a tool for rebuilding the GNAT run time with user
+supplied configuration pragmas.
+
+@menu
+* Running gnatlbr::
+* Switches for gnatlbr::
+* Examples of gnatlbr Usage::
+@end menu
+
+@node Running gnatlbr
+@section Running @code{gnatlbr}
+
+@noindent
+The @code{gnatlbr} command has the form
+
+@smallexample
+$ GNAT LIBRARY /[CREATE | SET | DELETE]=directory [/CONFIG=file]
+@end smallexample
+
+@node Switches for gnatlbr
+@section Switches for @code{gnatlbr}
+
+@noindent
+@code{gnatlbr} recognizes the following switches:
+
+@table @option
+@c !sort!
+@item /CREATE=directory
+@cindex @code{/CREATE} (@code{gnatlbr})
+ Create the new run-time library in the specified directory.
+
+@item /SET=directory
+@cindex @code{/SET} (@code{gnatlbr})
+ Make the library in the specified directory the current run-time
+ library.
+
+@item /DELETE=directory
+@cindex @code{/DELETE} (@code{gnatlbr})
+ Delete the run-time library in the specified directory.
+
+@item /CONFIG=file
+@cindex @code{/CONFIG} (@code{gnatlbr})
+ With /CREATE:
+ Use the configuration pragmas in the specified file when building
+ the library.
+
+ With /SET:
+ Use the configuration pragmas in the specified file when compiling.
+
+@end table
+
+@node Examples of gnatlbr Usage
+@section Example of @code{gnatlbr} Usage
+
+@smallexample
+Contents of VAXFLOAT.ADC:
+pragma Float_Representation (VAX_Float);
+
+$ GNAT LIBRARY /CREATE=[.VAXFLOAT] /CONFIG=VAXFLOAT.ADC
+
+GNAT LIBRARY rebuilds the run-time library in directory [.VAXFLOAT]
+
+@end smallexample
+@end ifset
+
+@node The GNAT Library Browser gnatls
+@chapter The GNAT Library Browser @code{gnatls}
+@findex gnatls
+@cindex Library browser
+
+@noindent
+@code{gnatls} is a tool that outputs information about compiled
+units. It gives the relationship between objects, unit names and source
+files. It can also be used to check the source dependencies of a unit
+as well as various characteristics.
+
+@menu
+* Running gnatls::
+* Switches for gnatls::
+* Examples of gnatls Usage::
+@end menu
+
+@node Running gnatls
+@section Running @code{gnatls}
+
+@noindent
+The @code{gnatls} command has the form
+
+@smallexample
+$ gnatls switches @var{object_or_ali_file}
+@end smallexample
+
+@noindent
+The main argument is the list of object or @file{ali} files
+(@pxref{The Ada Library Information Files})
+for which information is requested.
+
+In normal mode, without additional option, @code{gnatls} produces a
+four-column listing. Each line represents information for a specific
+object. The first column gives the full path of the object, the second
+column gives the name of the principal unit in this object, the third
+column gives the status of the source and the fourth column gives the
+full path of the source representing this unit.
+Here is a simple example of use:
+
+@smallexample
+$ gnatls *.o
+^./^[]^demo1.o demo1 DIF demo1.adb
+^./^[]^demo2.o demo2 OK demo2.adb
+^./^[]^hello.o h1 OK hello.adb
+^./^[]^instr-child.o instr.child MOK instr-child.adb
+^./^[]^instr.o instr OK instr.adb
+^./^[]^tef.o tef DIF tef.adb
+^./^[]^text_io_example.o text_io_example OK text_io_example.adb
+^./^[]^tgef.o tgef DIF tgef.adb
+@end smallexample
+
+@noindent
+The first line can be interpreted as follows: the main unit which is
+contained in
+object file @file{demo1.o} is demo1, whose main source is in
+@file{demo1.adb}. Furthermore, the version of the source used for the
+compilation of demo1 has been modified (DIF). Each source file has a status
+qualifier which can be:
+
+@table @code
+@item OK (unchanged)
+The version of the source file used for the compilation of the
+specified unit corresponds exactly to the actual source file.
+
+@item MOK (slightly modified)
+The version of the source file used for the compilation of the
+specified unit differs from the actual source file but not enough to
+require recompilation. If you use gnatmake with the qualifier
+@option{^-m (minimal recompilation)^/MINIMAL_RECOMPILATION^}, a file marked
+MOK will not be recompiled.
+
+@item DIF (modified)
+No version of the source found on the path corresponds to the source
+used to build this object.
+
+@item ??? (file not found)
+No source file was found for this unit.
+
+@item HID (hidden, unchanged version not first on PATH)
+The version of the source that corresponds exactly to the source used
+for compilation has been found on the path but it is hidden by another
+version of the same source that has been modified.
+
+@end table
+
+@node Switches for gnatls
+@section Switches for @code{gnatls}
+
+@noindent
+@code{gnatls} recognizes the following switches:
+
+@table @option
+@c !sort!
+@item ^-a^/ALL_UNITS^
+@cindex @option{^-a^/ALL_UNITS^} (@code{gnatls})
+Consider all units, including those of the predefined Ada library.
+Especially useful with @option{^-d^/DEPENDENCIES^}.
+
+@item ^-d^/DEPENDENCIES^
+@cindex @option{^-d^/DEPENDENCIES^} (@code{gnatls})
+List sources from which specified units depend on.
+
+@item ^-h^/OUTPUT=OPTIONS^
+@cindex @option{^-h^/OUTPUT=OPTIONS^} (@code{gnatls})
+Output the list of options.
+
+@item ^-o^/OUTPUT=OBJECTS^
+@cindex @option{^-o^/OUTPUT=OBJECTS^} (@code{gnatls})
+Only output information about object files.
+
+@item ^-s^/OUTPUT=SOURCES^
+@cindex @option{^-s^/OUTPUT=SOURCES^} (@code{gnatls})
+Only output information about source files.
+
+@item ^-u^/OUTPUT=UNITS^
+@cindex @option{^-u^/OUTPUT=UNITS^} (@code{gnatls})
+Only output information about compilation units.
+
+@item ^-files^/FILES^=@var{file}
+@cindex @option{^-files^/FILES^} (@code{gnatls})
+Take as arguments the files listed in text file @var{file}.
+Text file @var{file} may contain empty lines that are ignored.
+Each non empty line should contain the name of an existing file.
+Several such switches may be specified simultaneously.
+
+@item ^-aO^/OBJECT_SEARCH=^@var{dir}
+@itemx ^-aI^/SOURCE_SEARCH=^@var{dir}
+@itemx ^-I^/SEARCH=^@var{dir}
+@itemx ^-I-^/NOCURRENT_DIRECTORY^
+@itemx -nostdinc
+@cindex @option{^-aO^/OBJECT_SEARCH^} (@code{gnatls})
+@cindex @option{^-aI^/SOURCE_SEARCH^} (@code{gnatls})
+@cindex @option{^-I^/SEARCH^} (@code{gnatls})
+@cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatls})
+Source path manipulation. Same meaning as the equivalent @code{gnatmake} flags
+(see @ref{Switches for gnatmake}).
+
+@item --RTS=@var{rts-path}
+@cindex @option{--RTS} (@code{gnatls})
+Specifies the default location of the runtime library. Same meaning as the
+equivalent @code{gnatmake} flag (see @ref{Switches for gnatmake}).
+
+@item ^-v^/OUTPUT=VERBOSE^
+@cindex @option{^-v^/OUTPUT=VERBOSE^} (@code{gnatls})
+Verbose mode. Output the complete source and object paths. Do not use
+the default column layout but instead use long format giving as much as
+information possible on each requested units, including special
+characteristics such as:
+
+@table @code
+@item Preelaborable
+The unit is preelaborable in the Ada 95 sense.
+
+@item No_Elab_Code
+No elaboration code has been produced by the compiler for this unit.
+
+@item Pure
+The unit is pure in the Ada 95 sense.
+
+@item Elaborate_Body
+The unit contains a pragma Elaborate_Body.
+
+@item Remote_Types
+The unit contains a pragma Remote_Types.
+
+@item Shared_Passive
+The unit contains a pragma Shared_Passive.
+
+@item Predefined
+This unit is part of the predefined environment and cannot be modified
+by the user.
+
+@item Remote_Call_Interface
+The unit contains a pragma Remote_Call_Interface.
+
+@end table
+
+@end table
+
+@node Examples of gnatls Usage
+@section Example of @code{gnatls} Usage
+@ifclear vms
+
+@noindent
+Example of using the verbose switch. Note how the source and
+object paths are affected by the -I switch.
+
+@smallexample
+$ gnatls -v -I.. demo1.o
+
+GNATLS 3.10w (970212) Copyright 1999 Free Software Foundation, Inc.
+
+Source Search Path:
+ <Current_Directory>
+ ../
+ /home/comar/local/adainclude/
+
+Object Search Path:
+ <Current_Directory>
+ ../
+ /home/comar/local/lib/gcc-lib/mips-sni-sysv4/2.7.2/adalib/
+
+./demo1.o
+ Unit =>
+ Name => demo1
+ Kind => subprogram body
+ Flags => No_Elab_Code
+ Source => demo1.adb modified
+@end smallexample
+
+@noindent
+The following is an example of use of the dependency list.
+Note the use of the -s switch
+which gives a straight list of source files. This can be useful for
+building specialized scripts.
+
+@smallexample
+$ gnatls -d demo2.o
+./demo2.o demo2 OK demo2.adb
+ OK gen_list.ads
+ OK gen_list.adb
+ OK instr.ads
+ OK instr-child.ads
+
+$ gnatls -d -s -a demo1.o
+demo1.adb
+/home/comar/local/adainclude/ada.ads
+/home/comar/local/adainclude/a-finali.ads
+/home/comar/local/adainclude/a-filico.ads
+/home/comar/local/adainclude/a-stream.ads
+/home/comar/local/adainclude/a-tags.ads
+gen_list.ads
+gen_list.adb
+/home/comar/local/adainclude/gnat.ads
+/home/comar/local/adainclude/g-io.ads
+instr.ads
+/home/comar/local/adainclude/system.ads
+/home/comar/local/adainclude/s-exctab.ads
+/home/comar/local/adainclude/s-finimp.ads
+/home/comar/local/adainclude/s-finroo.ads
+/home/comar/local/adainclude/s-secsta.ads
+/home/comar/local/adainclude/s-stalib.ads
+/home/comar/local/adainclude/s-stoele.ads
+/home/comar/local/adainclude/s-stratt.ads
+/home/comar/local/adainclude/s-tasoli.ads
+/home/comar/local/adainclude/s-unstyp.ads
+/home/comar/local/adainclude/unchconv.ads
+@end smallexample
+@end ifclear
+
+@ifset vms
+@smallexample
+GNAT LIST /DEPENDENCIES /OUTPUT=SOURCES /ALL_UNITS DEMO1.ADB
+
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]ada.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-finali.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-filico.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-stream.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-tags.ads
+demo1.adb
+gen_list.ads
+gen_list.adb
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]gnat.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]g-io.ads
+instr.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]system.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-exctab.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-finimp.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-finroo.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-secsta.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-stalib.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-stoele.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-stratt.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-tasoli.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-unstyp.ads
+GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]unchconv.ads
+@end smallexample
+@end ifset
+
+@node Cleaning Up Using gnatclean
+@chapter Cleaning Up Using @code{gnatclean}
+@findex gnatclean
+@cindex Cleaning tool
+
+@noindent
+@code{gnatclean} is a tool that allows the deletion of files produced by the
+compiler, binder and linker, including ALI files, object files, tree files,
+expanded source files, library files, interface copy source files, binder
+generated files and executable files.
+
+@menu
+* Running gnatclean::
+* Switches for gnatclean::
+* Examples of gnatclean Usage::
+@end menu
+
+@node Running gnatclean
+@section Running @code{gnatclean}
+
+@noindent
+The @code{gnatclean} command has the form:
+
+@smallexample
+$ gnatclean switches @var{names}
+@end smallexample
+
+@noindent
+@var{names} is a list of source file names. Suffixes @code{.^ads^ADS^} and
+@code{^adb^ADB^} may be omitted. If a project file is specified using switch
+@code{^-P^/PROJECT_FILE=^}, then @var{names} may be completely omitted.
+
+@noindent
+In normal mode, @code{gnatclean} delete the files produced by the compiler and,
+if switch @code{^-c^/COMPILER_FILES_ONLY^} is not specified, by the binder and
+the linker. In informative-only mode, specified by switch
+@code{^-n^/NODELETE^}, the list of files that would have been deleted in
+normal mode is listed, but no file is actually deleted.
+
+@node Switches for gnatclean
+@section Switches for @code{gnatclean}
+
+@noindent
+@code{gnatclean} recognizes the following switches:
+
+@table @option
+@c !sort!
+@item ^-c^/COMPILER_FILES_ONLY^
+@cindex @option{^-c^/COMPILER_FILES_ONLY^} (@code{gnatclean})
+Only attempt to delete the files produced by the compiler, not those produced
+by the binder or the linker. The files that are not to be deleted are library
+files, interface copy files, binder generated files and executable files.
+
+@item ^-D ^/DIRECTORY_OBJECTS=^@var{dir}
+@cindex @option{^-D^/DIRECTORY_OBJECTS^} (@code{gnatclean})
+Indicate that ALI and object files should normally be found in directory
+@var{dir}.
+
+@item ^-F^/FULL_PATH_IN_BRIEF_MESSAGES^
+@cindex @option{^-F^/FULL_PATH_IN_BRIEF_MESSAGES^} (@code{gnatclean})
+When using project files, if some errors or warnings are detected during
+parsing and verbose mode is not in effect (no use of switch
+^-v^/VERBOSE^), then error lines start with the full path name of the project
+file, rather than its simple file name.
+
+@item ^-h^/HELP^
+@cindex @option{^-h^/HELP^} (@code{gnatclean})
+Output a message explaining the usage of @code{^gnatclean^gnatclean^}.
+
+@item ^-n^/NODELETE^
+@cindex @option{^-n^/NODELETE^} (@code{gnatclean})
+Informative-only mode. Do not delete any files. Output the list of the files
+that would have been deleted if this switch was not specified.
+
+@item ^-P^/PROJECT_FILE=^@var{project}
+@cindex @option{^-P^/PROJECT_FILE^} (@code{gnatclean})
+Use project file @var{project}. Only one such switch can be used.
+When cleaning a project file, the files produced by the compilation of the
+immediate sources or inherited sources of the project files are to be
+deleted. This is not depending on the presence or not of executable names
+on the command line.
+
+@item ^-q^/QUIET^
+@cindex @option{^-q^/QUIET^} (@code{gnatclean})
+Quiet output. If there are no error, do not ouuput anything, except in
+verbose mode (switch ^-v^/VERBOSE^) or in informative-only mode
+(switch ^-n^/NODELETE^).
+
+@item ^-r^/RECURSIVE^
+@cindex @option{^-r^/RECURSIVE^} (@code{gnatclean})
+When a project file is specified (using switch ^-P^/PROJECT_FILE=^),
+clean all imported and extended project files, recursively. If this switch
+is not specified, only the files related to the main project file are to be
+deleted. This switch has no effect if no project file is specified.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@code{gnatclean})
+Verbose mode.
+
+@item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}
+@cindex @option{^-vP^/MESSAGES_PROJECT_FILE^} (@code{gnatclean})
+Indicates the verbosity of the parsing of GNAT project files.
+See @ref{Switches Related to Project Files}.
+
+@item ^-X^/EXTERNAL_REFERENCE=^@var{name=value}
+@cindex @option{^-X^/EXTERNAL_REFERENCE^} (@code{gnatclean})
+Indicates that external variable @var{name} has the value @var{value}.
+The Project Manager will use this value for occurrences of
+@code{external(name)} when parsing the project file.
+See @ref{Switches Related to Project Files}.
+
+@item ^-aO^/OBJECT_SEARCH=^@var{dir}
+@cindex @option{^-aO^/OBJECT_SEARCH^} (@code{gnatclean})
+When searching for ALI and object files, look in directory
+@var{dir}.
+
+@item ^-I^/SEARCH=^@var{dir}
+@cindex @option{^-I^/SEARCH^} (@code{gnatclean})
+Equivalent to @option{^-aO^/OBJECT_SEARCH=^@var{dir}}.
+
+@item ^-I-^/NOCURRENT_DIRECTORY^
+@cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatclean})
+@cindex Source files, suppressing search
+Do not look for ALI or object files in the directory
+where @code{gnatclean} was invoked.
+
+@end table
+
+@node Examples of gnatclean Usage
+@section Examples of @code{gnatclean} Usage
+
+@ifclear vms
+@node GNAT and Libraries
+@chapter GNAT and Libraries
+@cindex Library, building, installing, using
+
+@noindent
+This chapter describes how to build and use
+libraries with GNAT, and also shows how to recompile the GNAT run-time library.
+You should be familiar with the
+Project Manager facility (see @ref{GNAT Project Manager}) before reading this
+chapter.
+
+@menu
+* Introduction to Libraries in GNAT::
+* General Ada Libraries::
+* Stand-alone Ada Libraries::
+* Rebuilding the GNAT Run-Time Library::
+@end menu
+
+@node Introduction to Libraries in GNAT
+@section Introduction to Libraries in GNAT
+
+@noindent
+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 approach is to provide directly the
+set of objects resulting from compilation of the library source files.
+Alternatively, you can group the objects into an archive using whatever
+commands are provided by the operating system. For the latter 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.
+@item
+Compiled code and @file{ALI} files.
+See @ref{The Ada Library Information Files}.
+@end itemize
+
+@noindent
+A GNAT library may either completely expose its source files to the
+compilation context of the user's application.
+Alternatively, it may expose
+a limited subset of its source files, called @emph{interface units},
+in which case the library is referred to as a @emph{stand-alone library}
+(see @ref{Stand-alone Ada Libraries}). In addition, GNAT fully supports
+foreign libraries, which are only available in the object format.
+
+All compilation units comprising
+an application are elaborated, in an order partially defined by Ada language
+semantics.
+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 below.
+
+@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 easiest way to build a library is to use the Project Manager,
+which supports a special type of projects called Library Projects
+(see @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:
+@table @code
+@item Library_Kind
+This attribute controls whether the library is to be static or shared
+
+@item 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 Library_Options
+@item 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 table
+
+@noindent
+The 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. copying associated source, object and @file{ALI} files
+to the specified location.
+
+It is not entirely trivial to correctly perform all the steps required to
+produce a library. We recommend that you use the 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 (see @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
+@command{gnatmake}, which will ensure that all necessary objects are built.
+
+After this task is accomplished, you should follow the standard procedure
+of the underlying operating system to produce the static or shared library.
+
+Here is an example of such a dummy program:
+@smallexample @c ada
+@group
+with My_Lib.Service1;
+with My_Lib.Service2;
+with My_Lib.Service3;
+procedure My_Lib_Dummy is
+begin
+ null;
+end;
+@end group
+@end smallexample
+
+@noindent
+Here are the generic commands that will build an archive or a shared library.
+
+@smallexample
+# compiling the library
+$ gnatmake -c my_lib_dummy.adb
+
+# we don't need the dummy object itself
+$ rm my_lib_dummy.o my_lib_dummy.ali
+
+# create an archive with the remaining objects
+$ ar rc libmy_lib.a *.o
+# some systems may require "ranlib" to be run as well
+
+# or create a shared library
+$ gcc -shared -o libmy_lib.so *.o
+# some systems may require the code to have been compiled with -fPIC
+
+# remove the object files that are now in the library
+$ rm *.o
+
+# Make the ALI files read-only so that gnatmake will not try to
+# regenerate the objects that are in the library
+$ chmod -w *.ali
+@end smallexample
+
+@noindent
+Please note that the library must have a name of the form @file{libxxx.a} or
+@file{libxxx.so} in order to be accessed by the directive @option{-lxxx}
+at link time.
+
+@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. 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 the user must specify the destination.
+GNAT also supports installing the sources in a
+different directory from the other files (@file{ALI}, objects, archives)
+since the source path and the object path can be specified separately.
+
+The system administrator can place general purpose libraries in the default
+compiler paths, by specifying the libraries' location in the configuration
+files @file{ada_source_path} and @file{ada_object_path}.
+These configuration files must be located in the GNAT
+installation tree at the same place as the gcc spec file. The location of
+the gcc spec file can be determined as follows:
+@smallexample
+$ gcc -v
+@end smallexample
+
+@noindent
+The configuration files mentioned above have a simple format: each line
+must contain one unique directory name.
+Those names are added to the corresponding path
+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.
+
+The files @file{ada_source_path} and @file{ada_object_path} might not be
+present in a
+GNAT installation, in which case, GNAT will look for its run-time library in
+the directories @file{adainclude} (for the sources) and @file{adalib} (for the
+objects and @file{ALI} files). When the files exist, the compiler does not
+look in @file{adainclude} and @file{adalib}, and thus the
+@file{ada_source_path} file
+must contain the location for the GNAT run-time sources (which can simply
+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}).
+
+You can also specify a new default path to the run-time library at compilation
+time with the switch @option{--RTS=rts-path}. You can thus choose / change
+the run-time library you want your program to be compiled with. This switch is
+recognized by @command{gcc}, @command{gnatmake}, @command{gnatbind},
+@command{gnatls}, @command{gnatfind} and @command{gnatxref}.
+
+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 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 that they are considered during the
+compilation and linking of the application.
+
+Even if you have a third-party, non-Ada library, you can still use GNAT's
+Project Manager facility to provide a wrapper for it. The following project for
+example, when @code{with}ed in your main project, will link with the
+third-party library @file{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 an Ada library manually, you need to make sure that this
+library is on both your source and object path
+(see @ref{Search Paths and the Run-Time Library (RTL)},
+and @ref{Search Paths for gnatbind}). Furthermore, when the objects are grouped
+in an archive or a shared library, you need to specify the desired
+library at link time.
+
+For 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
+$ gnatmake -aI/dir/my_lib_src -aO/dir/my_lib_obj my_appl \
+ -largs -lmy_lib
+@end smallexample
+
+@noindent
+This can be expressed more simply:
+@smallexample
+$ gnatmake my_appl
+@end smallexample
+@noindent
+when the following conditions are met:
+@itemize @bullet
+@item
+@file{/dir/my_lib_src} has been added by the user to the environment
+variable @code{ADA_INCLUDE_PATH}, or by the administrator to the file
+@file{ada_source_path}
+@item
+@file{/dir/my_lib_obj} has been added by the user to the environment
+variable @code{ADA_OBJECTS_PATH}, or by the administrator to the file
+@file{ada_object_path}
+@item
+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
+
+
+@node Stand-alone Ada Libraries
+@section Stand-alone Ada Libraries
+@cindex Stand-alone library, building, using
+
+@menu
+* Introduction to Stand-alone Libraries::
+* Building a Stand-alone Library::
+* Creating a Stand-alone Library to be used in a non-Ada context::
+* Restrictions in Stand-alone Libraries::
+@end menu
+
+@node Introduction to Stand-alone Libraries
+@subsection Introduction to Stand-alone Libraries
+
+@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. In contrast with
+an ordinary library, which consists of all sources, objects and @file{ALI}
+files of the
+library, a SAL may specify a restricted subset of compilation units
+to serve as a library interface. In this case, the fully
+self-sufficient set of files will normally consist of an objects
+archive, the sources of interface units' specs, and the @file{ALI}
+files of interface units.
+If an interface spec contains a generic unit or an inlined subprogram,
+the body's
+source must also be provided; if the units that must be provided in the source
+form depend on other units, the source and @file{ALI} files of those must
+also be provided.
+
+The main purpose of a SAL is to minimize the recompilation overhead of client
+applications when a 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, a SAL is provided in the shared form and its
+version, controlled by @code{Library_Version} attribute, is not changed,
+then the clients do not need to be relinked.
+
+SALs also allow the library providers to minimize the amount of library source
+text exposed to the clients. Such ``information hiding'' might be useful or
+necessary for various reasons.
+
+Stand-alone libraries are also well suited to be used in an executable whose
+main routine is not written in Ada.
+
+@node Building a Stand-alone Library
+@subsection Building a Stand-alone Library
+
+@noindent
+GNAT's 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. For example:
+
+@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
+
+@noindent
+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.
+
+When a Stand-alone Library is built, first the binder is invoked to build
+a package whose name depends on the library name
+(@file{^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 (@code{dummyinit} and @code{dummyfinal}
+in the example
+above). The object corresponding to this package is included in the library.
+
+You must ensure timely (e.g., prior to any use of interfaces in the SAL)
+calling of these procedures if a static SAL is built, or if a shared SAL
+is built
+with the project-level attribute @code{Library_Auto_Init} set to
+@code{"false"}.
+
+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.
+
+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 that are needed by an Ada client of the library will be
+copied to the designated directory, called the 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 unit 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.
+
+Building stand-alone libraries by hand is somewhat tedious, but for those
+occasions when it is necessary here are the steps that you need to perform:
+@itemize @bullet
+@item
+Compile all library sources.
+
+@item
+Invoke the binder with the switch @option{-n} (No Ada main program),
+with all the @file{ALI} files of the interfaces, and
+with the switch @option{-L} to give specific names to the @code{init}
+and @code{final} procedures. For example:
+@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 @code{init} (and possibly
+@code{final}) procedures for automatic initialization (and finalization).
+The built library should be placed in a directory different from
+the object directory.
+
+@item
+Copy the @code{ALI} files of the interface to the library directory,
+add in this copy an indication that it is an interface to a SAL
+(i.e. add a word @option{SL} on the line in the @file{ALI} file that starts
+with letter ``P'') and make the modified copy of the @file{ALI} file
+read-only.
+@end itemize
+
+@noindent
+Using SALs is not different from using other libraries
+(see @ref{Using the library}).
+
+@node Creating a Stand-alone Library to be used in a non-Ada context
+@subsection Creating a Stand-alone Library to be used in a non-Ada context
+
+@noindent
+It is easy to adapt the SAL build procedure discussed above for use of a SAL in
+a non-Ada context.
+
+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}.
+
+Here is an example of simple library interface for use with C main program:
+
+@smallexample @c ada
+package Interface is
+
+ procedure Do_Something;
+ pragma Export (C, Do_Something, "do_something");
+
+ procedure Do_Something_Else;
+ pragma Export (C, Do_Something_Else, "do_something_else");
+
+end Interface;
+@end smallexample
+
+@noindent
+On the foreign language side, you must provide a ``foreign'' view of the
+library interface; remember that it should contain elaboration routines in
+addition to interface subprograms.
+
+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)
+@smallexample
+/* the library elaboration procedure */
+extern void mylibinit (void);
+
+/* the library finalization procedure */
+extern void mylibfinal (void);
+
+/* the interface exported by the library */
+extern void do_something (void);
+extern void do_something_else (void);
+@end smallexample
+
+@noindent
+Libraries built as explained above can be used from any program, provided
+that the elaboration procedures (named @code{mylibinit} in the previous
+example) are called before the library services are used. Any number of
+libraries can be used simultaneously, as long as the elaboration
+procedure of each library is called.
+
+Below is an example of C program that uses the @code{mylib} library.
+
+@smallexample
+#include "mylib_interface.h"
+
+int
+main (void)
+@{
+ /* First, elaborate the library before using it */
+ mylibinit ();
+
+ /* Main program, using the library exported entities */
+ do_something ();
+ do_something_else ();
+
+ /* Library finalization at the end of the program */
+ mylibfinal ();
+ return 0;
+@}
+@end smallexample
+
+@noindent
+Note that invoking any library finalization procedure generated by
+@code{gnatbind} shuts down the Ada run-time environment.
+Consequently, the
+finalization of all Ada libraries must be performed at the end of the program.
+No call to these libraries nor to the Ada run-time library should be made
+after the finalization phase.
+
+@node Restrictions in Stand-alone Libraries
+@subsection Restrictions in Stand-alone Libraries
+
+@noindent
+The pragmas listed below should be used with caution inside libraries,
+as they can create incompatibilities with other Ada libraries:
+@itemize @bullet
+@item pragma @code{Locking_Policy}
+@item pragma @code{Queuing_Policy}
+@item pragma @code{Task_Dispatching_Policy}
+@item pragma @code{Unreserve_All_Interrupts}
+@end itemize
+
+@noindent
+When using a library that contains such pragmas, the user must make sure
+that all libraries use the same pragmas with the same values. Otherwise,
+@code{Program_Error} will
+be raised during the elaboration of the conflicting
+libraries. The usage of these pragmas and its consequences for the user
+should therefore be well documented.
+
+Similarly, the traceback in the exception occurrence mechanism should be
+enabled or disabled in a consistent manner across all libraries.
+Otherwise, Program_Error will be raised during the elaboration of the
+conflicting libraries.
+
+If the @code{Version} or @code{Body_Version}
+attributes are used inside a library, then you need to
+perform a @code{gnatbind} step that specifies all @file{ALI} files in all
+libraries, so that version identifiers can be properly computed.
+In practice these attributes are rarely used, so this is unlikely
+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 @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
+be determined by means of the command:
+
+@smallexample
+$ gnatls -v
+@end smallexample
+
+@noindent
+The last entry in the object search path usually contains the
+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
+
+@noindent
+This chapter offers some examples of makefiles that solve specific
+problems. It does not explain how to write a makefile (see the GNU make
+documentation), nor does it try to replace the @code{gnatmake} utility
+(@pxref{The GNAT Make Program gnatmake}).
+
+All the examples in this section are specific to the GNU version of
+make. Although @code{make} is a standard utility, and the basic language
+is the same, these examples use some advanced features found only in
+@code{GNU make}.
+
+@menu
+* Using gnatmake in a Makefile::
+* Automatically Creating a List of Directories::
+* Generating the Command Line Switches::
+* Overcoming Command Line Length Limits::
+@end menu
+
+@node Using gnatmake in a Makefile
+@section Using gnatmake in a Makefile
+@findex makefile
+@cindex GNU make
+
+@noindent
+Complex project organizations can be handled in a very powerful way by
+using GNU make combined with gnatmake. For instance, here is a Makefile
+which allows you to build each subsystem of a big project into a separate
+shared library. Such a makefile allows you to significantly reduce the link
+time of very big applications while maintaining full coherence at
+each step of the build process.
+
+The list of dependencies are handled automatically by
+@code{gnatmake}. The Makefile is simply used to call gnatmake in each of
+the appropriate directories.
+
+Note that you should also read the example on how to automatically
+create the list of directories
+(@pxref{Automatically Creating a List of Directories})
+which might help you in case your project has a lot of subdirectories.
+
+@smallexample
+@iftex
+@leftskip=0cm
+@font@heightrm=cmr8
+@heightrm
+@end iftex
+## This Makefile is intended to be used with the following directory
+## configuration:
+## - The sources are split into a series of csc (computer software components)
+## Each of these csc is put in its own directory.
+## Their name are referenced by the directory names.
+## They will be compiled into shared library (although this would also work
+## with static libraries
+## - The main program (and possibly other packages that do not belong to any
+## csc is put in the top level directory (where the Makefile is).
+## toplevel_dir __ first_csc (sources) __ lib (will contain the library)
+## \_ second_csc (sources) __ lib (will contain the library)
+## \_ ...
+## Although this Makefile is build for shared library, it is easy to modify
+## to build partial link objects instead (modify the lines with -shared and
+## gnatlink below)
+##
+## With this makefile, you can change any file in the system or add any new
+## file, and everything will be recompiled correctly (only the relevant shared
+## objects will be recompiled, and the main program will be re-linked).
+
+# The list of computer software component for your project. This might be
+# generated automatically.
+CSC_LIST=aa bb cc
+
+# Name of the main program (no extension)
+MAIN=main
+
+# If we need to build objects with -fPIC, uncomment the following line
+#NEED_FPIC=-fPIC
+
+# The following variable should give the directory containing libgnat.so
+# You can get this directory through 'gnatls -v'. This is usually the last
+# directory in the Object_Path.
+GLIB=...
+
+# The directories for the libraries
+# (This macro expands the list of CSC to the list of shared libraries, you
+# could simply use the expanded form :
+# LIB_DIR=aa/lib/libaa.so bb/lib/libbb.so cc/lib/libcc.so
+LIB_DIR=$@{foreach dir,$@{CSC_LIST@},$@{dir@}/lib/lib$@{dir@}.so@}
+
+$@{MAIN@}: objects $@{LIB_DIR@}
+ gnatbind $@{MAIN@} $@{CSC_LIST:%=-aO%/lib@} -shared
+ gnatlink $@{MAIN@} $@{CSC_LIST:%=-l%@}
+
+objects::
+ # recompile the sources
+ gnatmake -c -i $@{MAIN@}.adb $@{NEED_FPIC@} $@{CSC_LIST:%=-I%@}
+
+# Note: In a future version of GNAT, the following commands will be simplified
+# by a new tool, gnatmlib
+$@{LIB_DIR@}:
+ mkdir -p $@{dir $@@ @}
+ cd $@{dir $@@ @}; gcc -shared -o $@{notdir $@@ @} ../*.o -L$@{GLIB@} -lgnat
+ cd $@{dir $@@ @}; cp -f ../*.ali .
+
+# The dependencies for the modules
+# Note that we have to force the expansion of *.o, since in some cases
+# make won't be able to do it itself.
+aa/lib/libaa.so: $@{wildcard aa/*.o@}
+bb/lib/libbb.so: $@{wildcard bb/*.o@}
+cc/lib/libcc.so: $@{wildcard cc/*.o@}
+
+# Make sure all of the shared libraries are in the path before starting the
+# program
+run::
+ LD_LIBRARY_PATH=`pwd`/aa/lib:`pwd`/bb/lib:`pwd`/cc/lib ./$@{MAIN@}
+
+clean::
+ $@{RM@} -rf $@{CSC_LIST:%=%/lib@}
+ $@{RM@} $@{CSC_LIST:%=%/*.ali@}
+ $@{RM@} $@{CSC_LIST:%=%/*.o@}
+ $@{RM@} *.o *.ali $@{MAIN@}
+@end smallexample
+
+@node Automatically Creating a List of Directories
+@section Automatically Creating a List of Directories
+
+@noindent
+In most makefiles, you will have to specify a list of directories, and
+store it in a variable. For small projects, it is often easier to
+specify each of them by hand, since you then have full control over what
+is the proper order for these directories, which ones should be
+included...
+
+However, in larger projects, which might involve hundreds of
+subdirectories, it might be more convenient to generate this list
+automatically.
+
+The example below presents two methods. The first one, although less
+general, gives you more control over the list. It involves wildcard
+characters, that are automatically expanded by @code{make}. Its
+shortcoming is that you need to explicitly specify some of the
+organization of your project, such as for instance the directory tree
+depth, whether some directories are found in a separate tree,...
+
+The second method is the most general one. It requires an external
+program, called @code{find}, which is standard on all Unix systems. All
+the directories found under a given root directory will be added to the
+list.
+
+@smallexample
+@iftex
+@leftskip=0cm
+@font@heightrm=cmr8
+@heightrm
+@end iftex
+# The examples below are based on the following directory hierarchy:
+# All the directories can contain any number of files
+# ROOT_DIRECTORY -> a -> aa -> aaa
+# -> ab
+# -> ac
+# -> b -> ba -> baa
+# -> bb
+# -> bc
+# This Makefile creates a variable called DIRS, that can be reused any time
+# you need this list (see the other examples in this section)
+
+# The root of your project's directory hierarchy
+ROOT_DIRECTORY=.
+
+####
+# First method: specify explicitly the list of directories
+# This allows you to specify any subset of all the directories you need.
+####
+
+DIRS := a/aa/ a/ab/ b/ba/
+
+####
+# Second method: use wildcards
+# Note that the argument(s) to wildcard below should end with a '/'.
+# Since wildcards also return file names, we have to filter them out
+# to avoid duplicate directory names.
+# We thus use make's @code{dir} and @code{sort} functions.
+# It sets DIRs to the following value (note that the directories aaa and baa
+# are not given, unless you change the arguments to wildcard).
+# DIRS= ./a/a/ ./b/ ./a/aa/ ./a/ab/ ./a/ac/ ./b/ba/ ./b/bb/ ./b/bc/
+####
+
+DIRS := $@{sort $@{dir $@{wildcard $@{ROOT_DIRECTORY@}/*/
+ $@{ROOT_DIRECTORY@}/*/*/@}@}@}
+
+####
+# Third method: use an external program
+# This command is much faster if run on local disks, avoiding NFS slowdowns.
+# This is the most complete command: it sets DIRs to the following value:
+# DIRS= ./a ./a/aa ./a/aa/aaa ./a/ab ./a/ac ./b ./b/ba ./b/ba/baa ./b/bb ./b/bc
+####
+
+DIRS := $@{shell find $@{ROOT_DIRECTORY@} -type d -print@}
+
+@end smallexample
+
+@node Generating the Command Line Switches
+@section Generating the Command Line Switches
+
+@noindent
+Once you have created the list of directories as explained in the
+previous section (@pxref{Automatically Creating a List of Directories}),
+you can easily generate the command line arguments to pass to gnatmake.
+
+For the sake of completeness, this example assumes that the source path
+is not the same as the object path, and that you have two separate lists
+of directories.
+
+@smallexample
+# see "Automatically creating a list of directories" to create
+# these variables
+SOURCE_DIRS=
+OBJECT_DIRS=
+
+GNATMAKE_SWITCHES := $@{patsubst %,-aI%,$@{SOURCE_DIRS@}@}
+GNATMAKE_SWITCHES += $@{patsubst %,-aO%,$@{OBJECT_DIRS@}@}
+
+all:
+ gnatmake $@{GNATMAKE_SWITCHES@} main_unit
+@end smallexample
+
+@node Overcoming Command Line Length Limits
+@section Overcoming Command Line Length Limits
+
+@noindent
+One problem that might be encountered on big projects is that many
+operating systems limit the length of the command line. It is thus hard to give
+gnatmake the list of source and object directories.
+
+This example shows how you can set up environment variables, which will
+make @code{gnatmake} behave exactly as if the directories had been
+specified on the command line, but have a much higher length limit (or
+even none on most systems).
+
+It assumes that you have created a list of directories in your Makefile,
+using one of the methods presented in
+@ref{Automatically Creating a List of Directories}.
+For the sake of completeness, we assume that the object
+path (where the ALI files are found) is different from the sources patch.
+
+Note a small trick in the Makefile below: for efficiency reasons, we
+create two temporary variables (SOURCE_LIST and OBJECT_LIST), that are
+expanded immediately by @code{make}. This way we overcome the standard
+make behavior which is to expand the variables only when they are
+actually used.
+
+On Windows, if you are using the standard Windows command shell, you must
+replace colons with semicolons in the assignments to these variables.
+
+@smallexample
+@iftex
+@leftskip=0cm
+@font@heightrm=cmr8
+@heightrm
+@end iftex
+# In this example, we create both ADA_INCLUDE_PATH and ADA_OBJECT_PATH.
+# This is the same thing as putting the -I arguments on the command line.
+# (the equivalent of using -aI on the command line would be to define
+# only ADA_INCLUDE_PATH, the equivalent of -aO is ADA_OBJECT_PATH).
+# You can of course have different values for these variables.
+#
+# Note also that we need to keep the previous values of these variables, since
+# they might have been set before running 'make' to specify where the GNAT
+# library is installed.
+
+# see "Automatically creating a list of directories" to create these
+# variables
+SOURCE_DIRS=
+OBJECT_DIRS=
+
+empty:=
+space:=$@{empty@} $@{empty@}
+SOURCE_LIST := $@{subst $@{space@},:,$@{SOURCE_DIRS@}@}
+OBJECT_LIST := $@{subst $@{space@},:,$@{OBJECT_DIRS@}@}
+ADA_INCLUDE_PATH += $@{SOURCE_LIST@}
+ADA_OBJECT_PATH += $@{OBJECT_LIST@}
+export ADA_INCLUDE_PATH
+export ADA_OBJECT_PATH
+
+all:
+ gnatmake main_unit
+@end smallexample
+@end ifclear
+
+
+@node Finding Memory Problems
+@chapter Finding Memory Problems
+
+@noindent
+This chapter describes
+@ifclear vms
+the @command{gnatmem} tool, which can be used to track down
+``memory leaks'', and
+@end ifclear
+the GNAT Debug Pool facility, which can be used to detect incorrect uses of
+access values (including ``dangling references'').
+
+@menu
+@ifclear vms
+* The gnatmem Tool::
+@end ifclear
+* The GNAT Debug Pool Facility::
+@end menu
+
+
+@ifclear vms
+@node The gnatmem Tool
+@section The @command{gnatmem} Tool
+@findex gnatmem
+
+@noindent
+The @code{gnatmem} utility monitors dynamic allocation and
+deallocation activity in a program, and displays information about
+incorrect deallocations and possible sources of memory leaks.
+It provides three type of information:
+@itemize @bullet
+@item
+General information concerning memory management, such as the total
+number of allocations and deallocations, the amount of allocated
+memory and the high water mark, i.e. the largest amount of allocated
+memory in the course of program execution.
+
+@item
+Backtraces for all incorrect deallocations, that is to say deallocations
+which do not correspond to a valid allocation.
+
+@item
+Information on each allocation that is potentially the origin of a memory
+leak.
+@end itemize
+
+@menu
+* Running gnatmem::
+* Switches for gnatmem::
+* Example of gnatmem Usage::
+@end menu
+
+@node Running gnatmem
+@subsection Running @code{gnatmem}
+
+@noindent
+@code{gnatmem} makes use of the output created by the special version of
+allocation and deallocation routines that record call information. This
+allows to obtain accurate dynamic memory usage history at a minimal cost to
+the execution speed. Note however, that @code{gnatmem} is not supported on
+all platforms (currently, it is supported on AIX, HP-UX, GNU/Linux x86,
+Solaris (sparc and x86) and Windows NT/2000/XP (x86).
+
+@noindent
+The @code{gnatmem} command has the form
+
+@smallexample
+ $ gnatmem [switches] user_program
+@end smallexample
+
+@noindent
+The program must have been linked with the instrumented version of the
+allocation and deallocation routines. This is done by linking with the
+@file{libgmem.a} library. For correct symbolic backtrace information,
+the user program should be compiled with debugging options
+@ref{Switches for gcc}. For example to build @file{my_program}:
+
+@smallexample
+$ gnatmake -g my_program -largs -lgmem
+@end smallexample
+
+@noindent
+When running @file{my_program} the file @file{gmem.out} is produced. This file
+contains information about all allocations and deallocations done by the
+program. It is produced by the instrumented allocations and
+deallocations routines and will be used by @code{gnatmem}.
+
+@noindent
+Gnatmem must be supplied with the @file{gmem.out} file and the executable to
+examine. If the location of @file{gmem.out} file was not explicitly supplied by
+@code{-i} switch, gnatmem will assume that this file can be found in the
+current directory. For example, after you have executed @file{my_program},
+@file{gmem.out} can be analyzed by @code{gnatmem} using the command:
+
+@smallexample
+$ gnatmem my_program
+@end smallexample
+
+@noindent
+This will produce the output with the following format:
+
+*************** debut cc
+@smallexample
+$ gnatmem my_program
+
+Global information
+------------------
+ Total number of allocations : 45
+ Total number of deallocations : 6
+ Final Water Mark (non freed mem) : 11.29 Kilobytes
+ High Water Mark : 11.40 Kilobytes
+
+.
+.
+.
+Allocation Root # 2
+-------------------
+ Number of non freed allocations : 11
+ Final Water Mark (non freed mem) : 1.16 Kilobytes
+ High Water Mark : 1.27 Kilobytes
+ Backtrace :
+ my_program.adb:23 my_program.alloc
+.
+.
+.
+@end smallexample
+
+The first block of output gives general information. In this case, the
+Ada construct ``@code{@b{new}}'' was executed 45 times, and only 6 calls to an
+Unchecked_Deallocation routine occurred.
+
+@noindent
+Subsequent paragraphs display information on all allocation roots.
+An allocation root is a specific point in the execution of the program
+that generates some dynamic allocation, such as a ``@code{@b{new}}''
+construct. This root is represented by an execution backtrace (or subprogram
+call stack). By default the backtrace depth for allocations roots is 1, so
+that a root corresponds exactly to a source location. The backtrace can
+be made deeper, to make the root more specific.
+
+@node Switches for gnatmem
+@subsection Switches for @code{gnatmem}
+
+@noindent
+@code{gnatmem} recognizes the following switches:
+
+@table @option
+
+@item -q
+@cindex @option{-q} (@code{gnatmem})
+Quiet. Gives the minimum output needed to identify the origin of the
+memory leaks. Omits statistical information.
+
+@item @var{N}
+@cindex @var{N} (@code{gnatmem})
+N is an integer literal (usually between 1 and 10) which controls the
+depth of the backtraces defining allocation root. The default value for
+N is 1. The deeper the backtrace, the more precise the localization of
+the root. Note that the total number of roots can depend on this
+parameter. This parameter must be specified @emph{before} the name of the
+executable to be analyzed, to avoid ambiguity.
+
+@item -b n
+@cindex @option{-b} (@code{gnatmem})
+This switch has the same effect as just depth parameter.
+
+@item -i @var{file}
+@cindex @option{-i} (@code{gnatmem})
+Do the @code{gnatmem} processing starting from @file{file}, rather than
+@file{gmem.out} in the current directory.
+
+@item -m n
+@cindex @option{-m} (@code{gnatmem})
+This switch causes @code{gnatmem} to mask the allocation roots that have less
+than n leaks. The default value is 1. Specifying the value of 0 will allow to
+examine even the roots that didn't result in leaks.
+
+@item -s order
+@cindex @option{-s} (@code{gnatmem})
+This switch causes @code{gnatmem} to sort the allocation roots according to the
+specified order of sort criteria, each identified by a single letter. The
+currently supported criteria are @code{n, h, w} standing respectively for
+number of unfreed allocations, high watermark, and final watermark
+corresponding to a specific root. The default order is @code{nwh}.
+
+@end table
+
+@node Example of gnatmem Usage
+@subsection Example of @code{gnatmem} Usage
+
+@noindent
+The following example shows the use of @code{gnatmem}
+on a simple memory-leaking program.
+Suppose that we have the following Ada program:
+
+@smallexample @c ada
+@group
+@cartouche
+with Unchecked_Deallocation;
+procedure Test_Gm is
+
+ type T is array (1..1000) of Integer;
+ type Ptr is access T;
+ procedure Free is new Unchecked_Deallocation (T, Ptr);
+ A : Ptr;
+
+ procedure My_Alloc is
+ begin
+ A := new T;
+ end My_Alloc;
+
+ procedure My_DeAlloc is
+ B : Ptr := A;
+ begin
+ Free (B);
+ end My_DeAlloc;
+
+begin
+ My_Alloc;
+ for I in 1 .. 5 loop
+ for J in I .. 5 loop
+ My_Alloc;
+ end loop;
+ My_Dealloc;
+ end loop;
+end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+The program needs to be compiled with debugging option and linked with
+@code{gmem} library:
+
+@smallexample
+$ gnatmake -g test_gm -largs -lgmem
+@end smallexample
+
+@noindent
+Then we execute the program as usual:
+
+@smallexample
+$ test_gm
+@end smallexample
+
+@noindent
+Then @code{gnatmem} is invoked simply with
+@smallexample
+$ gnatmem test_gm
+@end smallexample
+
+@noindent
+which produces the following output (result may vary on different platforms):
+
+@smallexample
+Global information
+------------------
+ Total number of allocations : 18
+ Total number of deallocations : 5
+ Final Water Mark (non freed mem) : 53.00 Kilobytes
+ High Water Mark : 56.90 Kilobytes
+
+Allocation Root # 1
+-------------------
+ Number of non freed allocations : 11
+ Final Water Mark (non freed mem) : 42.97 Kilobytes
+ High Water Mark : 46.88 Kilobytes
+ Backtrace :
+ test_gm.adb:11 test_gm.my_alloc
+
+Allocation Root # 2
+-------------------
+ Number of non freed allocations : 1
+ Final Water Mark (non freed mem) : 10.02 Kilobytes
+ High Water Mark : 10.02 Kilobytes
+ Backtrace :
+ s-secsta.adb:81 system.secondary_stack.ss_init
+
+Allocation Root # 3
+-------------------
+ Number of non freed allocations : 1
+ Final Water Mark (non freed mem) : 12 Bytes
+ High Water Mark : 12 Bytes
+ Backtrace :
+ s-secsta.adb:181 system.secondary_stack.ss_init
+@end smallexample
+
+@noindent
+Note that the GNAT run time contains itself a certain number of
+allocations that have no corresponding deallocation,
+as shown here for root #2 and root
+#3. This is a normal behavior when the number of non freed allocations
+is one, it allocates dynamic data structures that the run time needs for
+the complete lifetime of the program. Note also that there is only one
+allocation root in the user program with a single line back trace:
+test_gm.adb:11 test_gm.my_alloc, whereas a careful analysis of the
+program shows that 'My_Alloc' is called at 2 different points in the
+source (line 21 and line 24). If those two allocation roots need to be
+distinguished, the backtrace depth parameter can be used:
+
+@smallexample
+$ gnatmem 3 test_gm
+@end smallexample
+
+@noindent
+which will give the following output:
+
+@smallexample
+Global information
+------------------
+ Total number of allocations : 18
+ Total number of deallocations : 5
+ Final Water Mark (non freed mem) : 53.00 Kilobytes
+ High Water Mark : 56.90 Kilobytes
+
+Allocation Root # 1
+-------------------
+ Number of non freed allocations : 10
+ Final Water Mark (non freed mem) : 39.06 Kilobytes
+ High Water Mark : 42.97 Kilobytes
+ Backtrace :
+ test_gm.adb:11 test_gm.my_alloc
+ test_gm.adb:24 test_gm
+ b_test_gm.c:52 main
+
+Allocation Root # 2
+-------------------
+ Number of non freed allocations : 1
+ Final Water Mark (non freed mem) : 10.02 Kilobytes
+ High Water Mark : 10.02 Kilobytes
+ Backtrace :
+ s-secsta.adb:81 system.secondary_stack.ss_init
+ s-secsta.adb:283 <system__secondary_stack___elabb>
+ b_test_gm.c:33 adainit
+
+Allocation Root # 3
+-------------------
+ Number of non freed allocations : 1
+ Final Water Mark (non freed mem) : 3.91 Kilobytes
+ High Water Mark : 3.91 Kilobytes
+ Backtrace :
+ test_gm.adb:11 test_gm.my_alloc
+ test_gm.adb:21 test_gm
+ b_test_gm.c:52 main
+
+Allocation Root # 4
+-------------------
+ Number of non freed allocations : 1
+ Final Water Mark (non freed mem) : 12 Bytes
+ High Water Mark : 12 Bytes
+ Backtrace :
+ s-secsta.adb:181 system.secondary_stack.ss_init
+ s-secsta.adb:283 <system__secondary_stack___elabb>
+ b_test_gm.c:33 adainit
+@end smallexample
+
+@noindent
+The allocation root #1 of the first example has been split in 2 roots #1
+and #3 thanks to the more precise associated backtrace.
+
+@end ifclear
+
+
+@node The GNAT Debug Pool Facility
+@section The GNAT Debug Pool Facility
+@findex Debug Pool
+@cindex storage, pool, memory corruption
+
+@noindent
+The use of unchecked deallocation and unchecked conversion can easily
+lead to incorrect memory references. The problems generated by such
+references are usually difficult to tackle because the symptoms can be
+very remote from the origin of the problem. In such cases, it is
+very helpful to detect the problem as early as possible. This is the
+purpose of the Storage Pool provided by @code{GNAT.Debug_Pools}.
+
+In order to use the GNAT specific debugging pool, the user must
+associate a debug pool object with each of the access types that may be
+related to suspected memory problems. See Ada Reference Manual 13.11.
+@smallexample @c ada
+type Ptr is access Some_Type;
+Pool : GNAT.Debug_Pools.Debug_Pool;
+for Ptr'Storage_Pool use Pool;
+@end smallexample
+
+@noindent
+@code{GNAT.Debug_Pools} is derived from a GNAT-specific kind of
+pool: the @code{Checked_Pool}. Such pools, like standard Ada storage pools,
+allow the user to redefine allocation and deallocation strategies. They
+also provide a checkpoint for each dereference, through the use of
+the primitive operation @code{Dereference} which is implicitly called at
+each dereference of an access value.
+
+Once an access type has been associated with a debug pool, operations on
+values of the type may raise four distinct exceptions,
+which correspond to four potential kinds of memory corruption:
+@itemize @bullet
+@item
+@code{GNAT.Debug_Pools.Accessing_Not_Allocated_Storage}
+@item
+@code{GNAT.Debug_Pools.Accessing_Deallocated_Storage}
+@item
+@code{GNAT.Debug_Pools.Freeing_Not_Allocated_Storage}
+@item
+@code{GNAT.Debug_Pools.Freeing_Deallocated_Storage }
+@end itemize
+
+@noindent
+For types associated with a Debug_Pool, dynamic allocation is performed using
+the standard
+GNAT allocation routine. References to all allocated chunks of memory
+are kept in an internal dictionary.
+Several deallocation strategies are provided, whereupon the user can choose
+to release the memory to the system, keep it allocated for further invalid
+access checks, or fill it with an easily recognizable pattern for debug
+sessions.
+The memory pattern is the old IBM hexadecimal convention: @code{16#DEADBEEF#}.
+
+See the documentation in the file g-debpoo.ads for more information on the
+various strategies.
+
+Upon each dereference, a check is made that the access value denotes a
+properly allocated memory location. Here is a complete example of use of
+@code{Debug_Pools}, that includes typical instances of memory corruption:
+@smallexample @c ada
+@iftex
+@leftskip=0cm
+@end iftex
+with Gnat.Io; use Gnat.Io;
+with Unchecked_Deallocation;
+with Unchecked_Conversion;
+with GNAT.Debug_Pools;
+with System.Storage_Elements;
+with Ada.Exceptions; use Ada.Exceptions;
+procedure Debug_Pool_Test is
+
+ type T is access Integer;
+ type U is access all T;
+
+ P : GNAT.Debug_Pools.Debug_Pool;
+ for T'Storage_Pool use P;
+
+ procedure Free is new Unchecked_Deallocation (Integer, T);
+ function UC is new Unchecked_Conversion (U, T);
+ A, B : aliased T;
+
+ procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line);
+
+begin
+ Info (P);
+ A := new Integer;
+ B := new Integer;
+ B := A;
+ Info (P);
+ Free (A);
+ begin
+ Put_Line (Integer'Image(B.all));
+ exception
+ when E : others => Put_Line ("raised: " & Exception_Name (E));
+ end;
+ begin
+ Free (B);
+ exception
+ when E : others => Put_Line ("raised: " & Exception_Name (E));
+ end;
+ B := UC(A'Access);
+ begin
+ Put_Line (Integer'Image(B.all));
+ exception
+ when E : others => Put_Line ("raised: " & Exception_Name (E));
+ end;
+ begin
+ Free (B);
+ exception
+ when E : others => Put_Line ("raised: " & Exception_Name (E));
+ end;
+ Info (P);
+end Debug_Pool_Test;
+@end smallexample
+
+@noindent
+The debug pool mechanism provides the following precise diagnostics on the
+execution of this erroneous program:
+@smallexample
+Debug Pool info:
+ Total allocated bytes : 0
+ Total deallocated bytes : 0
+ Current Water Mark: 0
+ High Water Mark: 0
+
+Debug Pool info:
+ Total allocated bytes : 8
+ Total deallocated bytes : 0
+ Current Water Mark: 8
+ High Water Mark: 8
+
+raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE
+raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE
+raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE
+raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE
+Debug Pool info:
+ Total allocated bytes : 8
+ Total deallocated bytes : 4
+ Current Water Mark: 4
+ High Water Mark: 8
+@end smallexample
+
+
+@node Creating Sample Bodies Using gnatstub
+@chapter Creating Sample Bodies Using @command{gnatstub}
+@findex gnatstub
+
+@noindent
+@command{gnatstub} creates body stubs, that is, empty but compilable bodies
+for library unit declarations.
+
+To create a body stub, @command{gnatstub} has to compile the library
+unit declaration. Therefore, bodies can be created only for legal
+library units. Moreover, if a library unit depends semantically upon
+units located outside the current directory, you have to provide
+the source search path when calling @command{gnatstub}, see the description
+of @command{gnatstub} switches below.
+
+@menu
+* Running gnatstub::
+* Switches for gnatstub::
+@end menu
+
+@node Running gnatstub
+@section Running @command{gnatstub}
+
+@noindent
+@command{gnatstub} has the command-line interface of the form
+
+@smallexample
+$ gnatstub [switches] filename [directory]
+@end smallexample
+
+@noindent
+where
+@table @emph
+@item filename
+is the name of the source file that contains a library unit declaration
+for which a body must be created. The file name may contain the path
+information.
+The file name does not have to follow the GNAT file name conventions. If the
+name
+does not follow GNAT file naming conventions, the name of the body file must
+be provided
+explicitly as the value of the @option{^-o^/BODY=^@var{body-name}} option.
+If the file name follows the GNAT file naming
+conventions and the name of the body file is not provided,
+@command{gnatstub}
+creates the name
+of the body file from the argument file name by replacing the @file{.ads}
+suffix
+with the @file{.adb} suffix.
+
+@item directory
+indicates the directory in which the body stub is to be placed (the default
+is the
+current directory)
+
+@item switches
+is an optional sequence of switches as described in the next section
+@end table
+
+@node Switches for gnatstub
+@section Switches for @command{gnatstub}
+
+@table @option
+@c !sort!
+
+@item ^-f^/FULL^
+@cindex @option{^-f^/FULL^} (@command{gnatstub})
+If the destination directory already contains a file with the name of the
+body file
+for the argument spec file, replace it with the generated body stub.
+
+@item ^-hs^/HEADER=SPEC^
+@cindex @option{^-hs^/HEADER=SPEC^} (@command{gnatstub})
+Put the comment header (i.e., all the comments preceding the
+compilation unit) from the source of the library unit declaration
+into the body stub.
+
+@item ^-hg^/HEADER=GENERAL^
+@cindex @option{^-hg^/HEADER=GENERAL^} (@command{gnatstub})
+Put a sample comment header into the body stub.
+
+@ifclear vms
+@item -IDIR
+@cindex @option{-IDIR} (@command{gnatstub})
+@itemx -I-
+@cindex @option{-I-} (@command{gnatstub})
+@end ifclear
+@ifset vms
+@item /NOCURRENT_DIRECTORY
+@cindex @option{/NOCURRENT_DIRECTORY} (@command{gnatstub})
+@end ifset
+^These switches have ^This switch has^ the same meaning as in calls to
+@command{gcc}.
+^They define ^It defines ^ the source search path in the call to
+@command{gcc} issued
+by @command{gnatstub} to compile an argument source file.
+
+@item ^-gnatec^/CONFIGURATION_PRAGMAS_FILE=^@var{PATH}
+@cindex @option{^-gnatec^/CONFIGURATION_PRAGMAS_FILE^} (@command{gnatstub})
+This switch has the same meaning as in calls to @command{gcc}.
+It defines the additional configuration file to be passed to the call to
+@command{gcc} issued
+by @command{gnatstub} to compile an argument source file.
+
+@item ^-gnatyM^/MAX_LINE_LENGTH=^@var{n}
+@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. 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})
+(@var{n} is a non-negative integer from 1 to 9). Set the indentation level in
+the generated body sample to @var{n}.
+The default indentation is 3.
+
+@item ^-gnatyo^/ORDERED_SUBPROGRAMS^
+@cindex @option{^-gnato^/ORDERED_SUBPROGRAMS^} (@command{gnatstub})
+Order local bodies alphabetically. (By default local bodies are ordered
+in the same way as the corresponding local specs in the argument spec file.)
+
+@item ^-i^/INDENTATION=^@var{n}
+@cindex @option{^-i^/INDENTATION^} (@command{gnatstub})
+Same as @option{^-gnaty^/STYLE_CHECKS=^@var{n}}
+
+@item ^-k^/TREE_FILE=SAVE^
+@cindex @option{^-k^/TREE_FILE=SAVE^} (@command{gnatstub})
+Do not remove the tree file (i.e., the snapshot of the compiler internal
+structures used by @command{gnatstub}) after creating the body stub.
+
+@item ^-l^/LINE_LENGTH=^@var{n}
+@cindex @option{^-l^/LINE_LENGTH^} (@command{gnatstub})
+Same as @option{^-gnatyM^/MAX_LINE_LENGTH=^@var{n}}
+
+@item ^-o^/BODY=^@var{body-name}
+@cindex @option{^-o^/BODY^} (@command{gnatstub})
+Body file name. This should be set if the argument file name does not
+follow
+the GNAT file naming
+conventions. If this switch is omitted the default name for the body will be
+obtained
+from the argument file name according to the GNAT file naming conventions.
+
+@item ^-q^/QUIET^
+@cindex @option{^-q^/QUIET^} (@command{gnatstub})
+Quiet mode: do not generate a confirmation when a body is
+successfully created, and do not generate a message when a body is not
+required for an
+argument unit.
+
+@item ^-r^/TREE_FILE=REUSE^
+@cindex @option{^-r^/TREE_FILE=REUSE^} (@command{gnatstub})
+Reuse the tree file (if it exists) instead of creating it. Instead of
+creating the tree file for the library unit declaration, @command{gnatstub}
+tries to find it in the current directory and use it for creating
+a body. If the tree file is not found, no body is created. This option
+also implies @option{^-k^/SAVE^}, whether or not
+the latter is set explicitly.
+
+@item ^-t^/TREE_FILE=OVERWRITE^
+@cindex @option{^-t^/TREE_FILE=OVERWRITE^} (@command{gnatstub})
+Overwrite the existing tree file. If the current directory already
+contains the file which, according to the GNAT file naming rules should
+be considered as a tree file for the argument source file,
+@command{gnatstub}
+will refuse to create the tree file needed to create a sample body
+unless this option is set.
+
+@item ^-v^/VERBOSE^
+@cindex @option{^-v^/VERBOSE^} (@command{gnatstub})
+Verbose mode: generate version information.
+
+@end table
+
+
+@node Other Utility Programs
+@chapter Other Utility Programs
+
+@noindent
+This chapter discusses some other utility programs available in the Ada
+environment.
+
+@menu
+* Using Other Utility Programs with GNAT::
+* The External Symbol Naming Scheme of GNAT::
+@ifclear vms
+* Ada Mode for Glide::
+@end ifclear
+* Converting Ada Files to html with gnathtml::
+* Installing gnathtml::
+@ifset vms
+* LSE::
+* Profiling::
+@end ifset
+@end menu
+
+@node Using Other Utility Programs with GNAT
+@section Using Other Utility Programs with GNAT
+
+@noindent
+The object files generated by GNAT are in standard system format and in
+particular the debugging information uses this format. This means
+programs generated by GNAT can be used with existing utilities that
+depend on these formats.
+
+@ifclear vms
+In general, any utility program that works with C will also often work with
+Ada programs generated by GNAT. This includes software utilities such as
+gprof (a profiling program), @code{gdb} (the FSF debugger), and utilities such
+as Purify.
+@end ifclear
+
+@node The External Symbol Naming Scheme of GNAT
+@section The External Symbol Naming Scheme of GNAT
+
+@noindent
+In order to interpret the output from GNAT, when using tools that are
+originally intended for use with other languages, it is useful to
+understand the conventions used to generate link names from the Ada
+entity names.
+
+All link names are in all lowercase letters. With the exception of library
+procedure names, the mechanism used is simply to use the full expanded
+Ada name with dots replaced by double underscores. For example, suppose
+we have the following package spec:
+
+@smallexample @c ada
+@group
+@cartouche
+package QRS is
+ MN : Integer;
+end QRS;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+The variable @code{MN} has a full expanded Ada name of @code{QRS.MN}, so
+the corresponding link name is @code{qrs__mn}.
+@findex Export
+Of course if a @code{pragma Export} is used this may be overridden:
+
+@smallexample @c ada
+@group
+@cartouche
+package Exports is
+ Var1 : Integer;
+ pragma Export (Var1, C, External_Name => "var1_name");
+ Var2 : Integer;
+ pragma Export (Var2, C, Link_Name => "var2_link_name");
+end Exports;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+In this case, the link name for @var{Var1} is whatever link name the
+C compiler would assign for the C function @var{var1_name}. This typically
+would be either @var{var1_name} or @var{_var1_name}, depending on operating
+system conventions, but other possibilities exist. The link name for
+@var{Var2} is @var{var2_link_name}, and this is not operating system
+dependent.
+
+@findex _main
+One exception occurs for library level procedures. A potential ambiguity
+arises between the required name @code{_main} for the C main program,
+and the name we would otherwise assign to an Ada library level procedure
+called @code{Main} (which might well not be the main program).
+
+To avoid this ambiguity, we attach the prefix @code{_ada_} to such
+names. So if we have a library level procedure such as
+
+@smallexample @c ada
+@group
+@cartouche
+procedure Hello (S : String);
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+the external name of this procedure will be @var{_ada_hello}.
+
+@ifclear vms
+@node Ada Mode for Glide
+@section Ada Mode for @code{Glide}
+@cindex Ada mode (for Glide)
+
+@noindent
+The Glide mode for programming in Ada (both Ada83 and Ada95) helps the
+user to understand and navigate existing code, and facilitates writing
+new code. It furthermore provides some utility functions for easier
+integration of standard Emacs features when programming in Ada.
+
+Its general features include:
+
+@itemize @bullet
+@item
+An Integrated Development Environment with functionality such as the
+following
+
+@itemize @bullet
+@item
+``Project files'' for configuration-specific aspects
+(e.g. directories and compilation options)
+
+@item
+Compiling and stepping through error messages.
+
+@item
+Running and debugging an applications within Glide.
+@end itemize
+
+@item
+Pull-down menus
+
+@item
+User configurability
+@end itemize
+
+Some of the specific Ada mode features are:
+
+@itemize @bullet
+@item
+Functions for easy and quick stepping through Ada code
+
+@item
+Getting cross reference information for identifiers (e.g., finding a
+defining occurrence)
+
+@item
+Displaying an index menu of types and subprograms, allowing
+direct selection for browsing
+
+@item
+Automatic color highlighting of the various Ada entities
+@end itemize
+
+Glide directly supports writing Ada code, via several facilities:
+
+@itemize @bullet
+@item
+Switching between spec and body files with possible
+autogeneration of body files
+
+@item
+Automatic formating of subprogram parameter lists
+
+@item
+Automatic indentation according to Ada syntax
+
+@item
+Automatic completion of identifiers
+
+@item
+Automatic (and configurable) casing of identifiers, keywords, and attributes
+
+@item
+Insertion of syntactic templates
+
+@item
+Block commenting / uncommenting
+@end itemize
+
+@noindent
+For more information, please refer to the online documentation
+available in the @code{Glide} @result{} @code{Help} menu.
+@end ifclear
+
+
+@node Converting Ada Files to html with gnathtml
+@section Converting Ada Files to HTML with @code{gnathtml}
+
+@noindent
+This @code{Perl} script allows Ada source files to be browsed using
+standard Web browsers. For installation procedure, see the section
+@xref{Installing gnathtml}.
+
+Ada reserved keywords are highlighted in a bold font and Ada comments in
+a blue font. Unless your program was compiled with the gcc @option{-gnatx}
+switch to suppress the generation of cross-referencing information, user
+defined variables and types will appear in a different color; you will
+be able to click on any identifier and go to its declaration.
+
+The command line is as follow:
+@smallexample
+$ perl gnathtml.pl [switches] ada-files
+@end smallexample
+
+@noindent
+You can pass it as many Ada files as you want. @code{gnathtml} will generate
+an html file for every ada file, and a global file called @file{index.htm}.
+This file is an index of every identifier defined in the files.
+
+The available switches are the following ones :
+
+@table @option
+@item -83
+@cindex @option{-83} (@code{gnathtml})
+Only the subset on the Ada 83 keywords will be highlighted, not the full
+Ada 95 keywords set.
+
+@item -cc @var{color}
+@cindex @option{-cc} (@code{gnathtml})
+This option allows you to change the color used for comments. The default
+value is green. The color argument can be any name accepted by html.
+
+@item -d
+@cindex @option{-d} (@code{gnathtml})
+If the ada files depend on some other files (using for instance the
+@code{with} command, the latter will also be converted to html.
+Only the files in the user project will be converted to html, not the files
+in the run-time library itself.
+
+@item -D
+@cindex @option{-D} (@code{gnathtml})
+This command is the same as @option{-d} above, but @command{gnathtml} will
+also look for files in the run-time library, and generate html files for them.
+
+@item -ext @var{extension}
+@cindex @option{-ext} (@code{gnathtml})
+This option allows you to change the extension of the generated HTML files.
+If you do not specify an extension, it will default to @file{htm}.
+
+@item -f
+@cindex @option{-f} (@code{gnathtml})
+By default, gnathtml will generate html links only for global entities
+('with'ed units, global variables and types,...). If you specify the
+@option{-f} on the command line, then links will be generated for local
+entities too.
+
+@item -l @var{number}
+@cindex @option{-l} (@code{gnathtml})
+If this switch is provided and @var{number} is not 0, then @code{gnathtml}
+will number the html files every @var{number} line.
+
+@item -I @var{dir}
+@cindex @option{-I} (@code{gnathtml})
+Specify a directory to search for library files (@file{.ALI} files) and
+source files. You can provide several -I switches on the command line,
+and the directories will be parsed in the order of the command line.
+
+@item -o @var{dir}
+@cindex @option{-o} (@code{gnathtml})
+Specify the output directory for html files. By default, gnathtml will
+saved the generated html files in a subdirectory named @file{html/}.
+
+@item -p @var{file}
+@cindex @option{-p} (@code{gnathtml})
+If you are using Emacs and the most recent Emacs Ada mode, which provides
+a full Integrated Development Environment for compiling, checking,
+running and debugging applications, you may use @file{.gpr} files
+to give the directories where Emacs can find sources and object files.
+
+Using this switch, you can tell gnathtml to use these files. This allows
+you to get an html version of your application, even if it is spread
+over multiple directories.
+
+@item -sc @var{color}
+@cindex @option{-sc} (@code{gnathtml})
+This option allows you to change the color used for symbol definitions.
+The default value is red. The color argument can be any name accepted by html.
+
+@item -t @var{file}
+@cindex @option{-t} (@code{gnathtml})
+This switch provides the name of a file. This file contains a list of
+file names to be converted, and the effect is exactly as though they had
+appeared explicitly on the command line. This
+is the recommended way to work around the command line length limit on some
+systems.
+
+@end table
+
+@node Installing gnathtml
+@section Installing @code{gnathtml}
+
+@noindent
+@code{Perl} needs to be installed on your machine to run this script.
+@code{Perl} is freely available for almost every architecture and
+Operating System via the Internet.
+
+On Unix systems, you may want to modify the first line of the script
+@code{gnathtml}, to explicitly tell the Operating system where Perl
+is. The syntax of this line is :
+@smallexample
+#!full_path_name_to_perl
+@end smallexample
+
+@noindent
+Alternatively, you may run the script using the following command line:
+
+@smallexample
+$ perl gnathtml.pl [switches] files
+@end smallexample
+
+@ifset vms
+@node LSE
+@section LSE
+@findex LSE
+
+@noindent
+The GNAT distribution provides an Ada 95 template for the Digital Language
+Sensitive Editor (LSE), a component of DECset. In order to
+access it, invoke LSE with the qualifier /ENVIRONMENT=GNU:[LIB]ADA95.ENV.
+
+@node Profiling
+@section Profiling
+@findex PCA
+
+@noindent
+GNAT supports The Digital Performance Coverage Analyzer (PCA), a component
+of DECset. To use it proceed as outlined under ``HELP PCA'', except for running
+the collection phase with the /DEBUG qualifier.
+
+@smallexample
+$ GNAT MAKE /DEBUG <PROGRAM_NAME>
+$ DEFINE LIB$DEBUG PCA$COLLECTOR
+$ RUN/DEBUG <PROGRAM_NAME>
+@end smallexample
+@noindent
+@end ifset
+
+@node Running and Debugging Ada Programs
+@chapter Running and Debugging Ada Programs
+@cindex Debugging
+
+@noindent
+This chapter discusses how to debug Ada programs. An incorrect Ada program
+may be handled in three ways by the GNAT compiler:
+
+@enumerate
+@item
+The illegality may be a violation of the static semantics of Ada. In
+that case GNAT diagnoses the constructs in the program that are illegal.
+It is then a straightforward matter for the user to modify those parts of
+the program.
+
+@item
+The illegality may be a violation of the dynamic semantics of Ada. In
+that case the program compiles and executes, but may generate incorrect
+results, or may terminate abnormally with some exception.
+
+@item
+When presented with a program that contains convoluted errors, GNAT
+itself may terminate abnormally without providing full diagnostics on
+the incorrect user program.
+@end enumerate
+
+@menu
+* The GNAT Debugger GDB::
+* Running GDB::
+* Introduction to GDB Commands::
+* Using Ada Expressions::
+* Calling User-Defined Subprograms::
+* Using the Next Command in a Function::
+* Ada Exceptions::
+* Ada Tasks::
+* Debugging Generic Units::
+* GNAT Abnormal Termination or Failure to Terminate::
+* Naming Conventions for GNAT Source Files::
+* Getting Internal Debugging Information::
+* Stack Traceback::
+@end menu
+
+@cindex Debugger
+@findex gdb
+
+@node The GNAT Debugger GDB
+@section The GNAT Debugger GDB
+
+@noindent
+@code{GDB} is a general purpose, platform-independent debugger that
+can be used to debug mixed-language programs compiled with @code{GCC},
+and in particular is capable of debugging Ada programs compiled with
+GNAT. The latest versions of @code{GDB} are Ada-aware and can handle
+complex Ada data structures.
+
+The manual @cite{Debugging with GDB}
+@ifset vms
+, located in the GNU:[DOCS] directory,
+@end ifset
+contains full details on the usage of @code{GDB}, including a section on
+its usage on programs. This manual should be consulted for full
+details. The section that follows is a brief introduction to the
+philosophy and use of @code{GDB}.
+
+When GNAT programs are compiled, the compiler optionally writes debugging
+information into the generated object file, including information on
+line numbers, and on declared types and variables. This information is
+separate from the generated code. It makes the object files considerably
+larger, but it does not add to the size of the actual executable that
+will be loaded into memory, and has no impact on run-time performance. The
+generation of debug information is triggered by the use of the
+^-g^/DEBUG^ switch in the gcc or gnatmake command used to carry out
+the compilations. It is important to emphasize that the use of these
+options does not change the generated code.
+
+The debugging information is written in standard system formats that
+are used by many tools, including debuggers and profilers. The format
+of the information is typically designed to describe C types and
+semantics, but GNAT implements a translation scheme which allows full
+details about Ada types and variables to be encoded into these
+standard C formats. Details of this encoding scheme may be found in
+the file exp_dbug.ads in the GNAT source distribution. However, the
+details of this encoding are, in general, of no interest to a user,
+since @code{GDB} automatically performs the necessary decoding.
+
+When a program is bound and linked, the debugging information is
+collected from the object files, and stored in the executable image of
+the program. Again, this process significantly increases the size of
+the generated executable file, but it does not increase the size of
+the executable program itself. Furthermore, if this program is run in
+the normal manner, it runs exactly as if the debug information were
+not present, and takes no more actual memory.
+
+However, if the program is run under control of @code{GDB}, the
+debugger is activated. The image of the program is loaded, at which
+point it is ready to run. If a run command is given, then the program
+will run exactly as it would have if @code{GDB} were not present. This
+is a crucial part of the @code{GDB} design philosophy. @code{GDB} is
+entirely non-intrusive until a breakpoint is encountered. If no
+breakpoint is ever hit, the program will run exactly as it would if no
+debugger were present. When a breakpoint is hit, @code{GDB} accesses
+the debugging information and can respond to user commands to inspect
+variables, and more generally to report on the state of execution.
+
+@c **************
+@node Running GDB
+@section Running GDB
+
+@noindent
+The debugger can be launched directly and simply from @code{glide} or
+through its graphical interface: @code{gvd}. It can also be used
+directly in text mode. Here is described the basic use of @code{GDB}
+in text mode. All the commands described below can be used in the
+@code{gvd} console window even though there is usually other more
+graphical ways to achieve the same goals.
+
+@ifclear vms
+@noindent
+The command to run the graphical interface of the debugger is
+@smallexample
+$ gvd program
+@end smallexample
+@end ifclear
+
+@noindent
+The command to run @code{GDB} in text mode is
+
+@smallexample
+$ ^gdb program^$ GDB PROGRAM^
+@end smallexample
+
+@noindent
+where @code{^program^PROGRAM^} is the name of the executable file. This
+activates the debugger and results in a prompt for debugger commands.
+The simplest command is simply @code{run}, which causes the program to run
+exactly as if the debugger were not present. The following section
+describes some of the additional commands that can be given to @code{GDB}.
+
+
+@c *******************************
+@node Introduction to GDB Commands
+@section Introduction to GDB Commands
+
+@noindent
+@code{GDB} contains a large repertoire of commands. The manual
+@cite{Debugging with GDB}
+@ifset vms
+, located in the GNU:[DOCS] directory,
+@end ifset
+includes extensive documentation on the use
+of these commands, together with examples of their use. Furthermore,
+the command @var{help} invoked from within @code{GDB} activates a simple help
+facility which summarizes the available commands and their options.
+In this section we summarize a few of the most commonly
+used commands to give an idea of what @code{GDB} is about. You should create
+a simple program with debugging information and experiment with the use of
+these @code{GDB} commands on the program as you read through the
+following section.
+
+@table @code
+@item set args @var{arguments}
+The @var{arguments} list above is a list of arguments to be passed to
+the program on a subsequent run command, just as though the arguments
+had been entered on a normal invocation of the program. The @code{set args}
+command is not needed if the program does not require arguments.
+
+@item run
+The @code{run} command causes execution of the program to start from
+the beginning. If the program is already running, that is to say if
+you are currently positioned at a breakpoint, then a prompt will ask
+for confirmation that you want to abandon the current execution and
+restart.
+
+@item breakpoint @var{location}
+The breakpoint command sets a breakpoint, that is to say a point at which
+execution will halt and @code{GDB} will await further
+commands. @var{location} is
+either a line number within a file, given in the format @code{file:linenumber},
+or it is the name of a subprogram. If you request that a breakpoint be set on
+a subprogram that is overloaded, a prompt will ask you to specify on which of
+those subprograms you want to breakpoint. You can also
+specify that all of them should be breakpointed. If the program is run
+and execution encounters the breakpoint, then the program
+stops and @code{GDB} signals that the breakpoint was encountered by
+printing the line of code before which the program is halted.
+
+@item breakpoint exception @var{name}
+A special form of the breakpoint command which breakpoints whenever
+exception @var{name} is raised.
+If @var{name} is omitted,
+then a breakpoint will occur when any exception is raised.
+
+@item print @var{expression}
+This will print the value of the given expression. Most simple
+Ada expression formats are properly handled by @code{GDB}, so the expression
+can contain function calls, variables, operators, and attribute references.
+
+@item continue
+Continues execution following a breakpoint, until the next breakpoint or the
+termination of the program.
+
+@item step
+Executes a single line after a breakpoint. If the next statement
+is a subprogram call, execution continues into (the first statement of)
+the called subprogram.
+
+@item next
+Executes a single line. If this line is a subprogram call, executes and
+returns from the call.
+
+@item list
+Lists a few lines around the current source location. In practice, it
+is usually more convenient to have a separate edit window open with the
+relevant source file displayed. Successive applications of this command
+print subsequent lines. The command can be given an argument which is a
+line number, in which case it displays a few lines around the specified one.
+
+@item backtrace
+Displays a backtrace of the call chain. This command is typically
+used after a breakpoint has occurred, to examine the sequence of calls that
+leads to the current breakpoint. The display includes one line for each
+activation record (frame) corresponding to an active subprogram.
+
+@item up
+At a breakpoint, @code{GDB} can display the values of variables local
+to the current frame. The command @code{up} can be used to
+examine the contents of other active frames, by moving the focus up
+the stack, that is to say from callee to caller, one frame at a time.
+
+@item down
+Moves the focus of @code{GDB} down from the frame currently being
+examined to the frame of its callee (the reverse of the previous command),
+
+@item frame @var{n}
+Inspect the frame with the given number. The value 0 denotes the frame
+of the current breakpoint, that is to say the top of the call stack.
+
+@end table
+
+The above list is a very short introduction to the commands that
+@code{GDB} provides. Important additional capabilities, including conditional
+breakpoints, the ability to execute command sequences on a breakpoint,
+the ability to debug at the machine instruction level and many other
+features are described in detail in @cite{Debugging with GDB}.
+Note that most commands can be abbreviated
+(for example, c for continue, bt for backtrace).
+
+@node Using Ada Expressions
+@section Using Ada Expressions
+@cindex Ada expressions
+
+@noindent
+@code{GDB} supports a fairly large subset of Ada expression syntax, with some
+extensions. The philosophy behind the design of this subset is
+
+@itemize @bullet
+@item
+That @code{GDB} should provide basic literals and access to operations for
+arithmetic, dereferencing, field selection, indexing, and subprogram calls,
+leaving more sophisticated computations to subprograms written into the
+program (which therefore may be called from @code{GDB}).
+
+@item
+That type safety and strict adherence to Ada language restrictions
+are not particularly important to the @code{GDB} user.
+
+@item
+That brevity is important to the @code{GDB} user.
+@end itemize
+
+Thus, for brevity, the debugger acts as if there were
+implicit @code{with} and @code{use} clauses in effect for all user-written
+packages, thus making it unnecessary to fully qualify most names with
+their packages, regardless of context. Where this causes ambiguity,
+@code{GDB} asks the user's intent.
+
+For details on the supported Ada syntax, see @cite{Debugging with GDB}.
+
+@node Calling User-Defined Subprograms
+@section Calling User-Defined Subprograms
+
+@noindent
+An important capability of @code{GDB} is the ability to call user-defined
+subprograms while debugging. This is achieved simply by entering
+a subprogram call statement in the form:
+
+@smallexample
+call subprogram-name (parameters)
+@end smallexample
+
+@noindent
+The keyword @code{call} can be omitted in the normal case where the
+@code{subprogram-name} does not coincide with any of the predefined
+@code{GDB} commands.
+
+The effect is to invoke the given subprogram, passing it the
+list of parameters that is supplied. The parameters can be expressions and
+can include variables from the program being debugged. The
+subprogram must be defined
+at the library level within your program, and @code{GDB} will call the
+subprogram within the environment of your program execution (which
+means that the subprogram is free to access or even modify variables
+within your program).
+
+The most important use of this facility is in allowing the inclusion of
+debugging routines that are tailored to particular data structures
+in your program. Such debugging routines can be written to provide a suitably
+high-level description of an abstract type, rather than a low-level dump
+of its physical layout. After all, the standard
+@code{GDB print} command only knows the physical layout of your
+types, not their abstract meaning. Debugging routines can provide information
+at the desired semantic level and are thus enormously useful.
+
+For example, when debugging GNAT itself, it is crucial to have access to
+the contents of the tree nodes used to represent the program internally.
+But tree nodes are represented simply by an integer value (which in turn
+is an index into a table of nodes).
+Using the @code{print} command on a tree node would simply print this integer
+value, which is not very useful. But the PN routine (defined in file
+treepr.adb in the GNAT sources) takes a tree node as input, and displays
+a useful high level representation of the tree node, which includes the
+syntactic category of the node, its position in the source, the integers
+that denote descendant nodes and parent node, as well as varied
+semantic information. To study this example in more detail, you might want to
+look at the body of the PN procedure in the stated file.
+
+@node Using the Next Command in a Function
+@section Using the Next Command in a Function
+
+@noindent
+When you use the @code{next} command in a function, the current source
+location will advance to the next statement as usual. A special case
+arises in the case of a @code{return} statement.
+
+Part of the code for a return statement is the ``epilog'' of the function.
+This is the code that returns to the caller. There is only one copy of
+this epilog code, and it is typically associated with the last return
+statement in the function if there is more than one return. In some
+implementations, this epilog is associated with the first statement
+of the function.
+
+The result is that if you use the @code{next} command from a return
+statement that is not the last return statement of the function you
+may see a strange apparent jump to the last return statement or to
+the start of the function. You should simply ignore this odd jump.
+The value returned is always that from the first return statement
+that was stepped through.
+
+@node Ada Exceptions
+@section Breaking on Ada Exceptions
+@cindex Exceptions
+
+@noindent
+You can set breakpoints that trip when your program raises
+selected exceptions.
+
+@table @code
+@item break exception
+Set a breakpoint that trips whenever (any task in the) program raises
+any exception.
+
+@item break exception @var{name}
+Set a breakpoint that trips whenever (any task in the) program raises
+the exception @var{name}.
+
+@item break exception unhandled
+Set a breakpoint that trips whenever (any task in the) program raises an
+exception for which there is no handler.
+
+@item info exceptions
+@itemx info exceptions @var{regexp}
+The @code{info exceptions} command permits the user to examine all defined
+exceptions within Ada programs. With a regular expression, @var{regexp}, as
+argument, prints out only those exceptions whose name matches @var{regexp}.
+@end table
+
+@node Ada Tasks
+@section Ada Tasks
+@cindex Tasks
+
+@noindent
+@code{GDB} allows the following task-related commands:
+
+@table @code
+@item info tasks
+This command shows a list of current Ada tasks, as in the following example:
+
+@smallexample
+@iftex
+@leftskip=0cm
+@end iftex
+(gdb) info tasks
+ ID TID P-ID Thread Pri State Name
+ 1 8088000 0 807e000 15 Child Activation Wait main_task
+ 2 80a4000 1 80ae000 15 Accept/Select Wait b
+ 3 809a800 1 80a4800 15 Child Activation Wait a
+* 4 80ae800 3 80b8000 15 Running c
+@end smallexample
+
+@noindent
+In this listing, the asterisk before the first task indicates it to be the
+currently running task. The first column lists the task ID that is used
+to refer to tasks in the following commands.
+
+@item break @var{linespec} task @var{taskid}
+@itemx break @var{linespec} task @var{taskid} if @dots{}
+@cindex Breakpoints and tasks
+These commands are like the @code{break @dots{} thread @dots{}}.
+@var{linespec} specifies source lines.
+
+Use the qualifier @samp{task @var{taskid}} with a breakpoint command
+to specify that you only want @code{GDB} to stop the program when a
+particular Ada task reaches this breakpoint. @var{taskid} is one of the
+numeric task identifiers assigned by @code{GDB}, shown in the first
+column of the @samp{info tasks} display.
+
+If you do not specify @samp{task @var{taskid}} when you set a
+breakpoint, the breakpoint applies to @emph{all} tasks of your
+program.
+
+You can use the @code{task} qualifier on conditional breakpoints as
+well; in this case, place @samp{task @var{taskid}} before the
+breakpoint condition (before the @code{if}).
+
+@item task @var{taskno}
+@cindex Task switching
+
+This command allows to switch to the task referred by @var{taskno}. In
+particular, This allows to browse the backtrace of the specified
+task. It is advised to switch back to the original task before
+continuing execution otherwise the scheduling of the program may be
+perturbated.
+@end table
+
+@noindent
+For more detailed information on the tasking support,
+see @cite{Debugging with GDB}.
+
+@node Debugging Generic Units
+@section Debugging Generic Units
+@cindex Debugging Generic Units
+@cindex Generics
+
+@noindent
+GNAT always uses code expansion for generic instantiation. This means that
+each time an instantiation occurs, a complete copy of the original code is
+made, with appropriate substitutions of formals by actuals.
+
+It is not possible to refer to the original generic entities in
+@code{GDB}, but it is always possible to debug a particular instance of
+a generic, by using the appropriate expanded names. For example, if we have
+
+@smallexample @c ada
+@group
+@cartouche
+procedure g is
+
+ generic package k is
+ procedure kp (v1 : in out integer);
+ end k;
+
+ package body k is
+ procedure kp (v1 : in out integer) is
+ begin
+ v1 := v1 + 1;
+ end kp;
+ end k;
+
+ package k1 is new k;
+ package k2 is new k;
+
+ var : integer := 1;
+
+begin
+ k1.kp (var);
+ k2.kp (var);
+ k1.kp (var);
+ k2.kp (var);
+end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Then to break on a call to procedure kp in the k2 instance, simply
+use the command:
+
+@smallexample
+(gdb) break g.k2.kp
+@end smallexample
+
+@noindent
+When the breakpoint occurs, you can step through the code of the
+instance in the normal manner and examine the values of local variables, as for
+other units.
+
+@node GNAT Abnormal Termination or Failure to Terminate
+@section GNAT Abnormal Termination or Failure to Terminate
+@cindex GNAT Abnormal Termination or Failure to Terminate
+
+@noindent
+When presented with programs that contain serious errors in syntax
+or semantics,
+GNAT may on rare occasions experience problems in operation, such
+as aborting with a
+segmentation fault or illegal memory access, raising an internal
+exception, terminating abnormally, or failing to terminate at all.
+In such cases, you can activate
+various features of GNAT that can help you pinpoint the construct in your
+program that is the likely source of the problem.
+
+The following strategies are presented in increasing order of
+difficulty, corresponding to your experience in using GNAT and your
+familiarity with compiler internals.
+
+@enumerate
+@item
+Run @code{gcc} with the @option{-gnatf}. This first
+switch causes all errors on a given line to be reported. In its absence,
+only the first error on a line is displayed.
+
+The @option{-gnatdO} switch causes errors to be displayed as soon as they
+are encountered, rather than after compilation is terminated. If GNAT
+terminates prematurely or goes into an infinite loop, the last error
+message displayed may help to pinpoint the culprit.
+
+@item
+Run @code{gcc} with the @option{^-v (verbose)^/VERBOSE^} switch. In this mode,
+@code{gcc} produces ongoing information about the progress of the
+compilation and provides the name of each procedure as code is
+generated. This switch allows you to find which Ada procedure was being
+compiled when it encountered a code generation problem.
+
+@item
+@cindex @option{-gnatdc} switch
+Run @code{gcc} with the @option{-gnatdc} switch. This is a GNAT specific
+switch that does for the front-end what @option{^-v^VERBOSE^} does
+for the back end. The system prints the name of each unit,
+either a compilation unit or nested unit, as it is being analyzed.
+@item
+Finally, you can start
+@code{gdb} directly on the @code{gnat1} executable. @code{gnat1} is the
+front-end of GNAT, and can be run independently (normally it is just
+called from @code{gcc}). You can use @code{gdb} on @code{gnat1} as you
+would on a C program (but @pxref{The GNAT Debugger GDB} for caveats). The
+@code{where} command is the first line of attack; the variable
+@code{lineno} (seen by @code{print lineno}), used by the second phase of
+@code{gnat1} and by the @code{gcc} backend, indicates the source line at
+which the execution stopped, and @code{input_file name} indicates the name of
+the source file.
+@end enumerate
+
+@node Naming Conventions for GNAT Source Files
+@section Naming Conventions for GNAT Source Files
+
+@noindent
+In order to examine the workings of the GNAT system, the following
+brief description of its organization may be helpful:
+
+@itemize @bullet
+@item
+Files with prefix @file{^sc^SC^} contain the lexical scanner.
+
+@item
+All files prefixed with @file{^par^PAR^} are components of the parser. The
+numbers correspond to chapters of the Ada 95 Reference Manual. For example,
+parsing of select statements can be found in @file{par-ch9.adb}.
+
+@item
+All files prefixed with @file{^sem^SEM^} perform semantic analysis. The
+numbers correspond to chapters of the Ada standard. For example, all
+issues involving context clauses can be found in @file{sem_ch10.adb}. In
+addition, some features of the language require sufficient special processing
+to justify their own semantic files: sem_aggr for aggregates, sem_disp for
+dynamic dispatching, etc.
+
+@item
+All files prefixed with @file{^exp^EXP^} perform normalization and
+expansion of the intermediate representation (abstract syntax tree, or AST).
+these files use the same numbering scheme as the parser and semantics files.
+For example, the construction of record initialization procedures is done in
+@file{exp_ch3.adb}.
+
+@item
+The files prefixed with @file{^bind^BIND^} implement the binder, which
+verifies the consistency of the compilation, determines an order of
+elaboration, and generates the bind file.
+
+@item
+The files @file{atree.ads} and @file{atree.adb} detail the low-level
+data structures used by the front-end.
+
+@item
+The files @file{sinfo.ads} and @file{sinfo.adb} detail the structure of
+the abstract syntax tree as produced by the parser.
+
+@item
+The files @file{einfo.ads} and @file{einfo.adb} detail the attributes of
+all entities, computed during semantic analysis.
+
+@item
+Library management issues are dealt with in files with prefix
+@file{^lib^LIB^}.
+
+@item
+@findex Ada
+@cindex Annex A
+Ada files with the prefix @file{^a-^A-^} are children of @code{Ada}, as
+defined in Annex A.
+
+@item
+@findex Interfaces
+@cindex Annex B
+Files with prefix @file{^i-^I-^} are children of @code{Interfaces}, as
+defined in Annex B.
+
+@item
+@findex System
+Files with prefix @file{^s-^S-^} are children of @code{System}. This includes
+both language-defined children and GNAT run-time routines.
+
+@item
+@findex GNAT
+Files with prefix @file{^g-^G-^} are children of @code{GNAT}. These are useful
+general-purpose packages, fully documented in their specifications. All
+the other @file{.c} files are modifications of common @code{gcc} files.
+@end itemize
+
+@node Getting Internal Debugging Information
+@section Getting Internal Debugging Information
+
+@noindent
+Most compilers have internal debugging switches and modes. GNAT
+does also, except GNAT internal debugging switches and modes are not
+secret. A summary and full description of all the compiler and binder
+debug flags are in the file @file{debug.adb}. You must obtain the
+sources of the compiler to see the full detailed effects of these flags.
+
+The switches that print the source of the program (reconstructed from
+the internal tree) are of general interest for user programs, as are the
+options to print
+the full internal tree, and the entity table (the symbol table
+information). The reconstructed source provides a readable version of the
+program after the front-end has completed analysis and expansion,
+and is useful when studying the performance of specific constructs.
+For example, constraint checks are indicated, complex aggregates
+are replaced with loops and assignments, and tasking primitives
+are replaced with run-time calls.
+
+@node Stack Traceback
+@section Stack Traceback
+@cindex traceback
+@cindex stack traceback
+@cindex stack unwinding
+
+@noindent
+Traceback is a mechanism to display the sequence of subprogram calls that
+leads to a specified execution point in a program. Often (but not always)
+the execution point is an instruction at which an exception has been raised.
+This mechanism is also known as @i{stack unwinding} because it obtains
+its information by scanning the run-time stack and recovering the activation
+records of all active subprograms. Stack unwinding is one of the most
+important tools for program debugging.
+
+The first entry stored in traceback corresponds to the deepest calling level,
+that is to say the subprogram currently executing the instruction
+from which we want to obtain the traceback.
+
+Note that there is no runtime performance penalty when stack traceback
+is enabled, and no exception is raised during program execution.
+
+@menu
+* Non-Symbolic Traceback::
+* Symbolic Traceback::
+@end menu
+
+@node Non-Symbolic Traceback
+@subsection Non-Symbolic Traceback
+@cindex traceback, non-symbolic
+
+@noindent
+Note: this feature is not supported on all platforms. See
+@file{GNAT.Traceback spec in g-traceb.ads} for a complete list of supported
+platforms.
+
+@menu
+* Tracebacks From an Unhandled Exception::
+* Tracebacks From Exception Occurrences (non-symbolic)::
+* Tracebacks From Anywhere in a Program (non-symbolic)::
+@end menu
+
+@node Tracebacks From an Unhandled Exception
+@subsubsection Tracebacks From an Unhandled Exception
+
+@noindent
+A runtime non-symbolic traceback is a list of addresses of call instructions.
+To enable this feature you must use the @option{-E}
+@code{gnatbind}'s option. With this option a stack traceback is stored as part
+of exception information. You can retrieve this information using the
+@code{addr2line} tool.
+
+Here is a simple example:
+
+@smallexample @c ada
+@cartouche
+procedure STB is
+
+ procedure P1 is
+ begin
+ raise Constraint_Error;
+ end P1;
+
+ procedure P2 is
+ begin
+ P1;
+ end P2;
+
+begin
+ P2;
+end STB;
+@end cartouche
+@end smallexample
+
+@smallexample
+$ gnatmake stb -bargs -E
+$ stb
+
+Execution terminated by unhandled exception
+Exception name: CONSTRAINT_ERROR
+Message: stb.adb:5
+Call stack traceback locations:
+0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4
+@end smallexample
+
+@noindent
+As we see the traceback lists a sequence of addresses for the unhandled
+exception @code{CONSTRAINT_ERROR} raised in procedure P1. It is easy to
+guess that this exception come from procedure P1. To translate these
+addresses into the source lines where the calls appear, the
+@code{addr2line} tool, described below, is invaluable. The use of this tool
+requires the program to be compiled with debug information.
+
+@smallexample
+$ gnatmake -g stb -bargs -E
+$ stb
+
+Execution terminated by unhandled exception
+Exception name: CONSTRAINT_ERROR
+Message: stb.adb:5
+Call stack traceback locations:
+0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4
+
+$ addr2line --exe=stb 0x401373 0x40138b 0x40139c 0x401335 0x4011c4
+ 0x4011f1 0x77e892a4
+
+00401373 at d:/stb/stb.adb:5
+0040138B at d:/stb/stb.adb:10
+0040139C at d:/stb/stb.adb:14
+00401335 at d:/stb/b~stb.adb:104
+004011C4 at /build/.../crt1.c:200
+004011F1 at /build/.../crt1.c:222
+77E892A4 in ?? at ??:0
+@end smallexample
+
+@noindent
+The @code{addr2line} tool has several other useful options:
+
+@table @code
+@item --functions
+to get the function name corresponding to any location
+
+@item --demangle=gnat
+to use the gnat decoding mode for the function names. Note that
+for binutils version 2.9.x the option is simply @option{--demangle}.
+@end table
+
+@smallexample
+$ addr2line --exe=stb --functions --demangle=gnat 0x401373 0x40138b
+ 0x40139c 0x401335 0x4011c4 0x4011f1
+
+00401373 in stb.p1 at d:/stb/stb.adb:5
+0040138B in stb.p2 at d:/stb/stb.adb:10
+0040139C in stb at d:/stb/stb.adb:14
+00401335 in main at d:/stb/b~stb.adb:104
+004011C4 in <__mingw_CRTStartup> at /build/.../crt1.c:200
+004011F1 in <mainCRTStartup> at /build/.../crt1.c:222
+@end smallexample
+
+@noindent
+From this traceback we can see that the exception was raised in
+@file{stb.adb} at line 5, which was reached from a procedure call in
+@file{stb.adb} at line 10, and so on. The @file{b~std.adb} is the binder file,
+which contains the call to the main program.
+@pxref{Running gnatbind}. The remaining entries are assorted runtime routines,
+and the output will vary from platform to platform.
+
+It is also possible to use @code{GDB} with these traceback addresses to debug
+the program. For example, we can break at a given code location, as reported
+in the stack traceback:
+
+@smallexample
+$ gdb -nw stb
+@ifclear vms
+@noindent
+Furthermore, this feature is not implemented inside Windows DLL. Only
+the non-symbolic traceback is reported in this case.
+@end ifclear
+
+(gdb) break *0x401373
+Breakpoint 1 at 0x401373: file stb.adb, line 5.
+@end smallexample
+
+@noindent
+It is important to note that the stack traceback addresses
+do not change when debug information is included. This is particularly useful
+because it makes it possible to release software without debug information (to
+minimize object size), get a field report that includes a stack traceback
+whenever an internal bug occurs, and then be able to retrieve the sequence
+of calls with the same program compiled with debug information.
+
+@node Tracebacks From Exception Occurrences (non-symbolic)
+@subsubsection Tracebacks From Exception Occurrences
+
+@noindent
+Non-symbolic tracebacks are obtained by using the @option{-E} binder argument.
+The stack traceback is attached to the exception information string, and can
+be retrieved in an exception handler within the Ada program, by means of the
+Ada95 facilities defined in @code{Ada.Exceptions}. Here is a simple example:
+
+@smallexample @c ada
+with Ada.Text_IO;
+with Ada.Exceptions;
+
+procedure STB is
+
+ use Ada;
+ use Ada.Exceptions;
+
+ procedure P1 is
+ K : Positive := 1;
+ begin
+ K := K - 1;
+ exception
+ when E : others =>
+ Text_IO.Put_Line (Exception_Information (E));
+ end P1;
+
+ procedure P2 is
+ begin
+ P1;
+ end P2;
+
+begin
+ P2;
+end STB;
+@end smallexample
+
+@noindent
+This program will output:
+
+@smallexample
+$ stb
+
+Exception name: CONSTRAINT_ERROR
+Message: stb.adb:12
+Call stack traceback locations:
+0x4015e4 0x401633 0x401644 0x401461 0x4011c4 0x4011f1 0x77e892a4
+@end smallexample
+
+@node Tracebacks From Anywhere in a Program (non-symbolic)
+@subsubsection Tracebacks From Anywhere in a Program
+
+@noindent
+It is also possible to retrieve a stack traceback from anywhere in a
+program. For this you need to
+use the @code{GNAT.Traceback} API. This package includes a procedure called
+@code{Call_Chain} that computes a complete stack traceback, as well as useful
+display procedures described below. It is not necessary to use the
+@option{-E gnatbind} option in this case, because the stack traceback mechanism
+is invoked explicitly.
+
+@noindent
+In the following example we compute a traceback at a specific location in
+the program, and we display it using @code{GNAT.Debug_Utilities.Image} to
+convert addresses to strings:
+
+@smallexample @c ada
+with Ada.Text_IO;
+with GNAT.Traceback;
+with GNAT.Debug_Utilities;
+
+procedure STB is
+
+ use Ada;
+ use GNAT;
+ use GNAT.Traceback;
+
+ procedure P1 is
+ TB : Tracebacks_Array (1 .. 10);
+ -- We are asking for a maximum of 10 stack frames.
+ Len : Natural;
+ -- Len will receive the actual number of stack frames returned.
+ begin
+ Call_Chain (TB, Len);
+
+ Text_IO.Put ("In STB.P1 : ");
+
+ for K in 1 .. Len loop
+ Text_IO.Put (Debug_Utilities.Image (TB (K)));
+ Text_IO.Put (' ');
+ end loop;
+
+ Text_IO.New_Line;
+ end P1;
+
+ procedure P2 is
+ begin
+ P1;
+ end P2;
+
+begin
+ P2;
+end STB;
+@end smallexample
+
+@smallexample
+$ gnatmake -g stb
+$ stb
+
+In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
+16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4#
+@end smallexample
+
+@noindent
+You can then get further information by invoking the @code{addr2line}
+tool as described earlier (note that the hexadecimal addresses
+need to be specified in C format, with a leading ``0x'').
+
+
+@node Symbolic Traceback
+@subsection Symbolic Traceback
+@cindex traceback, symbolic
+
+@noindent
+A symbolic traceback is a stack traceback in which procedure names are
+associated with each code location.
+
+@noindent
+Note that this feature is not supported on all platforms. See
+@file{GNAT.Traceback.Symbolic spec in g-trasym.ads} for a complete
+list of currently supported platforms.
+
+@noindent
+Note that the symbolic traceback requires that the program be compiled
+with debug information. If it is not compiled with debug information
+only the non-symbolic information will be valid.
+
+@menu
+* Tracebacks From Exception Occurrences (symbolic)::
+* Tracebacks From Anywhere in a Program (symbolic)::
+@end menu
+
+@node Tracebacks From Exception Occurrences (symbolic)
+@subsubsection Tracebacks From Exception Occurrences
+
+@smallexample @c ada
+with Ada.Text_IO;
+with GNAT.Traceback.Symbolic;
+
+procedure STB is
+
+ procedure P1 is
+ begin
+ raise Constraint_Error;
+ end P1;
+
+ procedure P2 is
+ begin
+ P1;
+ end P2;
+
+ procedure P3 is
+ begin
+ P2;
+ end P3;
+
+begin
+ P3;
+exception
+ when E : others =>
+ Ada.Text_IO.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
+end STB;
+@end smallexample
+
+@smallexample
+$ gnatmake -g .\stb -bargs -E -largs -lgnat -laddr2line -lintl
+$ stb
+
+0040149F in stb.p1 at stb.adb:8
+004014B7 in stb.p2 at stb.adb:13
+004014CF in stb.p3 at stb.adb:18
+004015DD in ada.stb at stb.adb:22
+00401461 in main at b~stb.adb:168
+004011C4 in __mingw_CRTStartup at crt1.c:200
+004011F1 in mainCRTStartup at crt1.c:222
+77E892A4 in ?? at ??:0
+@end smallexample
+
+@noindent
+In the above example the ``.\'' syntax in the @command{gnatmake} command
+is currently required by @command{addr2line} for files that are in
+the current working directory.
+Moreover, the exact sequence of linker options may vary from platform
+to platform.
+The above @option{-largs} section is for Windows platforms. By contrast,
+under Unix there is no need for the @option{-largs} section.
+Differences across platforms are due to details of linker implementation.
+
+@node Tracebacks From Anywhere in a Program (symbolic)
+@subsubsection Tracebacks From Anywhere in a Program
+
+@noindent
+It is possible to get a symbolic stack traceback
+from anywhere in a program, just as for non-symbolic tracebacks.
+The first step is to obtain a non-symbolic
+traceback, and then call @code{Symbolic_Traceback} to compute the symbolic
+information. Here is an example:
+
+@smallexample @c ada
+with Ada.Text_IO;
+with GNAT.Traceback;
+with GNAT.Traceback.Symbolic;
+
+procedure STB is
+
+ use Ada;
+ use GNAT.Traceback;
+ use GNAT.Traceback.Symbolic;
+
+ procedure P1 is
+ TB : Tracebacks_Array (1 .. 10);
+ -- We are asking for a maximum of 10 stack frames.
+ Len : Natural;
+ -- Len will receive the actual number of stack frames returned.
+ begin
+ Call_Chain (TB, Len);
+ Text_IO.Put_Line (Symbolic_Traceback (TB (1 .. Len)));
+ end P1;
+
+ procedure P2 is
+ begin
+ P1;
+ end P2;
+
+begin
+ P2;
+end STB;
+@end smallexample
+
+@ifset vms
+@node Compatibility with DEC Ada
+@chapter Compatibility with DEC Ada
+@cindex Compatibility
+
+@noindent
+This section of the manual compares DEC Ada for OpenVMS Alpha and GNAT
+OpenVMS Alpha. GNAT achieves a high level of compatibility
+with DEC Ada, and it should generally be straightforward to port code
+from the DEC Ada environment to GNAT. However, there are a few language
+and implementation differences of which the user must be aware. These
+differences are discussed in this section. In
+addition, the operating environment and command structure for the
+compiler are different, and these differences are also discussed.
+
+Note that this discussion addresses specifically the implementation
+of Ada 83 for DIGITAL OpenVMS Alpha Systems. In cases where the implementation
+of DEC Ada differs between OpenVMS Alpha Systems and OpenVMS VAX Systems,
+GNAT always follows the Alpha implementation.
+
+@menu
+* Ada 95 Compatibility::
+* Differences in the Definition of Package System::
+* Language-Related Features::
+* The Package STANDARD::
+* The Package SYSTEM::
+* Tasking and Task-Related Features::
+* Implementation of Tasks in DEC Ada for OpenVMS Alpha Systems::
+* Pragmas and Pragma-Related Features::
+* Library of Predefined Units::
+* Bindings::
+* Main Program Definition::
+* Implementation-Defined Attributes::
+* Compiler and Run-Time Interfacing::
+* Program Compilation and Library Management::
+* Input-Output::
+* Implementation Limits::
+* Tools::
+@end menu
+
+@node Ada 95 Compatibility
+@section Ada 95 Compatibility
+
+@noindent
+GNAT is an Ada 95 compiler, and DEC Ada is an Ada 83
+compiler. Ada 95 is almost completely upwards compatible
+with Ada 83, and therefore Ada 83 programs will compile
+and run under GNAT with
+no changes or only minor changes. The Ada 95 Reference
+Manual (ANSI/ISO/IEC-8652:1995) provides details on specific
+incompatibilities.
+
+GNAT provides the switch /83 on the GNAT COMPILE command,
+as well as the pragma ADA_83, to force the compiler to
+operate in Ada 83 mode. This mode does not guarantee complete
+conformance to Ada 83, but in practice is sufficient to
+eliminate most sources of incompatibilities.
+In particular, it eliminates the recognition of the
+additional Ada 95 keywords, so that their use as identifiers
+in Ada83 program is legal, and handles the cases of packages
+with optional bodies, and generics that instantiate unconstrained
+types without the use of @code{(<>)}.
+
+@node Differences in the Definition of Package System
+@section Differences in the Definition of Package System
+
+@noindent
+Both the Ada 95 and Ada 83 reference manuals permit a compiler to add
+implementation-dependent declarations to package System. In normal mode,
+GNAT does not take advantage of this permission, and the version of System
+provided by GNAT exactly matches that in the Ada 95 Reference Manual.
+
+However, DEC Ada adds an extensive set of declarations to package System,
+as fully documented in the DEC Ada manuals. To minimize changes required
+for programs that make use of these extensions, GNAT provides the pragma
+Extend_System for extending the definition of package System. By using:
+
+@smallexample @c ada
+@group
+@cartouche
+pragma Extend_System (Aux_DEC);
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+The set of definitions in System is extended to include those in package
+@code{System.Aux_DEC}.
+These definitions are incorporated directly into package
+System, as though they had been declared there in the first place. For a
+list of the declarations added, see the specification of this package,
+which can be found in the file @code{s-auxdec.ads} in the GNAT library.
+The pragma Extend_System is a configuration pragma, which means that
+it can be placed in the file @file{gnat.adc}, so that it will automatically
+apply to all subsequent compilations. See the section on Configuration
+Pragmas for further details.
+
+An alternative approach that avoids the use of the non-standard
+Extend_System pragma is to add a context clause to the unit that
+references these facilities:
+
+@smallexample @c ada
+@group
+@cartouche
+with System.Aux_DEC;
+use System.Aux_DEC;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+The effect is not quite semantically identical to incorporating
+the declarations directly into package @code{System},
+but most programs will not notice a difference
+unless they use prefix notation (e.g. @code{System.Integer_8})
+to reference the
+entities directly in package @code{System}.
+For units containing such references,
+the prefixes must either be removed, or the pragma @code{Extend_System}
+must be used.
+
+@node Language-Related Features
+@section Language-Related Features
+
+@noindent
+The following sections highlight differences in types,
+representations of types, operations, alignment, and
+related topics.
+
+@menu
+* Integer Types and Representations::
+* Floating-Point Types and Representations::
+* Pragmas Float_Representation and Long_Float::
+* Fixed-Point Types and Representations::
+* Record and Array Component Alignment::
+* Address Clauses::
+* Other Representation Clauses::
+@end menu
+
+@node Integer Types and Representations
+@subsection Integer Types and Representations
+
+@noindent
+The set of predefined integer types is identical in DEC Ada and GNAT.
+Furthermore the representation of these integer types is also identical,
+including the capability of size clauses forcing biased representation.
+
+In addition,
+DEC Ada for OpenVMS Alpha systems has defined the
+following additional integer types in package System:
+
+@itemize @bullet
+
+@item
+INTEGER_8
+
+@item
+INTEGER_16
+
+@item
+INTEGER_32
+
+@item
+INTEGER_64
+
+@item
+LARGEST_INTEGER
+@end itemize
+
+@noindent
+When using GNAT, the first four of these types may be obtained from the
+standard Ada 95 package @code{Interfaces}.
+Alternatively, by use of the pragma
+@code{Extend_System}, identical
+declarations can be referenced directly in package @code{System}.
+On both GNAT and DEC Ada, the maximum integer size is 64 bits.
+
+@node Floating-Point Types and Representations
+@subsection Floating-Point Types and Representations
+@cindex Floating-Point types
+
+@noindent
+The set of predefined floating-point types is identical in DEC Ada and GNAT.
+Furthermore the representation of these floating-point
+types is also identical. One important difference is that the default
+representation for DEC Ada is VAX_Float, but the default representation
+for GNAT is IEEE.
+
+Specific types may be declared to be VAX_Float or IEEE, using the pragma
+@code{Float_Representation} as described in the DEC Ada documentation.
+For example, the declarations:
+
+@smallexample @c ada
+@group
+@cartouche
+type F_Float is digits 6;
+pragma Float_Representation (VAX_Float, F_Float);
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+declare a type F_Float that will be represented in VAX_Float format.
+This set of declarations actually appears in System.Aux_DEC, which provides
+the full set of additional floating-point declarations provided in
+the DEC Ada version of package
+System. This and similar declarations may be accessed in a user program
+by using pragma @code{Extend_System}. The use of this
+pragma, and the related pragma @code{Long_Float} is described in further
+detail in the following section.
+
+@node Pragmas Float_Representation and Long_Float
+@subsection Pragmas Float_Representation and Long_Float
+
+@noindent
+DEC Ada provides the pragma @code{Float_Representation}, which
+acts as a program library switch to allow control over
+the internal representation chosen for the predefined
+floating-point types declared in the package @code{Standard}.
+The format of this pragma is as follows:
+
+@smallexample
+@group
+@cartouche
+@b{pragma} @code{Float_Representation}(VAX_Float | IEEE_Float);
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+This pragma controls the representation of floating-point
+types as follows:
+
+@itemize @bullet
+@item
+@code{VAX_Float} specifies that floating-point
+types are represented by default with the VAX hardware types
+F-floating, D-floating, G-floating. Note that the H-floating
+type is available only on DIGITAL Vax systems, and is not available
+in either DEC Ada or GNAT for Alpha systems.
+
+@item
+@code{IEEE_Float} specifies that floating-point
+types are represented by default with the IEEE single and
+double floating-point types.
+@end itemize
+
+@noindent
+GNAT provides an identical implementation of the pragma
+@code{Float_Representation}, except that it functions as a
+configuration pragma, as defined by Ada 95. Note that the
+notion of configuration pragma corresponds closely to the
+DEC Ada notion of a program library switch.
+
+When no pragma is used in GNAT, the default is IEEE_Float, which is different
+from DEC Ada 83, where the default is VAX_Float. In addition, the
+predefined libraries in GNAT are built using IEEE_Float, so it is not
+advisable to change the format of numbers passed to standard library
+routines, and if necessary explicit type conversions may be needed.
+
+The use of IEEE_Float is recommended in GNAT since it is more efficient,
+and (given that it conforms to an international standard) potentially more
+portable. The situation in which VAX_Float may be useful is in interfacing
+to existing code and data that expects the use of VAX_Float. There are
+two possibilities here. If the requirement for the use of VAX_Float is
+localized, then the best approach is to use the predefined VAX_Float
+types in package @code{System}, as extended by
+@code{Extend_System}. For example, use @code{System.F_Float}
+to specify the 32-bit @code{F-Float} format.
+
+Alternatively, if an entire program depends heavily on the use of
+the @code{VAX_Float} and in particular assumes that the types in
+package @code{Standard} are in @code{Vax_Float} format, then it
+may be desirable to reconfigure GNAT to assume Vax_Float by default.
+This is done by using the GNAT LIBRARY command to rebuild the library, and
+then using the general form of the @code{Float_Representation}
+pragma to ensure that this default format is used throughout.
+The form of the GNAT LIBRARY command is:
+
+@smallexample
+GNAT LIBRARY /CONFIG=@i{file} /CREATE=@i{directory}
+@end smallexample
+
+@noindent
+where @i{file} contains the new configuration pragmas
+and @i{directory} is the directory to be created to contain
+the new library.
+
+@noindent
+On OpenVMS systems, DEC Ada provides the pragma @code{Long_Float}
+to allow control over the internal representation chosen
+for the predefined type @code{Long_Float} and for floating-point
+type declarations with digits specified in the range 7 .. 15.
+The format of this pragma is as follows:
+
+@smallexample @c ada
+@cartouche
+pragma Long_Float (D_FLOAT | G_FLOAT);
+@end cartouche
+@end smallexample
+
+@node Fixed-Point Types and Representations
+@subsection Fixed-Point Types and Representations
+
+@noindent
+On DEC Ada for OpenVMS Alpha systems, rounding is
+away from zero for both positive and negative numbers.
+Therefore, +0.5 rounds to 1 and -0.5 rounds to -1.
+
+On GNAT for OpenVMS Alpha, the results of operations
+on fixed-point types are in accordance with the Ada 95
+rules. In particular, results of operations on decimal
+fixed-point types are truncated.
+
+@node Record and Array Component Alignment
+@subsection Record and Array Component Alignment
+
+@noindent
+On DEC Ada for OpenVMS Alpha, all non composite components
+are aligned on natural boundaries. For example, 1-byte
+components are aligned on byte boundaries, 2-byte
+components on 2-byte boundaries, 4-byte components on 4-byte
+byte boundaries, and so on. The OpenVMS Alpha hardware
+runs more efficiently with naturally aligned data.
+
+ON GNAT for OpenVMS Alpha, alignment rules are compatible
+with DEC Ada for OpenVMS Alpha.
+
+@node Address Clauses
+@subsection Address Clauses
+
+@noindent
+In DEC Ada and GNAT, address clauses are supported for
+objects and imported subprograms.
+The predefined type @code{System.Address} is a private type
+in both compilers, with the same representation (it is simply
+a machine pointer). Addition, subtraction, and comparison
+operations are available in the standard Ada 95 package
+@code{System.Storage_Elements}, or in package @code{System}
+if it is extended to include @code{System.Aux_DEC} using a
+pragma @code{Extend_System} as previously described.
+
+Note that code that with's both this extended package @code{System}
+and the package @code{System.Storage_Elements} should not @code{use}
+both packages, or ambiguities will result. In general it is better
+not to mix these two sets of facilities. The Ada 95 package was
+designed specifically to provide the kind of features that DEC Ada
+adds directly to package @code{System}.
+
+GNAT is compatible with DEC Ada in its handling of address
+clauses, except for some limitations in
+the form of address clauses for composite objects with
+initialization. Such address clauses are easily replaced
+by the use of an explicitly-defined constant as described
+in the Ada 95 Reference Manual (13.1(22)). For example, the sequence
+of declarations:
+
+@smallexample @c ada
+@cartouche
+X, Y : Integer := Init_Func;
+Q : String (X .. Y) := "abc";
+...
+for Q'Address use Compute_Address;
+@end cartouche
+@end smallexample
+
+@noindent
+will be rejected by GNAT, since the address cannot be computed at the time
+that Q is declared. To achieve the intended effect, write instead:
+
+@smallexample @c ada
+@group
+@cartouche
+X, Y : Integer := Init_Func;
+Q_Address : constant Address := Compute_Address;
+Q : String (X .. Y) := "abc";
+...
+for Q'Address use Q_Address;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+which will be accepted by GNAT (and other Ada 95 compilers), and is also
+backwards compatible with Ada 83. A fuller description of the restrictions
+on address specifications is found in the GNAT Reference Manual.
+
+@node Other Representation Clauses
+@subsection Other Representation Clauses
+
+@noindent
+GNAT supports in a compatible manner all the representation
+clauses supported by DEC Ada. In addition, it
+supports representation clause forms that are new in Ada 95
+including COMPONENT_SIZE and SIZE clauses for objects.
+
+@node The Package STANDARD
+@section The Package STANDARD
+
+@noindent
+The package STANDARD, as implemented by DEC Ada, is fully
+described in the Reference Manual for the Ada Programming
+Language (ANSI/MIL-STD-1815A-1983) and in the DEC Ada
+Language Reference Manual. As implemented by GNAT, the
+package STANDARD is described in the Ada 95 Reference
+Manual.
+
+In addition, DEC Ada supports the Latin-1 character set in
+the type CHARACTER. GNAT supports the Latin-1 character set
+in the type CHARACTER and also Unicode (ISO 10646 BMP) in
+the type WIDE_CHARACTER.
+
+The floating-point types supported by GNAT are those
+supported by DEC Ada, but defaults are different, and are controlled by
+pragmas. See @pxref{Floating-Point Types and Representations} for details.
+
+@node The Package SYSTEM
+@section The Package SYSTEM
+
+@noindent
+DEC Ada provides a system-specific version of the package
+SYSTEM for each platform on which the language ships.
+For the complete specification of the package SYSTEM, see
+Appendix F of the DEC Ada Language Reference Manual.
+
+On DEC Ada, the package SYSTEM includes the following conversion functions:
+@itemize @bullet
+@item TO_ADDRESS(INTEGER)
+
+@item TO_ADDRESS(UNSIGNED_LONGWORD)
+
+@item TO_ADDRESS(universal_integer)
+
+@item TO_INTEGER(ADDRESS)
+
+@item TO_UNSIGNED_LONGWORD(ADDRESS)
+
+@item Function IMPORT_VALUE return UNSIGNED_LONGWORD and the
+ functions IMPORT_ADDRESS and IMPORT_LARGEST_VALUE
+@end itemize
+
+@noindent
+By default, GNAT supplies a version of SYSTEM that matches
+the definition given in the Ada 95 Reference Manual.
+This
+is a subset of the DIGITAL system definitions, which is as
+close as possible to the original definitions. The only difference
+is that the definition of SYSTEM_NAME is different:
+
+@smallexample @c ada
+@group
+@cartouche
+type Name is (SYSTEM_NAME_GNAT);
+System_Name : constant Name := SYSTEM_NAME_GNAT;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Also, GNAT adds the new Ada 95 declarations for
+BIT_ORDER and DEFAULT_BIT_ORDER.
+
+However, the use of the following pragma causes GNAT
+to extend the definition of package SYSTEM so that it
+encompasses the full set of DIGITAL-specific extensions,
+including the functions listed above:
+
+@smallexample @c ada
+@cartouche
+pragma Extend_System (Aux_DEC);
+@end cartouche
+@end smallexample
+
+@noindent
+The pragma Extend_System is a configuration pragma that
+is most conveniently placed in the @file{gnat.adc} file. See the
+GNAT Reference Manual for further details.
+
+DEC Ada does not allow the recompilation of the package
+SYSTEM. Instead DEC Ada provides several pragmas (SYSTEM_
+NAME, STORAGE_UNIT, and MEMORY_SIZE) to modify values in
+the package SYSTEM. On OpenVMS Alpha systems, the pragma
+SYSTEM_NAME takes the enumeration literal OPENVMS_AXP as
+its single argument.
+
+GNAT does permit the recompilation of package SYSTEM using
+a special switch (@option{-gnatg}) and this switch can be used if
+it is necessary to modify the definitions in SYSTEM. GNAT does
+not permit the specification of SYSTEM_NAME, STORAGE_UNIT
+or MEMORY_SIZE by any other means.
+
+On GNAT systems, the pragma SYSTEM_NAME takes the
+enumeration literal SYSTEM_NAME_GNAT.
+
+The definitions provided by the use of
+
+@smallexample @c ada
+pragma Extend_System (AUX_Dec);
+@end smallexample
+
+@noindent
+are virtually identical to those provided by the DEC Ada 83 package
+System. One important difference is that the name of the TO_ADDRESS
+function for type UNSIGNED_LONGWORD is changed to TO_ADDRESS_LONG.
+See the GNAT Reference manual for a discussion of why this change was
+necessary.
+
+@noindent
+The version of TO_ADDRESS taking a universal integer argument is in fact
+an extension to Ada 83 not strictly compatible with the reference manual.
+In GNAT, we are constrained to be exactly compatible with the standard,
+and this means we cannot provide this capability. In DEC Ada 83, the
+point of this definition is to deal with a call like:
+
+@smallexample @c ada
+TO_ADDRESS (16#12777#);
+@end smallexample
+
+@noindent
+Normally, according to the Ada 83 standard, one would expect this to be
+ambiguous, since it matches both the INTEGER and UNSIGNED_LONGWORD forms
+of TO_ADDRESS. However, in DEC Ada 83, there is no ambiguity, since the
+definition using universal_integer takes precedence.
+
+In GNAT, since the version with universal_integer cannot be supplied, it is
+not possible to be 100% compatible. Since there are many programs using
+numeric constants for the argument to TO_ADDRESS, the decision in GNAT was
+to change the name of the function in the UNSIGNED_LONGWORD case, so the
+declarations provided in the GNAT version of AUX_Dec are:
+
+@smallexample @c ada
+function To_Address (X : Integer) return Address;
+pragma Pure_Function (To_Address);
+
+function To_Address_Long (X : Unsigned_Longword) return Address;
+pragma Pure_Function (To_Address_Long);
+@end smallexample
+
+@noindent
+This means that programs using TO_ADDRESS for UNSIGNED_LONGWORD must
+change the name to TO_ADDRESS_LONG.
+
+@node Tasking and Task-Related Features
+@section Tasking and Task-Related Features
+
+@noindent
+The concepts relevant to a comparison of tasking on GNAT
+and on DEC Ada for OpenVMS Alpha systems are discussed in
+the following sections.
+
+For detailed information on concepts related to tasking in
+DEC Ada, see the DEC Ada Language Reference Manual and the
+relevant run-time reference manual.
+
+@node Implementation of Tasks in DEC Ada for OpenVMS Alpha Systems
+@section Implementation of Tasks in DEC Ada for OpenVMS Alpha Systems
+
+@noindent
+On OpenVMS Alpha systems, each Ada task (except a passive
+task) is implemented as a single stream of execution
+that is created and managed by the kernel. On these
+systems, DEC Ada tasking support is based on DECthreads,
+an implementation of the POSIX standard for threads.
+
+Although tasks are implemented as threads, all tasks in
+an Ada program are part of the same process. As a result,
+resources such as open files and virtual memory can be
+shared easily among tasks. Having all tasks in one process
+allows better integration with the programming environment
+(the shell and the debugger, for example).
+
+Also, on OpenVMS Alpha systems, DEC Ada tasks and foreign
+code that calls DECthreads routines can be used together.
+The interaction between Ada tasks and DECthreads routines
+can have some benefits. For example when on OpenVMS Alpha,
+DEC Ada can call C code that is already threaded.
+GNAT on OpenVMS Alpha uses the facilities of DECthreads,
+and Ada tasks are mapped to threads.
+
+@menu
+* Assigning Task IDs::
+* Task IDs and Delays::
+* Task-Related Pragmas::
+* Scheduling and Task Priority::
+* The Task Stack::
+* External Interrupts::
+@end menu
+
+@node Assigning Task IDs
+@subsection Assigning Task IDs
+
+@noindent
+The DEC Ada Run-Time Library always assigns %TASK 1 to
+the environment task that executes the main program. On
+OpenVMS Alpha systems, %TASK 0 is often used for tasks
+that have been created but are not yet activated.
+
+On OpenVMS Alpha systems, task IDs are assigned at
+activation. On GNAT systems, task IDs are also assigned at
+task creation but do not have the same form or values as
+task ID values in DEC Ada. There is no null task, and the
+environment task does not have a specific task ID value.
+
+@node Task IDs and Delays
+@subsection Task IDs and Delays
+
+@noindent
+On OpenVMS Alpha systems, tasking delays are implemented
+using Timer System Services. The Task ID is used for the
+identification of the timer request (the REQIDT parameter).
+If Timers are used in the application take care not to use
+0 for the identification, because cancelling such a timer
+will cancel all timers and may lead to unpredictable results.
+
+@node Task-Related Pragmas
+@subsection Task-Related Pragmas
+
+@noindent
+Ada supplies the pragma TASK_STORAGE, which allows
+specification of the size of the guard area for a task
+stack. (The guard area forms an area of memory that has no
+read or write access and thus helps in the detection of
+stack overflow.) On OpenVMS Alpha systems, if the pragma
+TASK_STORAGE specifies a value of zero, a minimal guard
+area is created. In the absence of a pragma TASK_STORAGE, a default guard
+area is created.
+
+GNAT supplies the following task-related pragmas:
+
+@itemize @bullet
+@item TASK_INFO
+
+ This pragma appears within a task definition and
+ applies to the task in which it appears. The argument
+ must be of type SYSTEM.TASK_INFO.TASK_INFO_TYPE.
+
+@item TASK_STORAGE
+
+ GNAT implements pragma TASK_STORAGE in the same way as
+ DEC Ada.
+ Both DEC Ada and GNAT supply the pragmas PASSIVE,
+ SUPPRESS, and VOLATILE.
+@end itemize
+@node Scheduling and Task Priority
+@subsection Scheduling and Task Priority
+
+@noindent
+DEC Ada implements the Ada language requirement that
+when two tasks are eligible for execution and they have
+different priorities, the lower priority task does not
+execute while the higher priority task is waiting. The DEC
+Ada Run-Time Library keeps a task running until either the
+task is suspended or a higher priority task becomes ready.
+
+On OpenVMS Alpha systems, the default strategy is round-
+robin with preemption. Tasks of equal priority take turns
+at the processor. A task is run for a certain period of
+time and then placed at the rear of the ready queue for
+its priority level.
+
+DEC Ada provides the implementation-defined pragma TIME_SLICE,
+which can be used to enable or disable round-robin
+scheduling of tasks with the same priority.
+See the relevant DEC Ada run-time reference manual for
+information on using the pragmas to control DEC Ada task
+scheduling.
+
+GNAT follows the scheduling rules of Annex D (real-time
+Annex) of the Ada 95 Reference Manual. In general, this
+scheduling strategy is fully compatible with DEC Ada
+although it provides some additional constraints (as
+fully documented in Annex D).
+GNAT implements time slicing control in a manner compatible with
+DEC Ada 83, by means of the pragma Time_Slice, whose semantics are identical
+to the DEC Ada 83 pragma of the same name.
+Note that it is not possible to mix GNAT tasking and
+DEC Ada 83 tasking in the same program, since the two run times are
+not compatible.
+
+@node The Task Stack
+@subsection The Task Stack
+
+@noindent
+In DEC Ada, a task stack is allocated each time a
+non passive task is activated. As soon as the task is
+terminated, the storage for the task stack is deallocated.
+If you specify a size of zero (bytes) with T'STORAGE_SIZE,
+a default stack size is used. Also, regardless of the size
+specified, some additional space is allocated for task
+management purposes. On OpenVMS Alpha systems, at least
+one page is allocated.
+
+GNAT handles task stacks in a similar manner. According to
+the Ada 95 rules, it provides the pragma STORAGE_SIZE as
+an alternative method for controlling the task stack size.
+The specification of the attribute T'STORAGE_SIZE is also
+supported in a manner compatible with DEC Ada.
+
+@node External Interrupts
+@subsection External Interrupts
+
+@noindent
+On DEC Ada, external interrupts can be associated with task entries.
+GNAT is compatible with DEC Ada in its handling of external interrupts.
+
+@node Pragmas and Pragma-Related Features
+@section Pragmas and Pragma-Related Features
+
+@noindent
+Both DEC Ada and GNAT supply all language-defined pragmas
+as specified by the Ada 83 standard. GNAT also supplies all
+language-defined pragmas specified in the Ada 95 Reference Manual.
+In addition, GNAT implements the implementation-defined pragmas
+from DEC Ada 83.
+
+@itemize @bullet
+@item AST_ENTRY
+
+@item COMMON_OBJECT
+
+@item COMPONENT_ALIGNMENT
+
+@item EXPORT_EXCEPTION
+
+@item EXPORT_FUNCTION
+
+@item EXPORT_OBJECT
+
+@item EXPORT_PROCEDURE
+
+@item EXPORT_VALUED_PROCEDURE
+
+@item FLOAT_REPRESENTATION
+
+@item IDENT
+
+@item IMPORT_EXCEPTION
+
+@item IMPORT_FUNCTION
+
+@item IMPORT_OBJECT
+
+@item IMPORT_PROCEDURE
+
+@item IMPORT_VALUED_PROCEDURE
+
+@item INLINE_GENERIC
+
+@item INTERFACE_NAME
+
+@item LONG_FLOAT
+
+@item MAIN_STORAGE
+
+@item PASSIVE
+
+@item PSET_OBJECT
+
+@item SHARE_GENERIC
+
+@item SUPPRESS_ALL
+
+@item TASK_STORAGE
+
+@item TIME_SLICE
+
+@item TITLE
+@end itemize
+
+@noindent
+These pragmas are all fully implemented, with the exception of @code{Title},
+@code{Passive}, and @code{Share_Generic}, which are
+recognized, but which have no
+effect in GNAT. The effect of @code{Passive} may be obtained by the
+use of protected objects in Ada 95. In GNAT, all generics are inlined.
+
+Unlike DEC Ada, the GNAT 'EXPORT_@i{subprogram}' pragmas require
+a separate subprogram specification which must appear before the
+subprogram body.
+
+GNAT also supplies a number of implementation-defined pragmas as follows:
+@itemize @bullet
+@item C_PASS_BY_COPY
+
+@item EXTEND_SYSTEM
+
+@item SOURCE_FILE_NAME
+
+@item UNSUPPRESS
+
+@item WARNINGS
+
+@item ABORT_DEFER
+
+@item ADA_83
+
+@item ADA_95
+
+@item ANNOTATE
+
+@item ASSERT
+
+@item CPP_CLASS
+
+@item CPP_CONSTRUCTOR
+
+@item CPP_DESTRUCTOR
+
+@item CPP_VIRTUAL
+
+@item CP_VTABLE
+
+@item DEBUG
+
+@item LINKER_ALIAS
+
+@item LINKER_SECTION
+
+@item MACHINE_ATTRIBUTE
+
+@item NO_RETURN
+
+@item PURE_FUNCTION
+
+@item SOURCE_REFERENCE
+
+@item TASK_INFO
+
+@item UNCHECKED_UNION
+
+@item UNIMPLEMENTED_UNIT
+
+@item UNIVERSAL_DATA
+
+@item WEAK_EXTERNAL
+@end itemize
+
+@noindent
+For full details on these GNAT implementation-defined pragmas, see
+the GNAT Reference Manual.
+
+@menu
+* Restrictions on the Pragma INLINE::
+* Restrictions on the Pragma INTERFACE::
+* Restrictions on the Pragma SYSTEM_NAME::
+@end menu
+
+@node Restrictions on the Pragma INLINE
+@subsection Restrictions on the Pragma INLINE
+
+@noindent
+DEC Ada applies the following restrictions to the pragma INLINE:
+@itemize @bullet
+@item Parameters cannot be a task type.
+
+@item Function results cannot be task types, unconstrained
+array types, or unconstrained types with discriminants.
+
+@item Bodies cannot declare the following:
+@itemize @bullet
+@item Subprogram body or stub (imported subprogram is allowed)
+
+@item Tasks
+
+@item Generic declarations
+
+@item Instantiations
+
+@item Exceptions
+
+@item Access types (types derived from access types allowed)
+
+@item Array or record types
+
+@item Dependent tasks
+
+@item Direct recursive calls of subprogram or containing
+subprogram, directly or via a renaming
+
+@end itemize
+@end itemize
+
+@noindent
+In GNAT, the only restriction on pragma INLINE is that the
+body must occur before the call if both are in the same
+unit, and the size must be appropriately small. There are
+no other specific restrictions which cause subprograms to
+be incapable of being inlined.
+
+@node Restrictions on the Pragma INTERFACE
+@subsection Restrictions on the Pragma INTERFACE
+
+@noindent
+The following lists and describes the restrictions on the
+pragma INTERFACE on DEC Ada and GNAT:
+@itemize @bullet
+@item Languages accepted: Ada, Bliss, C, Fortran, Default.
+Default is the default on OpenVMS Alpha systems.
+
+@item Parameter passing: Language specifies default
+mechanisms but can be overridden with an EXPORT pragma.
+
+@itemize @bullet
+@item Ada: Use internal Ada rules.
+
+@item Bliss, C: Parameters must be mode @code{in}; cannot be
+record or task type. Result cannot be a string, an
+array, or a record.
+
+@item Fortran: Parameters cannot be a task. Result cannot
+be a string, an array, or a record.
+@end itemize
+@end itemize
+
+@noindent
+GNAT is entirely upwards compatible with DEC Ada, and in addition allows
+record parameters for all languages.
+
+@node Restrictions on the Pragma SYSTEM_NAME
+@subsection Restrictions on the Pragma SYSTEM_NAME
+
+@noindent
+For DEC Ada for OpenVMS Alpha, the enumeration literal
+for the type NAME is OPENVMS_AXP. In GNAT, the enumeration
+literal for the type NAME is SYSTEM_NAME_GNAT.
+
+@node Library of Predefined Units
+@section Library of Predefined Units
+
+@noindent
+A library of predefined units is provided as part of the
+DEC Ada and GNAT implementations. DEC Ada does not provide
+the package MACHINE_CODE but instead recommends importing
+assembler code.
+
+The GNAT versions of the DEC Ada Run-Time Library (ADA$PREDEFINED:)
+units are taken from the OpenVMS Alpha version, not the OpenVMS VAX
+version. During GNAT installation, the DEC Ada Predefined
+Library units are copied into the GNU:[LIB.OPENVMS7_x.2_8_x.DECLIB]
+(aka DECLIB) directory and patched to remove Ada 95 incompatibilities
+and to make them interoperable with GNAT, @pxref{Changes to DECLIB}
+for details.
+
+The GNAT RTL is contained in
+the GNU:[LIB.OPENVMS7_x.2_8_x.ADALIB] (aka ADALIB) directory and
+the default search path is set up to find DECLIB units in preference
+to ADALIB units with the same name (TEXT_IO, SEQUENTIAL_IO, and DIRECT_IO,
+for example).
+
+However, it is possible to change the default so that the
+reverse is true, or even to mix them using child package
+notation. The DEC Ada 83 units are available as DEC.xxx where xxx
+is the package name, and the Ada units are available in the
+standard manner defined for Ada 95, that is to say as Ada.xxx. To
+change the default, set ADA_INCLUDE_PATH and ADA_OBJECTS_PATH
+appropriately. For example, to change the default to use the Ada95
+versions do:
+
+@smallexample
+$ DEFINE ADA_INCLUDE_PATH GNU:[LIB.OPENVMS7_1.2_8_1.ADAINCLUDE],-
+ GNU:[LIB.OPENVMS7_1.2_8_1.DECLIB]
+$ DEFINE ADA_OBJECTS_PATH GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB],-
+ GNU:[LIB.OPENVMS7_1.2_8_1.DECLIB]
+@end smallexample
+
+@menu
+* Changes to DECLIB::
+@end menu
+
+@node Changes to DECLIB
+@subsection Changes to DECLIB
+
+@noindent
+The changes made to the DEC Ada predefined library for GNAT and Ada 95
+compatibility are minor and include the following:
+
+@itemize @bullet
+@item Adjusting the location of pragmas and record representation
+clauses to obey Ada 95 rules
+
+@item Adding the proper notation to generic formal parameters
+that take unconstrained types in instantiation
+
+@item Adding pragma ELABORATE_BODY to package specifications
+that have package bodies not otherwise allowed
+
+@item Occurrences of the identifier @code{"PROTECTED"} are renamed to
+@code{"PROTECTD"}.
+Currently these are found only in the STARLET package spec.
+@end itemize
+
+@noindent
+None of the above changes is visible to users.
+
+@node Bindings
+@section Bindings
+
+@noindent
+On OpenVMS Alpha, DEC Ada provides the following strongly-typed bindings:
+@itemize @bullet
+
+@item Command Language Interpreter (CLI interface)
+
+@item DECtalk Run-Time Library (DTK interface)
+
+@item Librarian utility routines (LBR interface)
+
+@item General Purpose Run-Time Library (LIB interface)
+
+@item Math Run-Time Library (MTH interface)
+
+@item National Character Set Run-Time Library (NCS interface)
+
+@item Compiled Code Support Run-Time Library (OTS interface)
+
+@item Parallel Processing Run-Time Library (PPL interface)
+
+@item Screen Management Run-Time Library (SMG interface)
+
+@item Sort Run-Time Library (SOR interface)
+
+@item String Run-Time Library (STR interface)
+
+@item STARLET System Library
+@findex Starlet
+
+@item X Window System Version 11R4 and 11R5 (X, XLIB interface)
+
+@item X Windows Toolkit (XT interface)
+
+@item X/Motif Version 1.1.3 and 1.2 (XM interface)
+@end itemize
+
+@noindent
+GNAT provides implementations of these DEC bindings in the DECLIB directory.
+
+The X/Motif bindings used to build DECLIB are whatever versions are in the
+DEC Ada @file{ADA$PREDEFINED} directory with extension @file{.ADC}.
+The build script will
+automatically add a pragma Linker_Options to packages @code{Xm}, @code{Xt},
+and @code{X_Lib}
+causing the default X/Motif sharable image libraries to be linked in. This
+is done via options files named @file{xm.opt}, @file{xt.opt}, and
+@file{x_lib.opt} (also located in the @file{DECLIB} directory).
+
+It may be necessary to edit these options files to update or correct the
+library names if, for example, the newer X/Motif bindings from
+@file{ADA$EXAMPLES}
+had been (previous to installing GNAT) copied and renamed to supersede the
+default @file{ADA$PREDEFINED} versions.
+
+@menu
+* Shared Libraries and Options Files::
+* Interfaces to C::
+@end menu
+
+@node Shared Libraries and Options Files
+@subsection Shared Libraries and Options Files
+
+@noindent
+When using the DEC Ada
+predefined X and Motif bindings, the linking with their sharable images is
+done automatically by @command{GNAT LINK}.
+When using other X and Motif bindings, you need
+to add the corresponding sharable images to the command line for
+@code{GNAT LINK}. When linking with shared libraries, or with
+@file{.OPT} files, you must
+also add them to the command line for @command{GNAT LINK}.
+
+A shared library to be used with GNAT is built in the same way as other
+libraries under VMS. The VMS Link command can be used in standard fashion.
+
+@node Interfaces to C
+@subsection Interfaces to C
+
+@noindent
+DEC Ada
+provides the following Ada types and operations:
+
+@itemize @bullet
+@item C types package (C_TYPES)
+
+@item C strings (C_TYPES.NULL_TERMINATED)
+
+@item Other_types (SHORT_INT)
+@end itemize
+
+@noindent
+Interfacing to C with GNAT, one can use the above approach
+described for DEC Ada or the facilities of Annex B of
+the Ada 95 Reference Manual (packages INTERFACES.C,
+INTERFACES.C.STRINGS and INTERFACES.C.POINTERS). For more
+information, see the section ``Interfacing to C'' in the
+@cite{GNAT Reference Manual}.
+
+The @option{-gnatF} qualifier forces default and explicit
+@code{External_Name} parameters in pragmas Import and Export
+to be uppercased for compatibility with the default behavior
+of Compaq C. The qualifier has no effect on @code{Link_Name} parameters.
+
+@node Main Program Definition
+@section Main Program Definition
+
+@noindent
+The following section discusses differences in the
+definition of main programs on DEC Ada and GNAT.
+On DEC Ada, main programs are defined to meet the
+following conditions:
+@itemize @bullet
+@item Procedure with no formal parameters (returns 0 upon
+ normal completion)
+
+@item Procedure with no formal parameters (returns 42 when
+ unhandled exceptions are raised)
+
+@item Function with no formal parameters whose returned value
+ is of a discrete type
+
+@item Procedure with one OUT formal of a discrete type for
+ which a specification of pragma EXPORT_VALUED_PROCEDURE is given.
+
+@end itemize
+
+@noindent
+When declared with the pragma EXPORT_VALUED_PROCEDURE,
+a main function or main procedure returns a discrete
+value whose size is less than 64 bits (32 on VAX systems),
+the value is zero- or sign-extended as appropriate.
+On GNAT, main programs are defined as follows:
+@itemize @bullet
+@item Must be a non-generic, parameter-less subprogram that
+is either a procedure or function returning an Ada
+STANDARD.INTEGER (the predefined type)
+
+@item Cannot be a generic subprogram or an instantiation of a
+generic subprogram
+@end itemize
+
+@node Implementation-Defined Attributes
+@section Implementation-Defined Attributes
+
+@noindent
+GNAT provides all DEC Ada implementation-defined
+attributes.
+
+@node Compiler and Run-Time Interfacing
+@section Compiler and Run-Time Interfacing
+
+@noindent
+DEC Ada provides the following ways to pass options to the linker
+(ACS LINK):
+@itemize @bullet
+@item /WAIT and /SUBMIT qualifiers
+
+@item /COMMAND qualifier
+
+@item /[NO]MAP qualifier
+
+@item /OUTPUT=file-spec
+
+@item /[NO]DEBUG and /[NO]TRACEBACK qualifiers
+@end itemize
+
+@noindent
+To pass options to the linker, GNAT provides the following
+switches:
+
+@itemize @bullet
+@item @option{/EXECUTABLE=exec-name}
+
+@item @option{/VERBOSE qualifier}
+
+@item @option{/[NO]DEBUG} and @option{/[NO]TRACEBACK} qualifiers
+@end itemize
+
+@noindent
+For more information on these switches, see
+@ref{Switches for gnatlink}.
+In DEC Ada, the command-line switch @option{/OPTIMIZE} is available
+to control optimization. DEC Ada also supplies the
+following pragmas:
+@itemize @bullet
+@item @code{OPTIMIZE}
+
+@item @code{INLINE}
+
+@item @code{INLINE_GENERIC}
+
+@item @code{SUPPRESS_ALL}
+
+@item @code{PASSIVE}
+@end itemize
+
+@noindent
+In GNAT, optimization is controlled strictly by command
+line parameters, as described in the corresponding section of this guide.
+The DIGITAL pragmas for control of optimization are
+recognized but ignored.
+
+Note that in GNAT, the default is optimization off, whereas in DEC Ada 83,
+the default is that optimization is turned on.
+
+@node Program Compilation and Library Management
+@section Program Compilation and Library Management
+
+@noindent
+DEC Ada and GNAT provide a comparable set of commands to
+build programs. DEC Ada also provides a program library,
+which is a concept that does not exist on GNAT. Instead,
+GNAT provides directories of sources that are compiled as
+needed.
+
+The following table summarizes
+the DEC Ada commands and provides
+equivalent GNAT commands. In this table, some GNAT
+equivalents reflect the fact that GNAT does not use the
+concept of a program library. Instead, it uses a model
+in which collections of source and object files are used
+in a manner consistent with other languages like C and
+Fortran. Therefore, standard system file commands are used
+to manipulate these elements. Those GNAT commands are marked with
+an asterisk.
+Note that, unlike DEC Ada, none of the GNAT commands accepts wild cards.
+
+@need 1500
+@multitable @columnfractions .35 .65
+
+@item @emph{DEC Ada Command}
+@tab @emph{GNAT Equivalent / Description}
+
+@item @command{ADA}
+@tab @command{GNAT COMPILE}@*
+Invokes the compiler to compile one or more Ada source files.
+
+@item @command{ACS ATTACH}@*
+@tab [No equivalent]@*
+Switches control of terminal from current process running the program
+library manager.
+
+@item @command{ACS CHECK}
+@tab @command{GNAT MAKE /DEPENDENCY_LIST}@*
+Forms the execution closure of one
+or more compiled units and checks completeness and currency.
+
+@item @command{ACS COMPILE}
+@tab @command{GNAT MAKE /ACTIONS=COMPILE}@*
+Forms the execution closure of one or
+more specified units, checks completeness and currency,
+identifies units that have revised source files, compiles same,
+and recompiles units that are or will become obsolete.
+Also completes incomplete generic instantiations.
+
+@item @command{ACS COPY FOREIGN}
+@tab Copy (*)@*
+Copies a foreign object file into the program library as a
+library unit body.
+
+@item @command{ACS COPY UNIT}
+@tab Copy (*)@*
+Copies a compiled unit from one program library to another.
+
+@item @command{ACS CREATE LIBRARY}
+@tab Create /directory (*)@*
+Creates a program library.
+
+@item @command{ACS CREATE SUBLIBRARY}
+@tab Create /directory (*)@*
+Creates a program sublibrary.
+
+@item @command{ACS DELETE LIBRARY}
+@tab @*
+Deletes a program library and its contents.
+
+@item @command{ACS DELETE SUBLIBRARY}
+@tab @*
+Deletes a program sublibrary and its contents.
+
+@item @command{ACS DELETE UNIT}
+@tab Delete file (*)@*
+On OpenVMS systems, deletes one or more compiled units from
+the current program library.
+
+@item @command{ACS DIRECTORY}
+@tab Directory (*)@*
+On OpenVMS systems, lists units contained in the current
+program library.
+
+@item @command{ACS ENTER FOREIGN}
+@tab Copy (*)@*
+Allows the import of a foreign body as an Ada library
+specification and enters a reference to a pointer.
+
+@item @command{ACS ENTER UNIT}
+@tab Copy (*)@*
+Enters a reference (pointer) from the current program library to
+a unit compiled into another program library.
+
+@item @command{ACS EXIT}
+@tab [No equivalent]@*
+Exits from the program library manager.
+
+@item @command{ACS EXPORT}
+@tab Copy (*)@*
+Creates an object file that contains system-specific object code
+for one or more units. With GNAT, object files can simply be copied
+into the desired directory.
+
+@item @command{ACS EXTRACT SOURCE}
+@tab Copy (*)@*
+Allows access to the copied source file for each Ada compilation unit
+
+@item @command{ACS HELP}
+@tab @command{HELP GNAT}@*
+Provides online help.
+
+@item @command{ACS LINK}
+@tab @command{GNAT LINK}@*
+Links an object file containing Ada units into an executable file.
+
+@item @command{ACS LOAD}
+@tab Copy (*)@*
+Loads (partially compiles) Ada units into the program library.
+Allows loading a program from a collection of files into a library
+without knowing the relationship among units.
+
+@item @command{ACS MERGE}
+@tab Copy (*)@*
+Merges into the current program library, one or more units from
+another library where they were modified.
+
+@item @command{ACS RECOMPILE}
+@tab @command{GNAT MAKE /ACTIONS=COMPILE}@*
+Recompiles from external or copied source files any obsolete
+unit in the closure. Also, completes any incomplete generic
+instantiations.
+
+@item @command{ACS REENTER}
+@tab @command{GNAT MAKE}@*
+Reenters current references to units compiled after last entered
+with the @command{ACS ENTER UNIT} command.
+
+@item @command{ACS SET LIBRARY}
+@tab Set default (*)@*
+Defines a program library to be the compilation context as well
+as the target library for compiler output and commands in general.
+
+@item @command{ACS SET PRAGMA}
+@tab Edit @file{gnat.adc} (*)@*
+Redefines specified values of the library characteristics
+@code{LONG_ FLOAT}, @code{MEMORY_SIZE}, @code{SYSTEM_NAME},
+and @code{Float_Representation}.
+
+@item @command{ACS SET SOURCE}
+@tab Define @code{ADA_INCLUDE_PATH} path (*)@*
+Defines the source file search list for the @command{ACS COMPILE} command.
+
+@item @command{ACS SHOW LIBRARY}
+@tab Directory (*)@*
+Lists information about one or more program libraries.
+
+@item @command{ACS SHOW PROGRAM}
+@tab [No equivalent]@*
+Lists information about the execution closure of one or
+more units in the program library.
+
+@item @command{ACS SHOW SOURCE}
+@tab Show logical @code{ADA_INCLUDE_PATH}@*
+Shows the source file search used when compiling units.
+
+@item @command{ACS SHOW VERSION}
+@tab Compile with @option{VERBOSE} option
+Displays the version number of the compiler and program library
+manager used.
+
+@item @command{ACS SPAWN}
+@tab [No equivalent]@*
+Creates a subprocess of the current process (same as @command{DCL SPAWN}
+command).
+
+@item @command{ACS VERIFY}
+@tab [No equivalent]@*
+Performs a series of consistency checks on a program library to
+determine whether the library structure and library files are in
+valid form.
+@end multitable
+
+@noindent
+
+@node Input-Output
+@section Input-Output
+
+@noindent
+On OpenVMS Alpha systems, DEC Ada uses OpenVMS Record
+Management Services (RMS) to perform operations on
+external files.
+
+@noindent
+DEC Ada and GNAT predefine an identical set of input-
+output packages. To make the use of the
+generic TEXT_IO operations more convenient, DEC Ada
+provides predefined library packages that instantiate the
+integer and floating-point operations for the predefined
+integer and floating-point types as shown in the following table.
+
+@multitable @columnfractions .45 .55
+@item @emph{Package Name} @tab Instantiation
+
+@item @code{INTEGER_TEXT_IO}
+@tab @code{INTEGER_IO(INTEGER)}
+
+@item @code{SHORT_INTEGER_TEXT_IO}
+@tab @code{INTEGER_IO(SHORT_INTEGER)}
+
+@item @code{SHORT_SHORT_INTEGER_TEXT_IO}
+@tab @code{INTEGER_IO(SHORT_SHORT_INTEGER)}
+
+@item @code{FLOAT_TEXT_IO}
+@tab @code{FLOAT_IO(FLOAT)}
+
+@item @code{LONG_FLOAT_TEXT_IO}
+@tab @code{FLOAT_IO(LONG_FLOAT)}
+@end multitable
+
+@noindent
+The DEC Ada predefined packages and their operations
+are implemented using OpenVMS Alpha files and input-
+output facilities. DEC Ada supports asynchronous input-
+output on OpenVMS Alpha. Familiarity with the following is
+recommended:
+@itemize @bullet
+@item RMS file organizations and access methods
+
+@item OpenVMS file specifications and directories
+
+@item OpenVMS File Definition Language (FDL)
+@end itemize
+
+@noindent
+GNAT provides I/O facilities that are completely
+compatible with DEC Ada. The distribution includes the
+standard DEC Ada versions of all I/O packages, operating
+in a manner compatible with DEC Ada. In particular, the
+following packages are by default the DEC Ada (Ada 83)
+versions of these packages rather than the renamings
+suggested in annex J of the Ada 95 Reference Manual:
+@itemize @bullet
+@item @code{TEXT_IO}
+
+@item @code{SEQUENTIAL_IO}
+
+@item @code{DIRECT_IO}
+@end itemize
+
+@noindent
+The use of the standard Ada 95 syntax for child packages (for
+example, @code{ADA.TEXT_IO}) retrieves the Ada 95 versions of these
+packages, as defined in the Ada 95 Reference Manual.
+GNAT provides DIGITAL-compatible predefined instantiations
+of the @code{TEXT_IO} packages, and also
+provides the standard predefined instantiations required
+by the Ada 95 Reference Manual.
+
+For further information on how GNAT interfaces to the file
+system or how I/O is implemented in programs written in
+mixed languages, see the chapter ``Implementation of the
+Standard I/O'' in the @cite{GNAT Reference Manual}.
+This chapter covers the following:
+@itemize @bullet
+@item Standard I/O packages
+
+@item @code{FORM} strings
+
+@item @code{ADA.DIRECT_IO}
+
+@item @code{ADA.SEQUENTIAL_IO}
+
+@item @code{ADA.TEXT_IO}
+
+@item Stream pointer positioning
+
+@item Reading and writing non-regular files
+
+@item @code{GET_IMMEDIATE}
+
+@item Treating @code{TEXT_IO} files as streams
+
+@item Shared files
+
+@item Open modes
+@end itemize
+
+@node Implementation Limits
+@section Implementation Limits
+
+@noindent
+The following table lists implementation limits for DEC Ada
+and GNAT systems.
+@multitable @columnfractions .60 .20 .20
+@sp 1
+@item @emph{Compilation Parameter}
+@tab @emph{DEC Ada}
+@tab @emph{GNAT}
+@sp 1
+
+@item In a subprogram or entry declaration, maximum number of
+ formal parameters that are of an unconstrained record type
+@tab 32
+@tab No set limit
+@sp 1
+
+@item Maximum identifier length (number of characters)
+@tab 255
+@tab 255
+@sp 1
+
+@item Maximum number of characters in a source line
+@tab 255
+@tab 255
+@sp 1
+
+@item Maximum collection size (number of bytes)
+@tab 2**31-1
+@tab 2**31-1
+@sp 1
+
+@item Maximum number of discriminants for a record type
+@tab 245
+@tab No set limit
+@sp 1
+
+@item Maximum number of formal parameters in an entry or
+ subprogram declaration
+@tab 246
+@tab No set limit
+@sp 1
+
+@item Maximum number of dimensions in an array type
+@tab 255
+@tab No set limit
+@sp 1
+
+@item Maximum number of library units and subunits in a compilation.
+@tab 4095
+@tab No set limit
+@sp 1
+
+@item Maximum number of library units and subunits in an execution.
+@tab 16383
+@tab No set limit
+@sp 1
+
+@item Maximum number of objects declared with the pragma @code{COMMON_OBJECT}
+ or @code{PSECT_OBJECT}
+@tab 32757
+@tab No set limit
+@sp 1
+
+@item Maximum number of enumeration literals in an enumeration type
+ definition
+@tab 65535
+@tab No set limit
+@sp 1
+
+@item Maximum number of lines in a source file
+@tab 65534
+@tab No set limit
+@sp 1
+
+@item Maximum number of bits in any object
+@tab 2**31-1
+@tab 2**31-1
+@sp 1
+
+@item Maximum size of the static portion of a stack frame (approximate)
+@tab 2**31-1
+@tab 2**31-1
+@end multitable
+
+@node Tools
+@section Tools
+
+@end ifset
+
+
+@c **************************************
+@node Platform-Specific Information for the Run-Time Libraries
+@appendix Platform-Specific Information for the Run-Time Libraries
+@cindex Tasking and threads libraries
+@cindex Threads libraries and tasking
+@cindex Run-time libraries (platform-specific information)
+
+@noindent
+The GNAT run-time implementation
+may vary with respect to both the underlying threads library and
+the exception handling scheme.
+For threads support, one or more of the following are supplied:
+@itemize @bullet
+@item @b{native threads library}, a binding to the thread package from
+the underlying operating system
+
+@item @b{FSU threads library}, a binding to the Florida State University
+threads implementation, which complies fully with the requirements of Annex D
+
+@item @b{pthreads library} (Sparc Solaris only), a binding to the Solaris
+POSIX thread package
+@end itemize
+
+@noindent
+For exception handling, either or both of two models are supplied:
+@itemize @bullet
+@item @b{Zero-Cost Exceptions} (``ZCX''),@footnote{
+Most programs should experience a substantial speed improvement by
+being compiled with a ZCX run-time.
+This is especially true for
+tasking applications or applications with many exception handlers.}
+@cindex Zero-Cost Exceptions
+@cindex ZCX (Zero-Cost Exceptions)
+which uses binder-generated tables that
+are interrogated at run time to locate a handler
+
+@item @b{setjmp / longjmp} (``SJLJ''),
+@cindex setjmp/longjmp Exception Model
+@cindex SJLJ (setjmp/longjmp Exception Model)
+which uses dynamically-set data to establish
+the set of handlers
+@end itemize
+
+@noindent
+This appendix summarizes which combinations of threads and exception support
+are supplied on various GNAT platforms.
+It then shows how to select a particular library either
+permanently or temporarily,
+explains the properties of (and tradeoffs among) the various threads
+libraries, and provides some additional
+information about several specific platforms.
+
+@menu
+* Summary of Run-Time Configurations::
+* Specifying a Run-Time Library::
+* Choosing between Native and FSU Threads Libraries::
+* Choosing the Scheduling Policy::
+* Solaris-Specific Considerations::
+* IRIX-Specific Considerations::
+* Linux-Specific Considerations::
+* AIX-Specific Considerations::
+@end menu
+
+
+@node Summary of Run-Time Configurations
+@section Summary of Run-Time Configurations
+
+
+@multitable @columnfractions .30 .70
+@item @b{alpha-openvms}
+@item @code{@ @ }@i{rts-native (default)}
+@item @code{@ @ @ @ }Tasking @tab native VMS threads
+@item @code{@ @ @ @ }Exceptions @tab ZCX
+@*
+@item @b{pa-hpux}
+@item @code{@ @ }@i{rts-native (default)}
+@item @code{@ @ @ @ }Tasking @tab native HP threads library
+@item @code{@ @ @ @ }Exceptions @tab ZCX
+@*
+@item @code{@ @ }@i{rts-sjlj}
+@item @code{@ @ @ @ }Tasking @tab native HP threads library
+@item @code{@ @ @ @ }Exceptions @tab SJLJ
+@*
+@item @b{sparc-solaris} @tab
+@item @code{@ @ }@i{rts-native (default)}
+@item @code{@ @ @ @ }Tasking @tab native Solaris threads library
+@item @code{@ @ @ @ }Exceptions @tab ZCX
+@*
+@item @code{@ @ }@i{rts-fsu} @tab
+@item @code{@ @ @ @ }Tasking @tab FSU threads library
+@item @code{@ @ @ @ }Exceptions @tab SJLJ
+@*
+@item @code{@ @ }@i{rts-m64}
+@item @code{@ @ @ @ }Tasking @tab native Solaris threads library
+@item @code{@ @ @ @ }Exceptions @tab ZCX
+@item @code{@ @ @ @ }Constraints @tab Use only when compiling in 64-bit mode;
+@item @tab Use only on Solaris 8 or later.
+@item @tab @xref{Building and Debugging 64-bit Applications}, for details.
+@*
+@item @code{@ @ }@i{rts-pthread}
+@item @code{@ @ @ @ }Tasking @tab pthreads library
+@item @code{@ @ @ @ }Exceptions @tab ZCX
+@*
+@item @code{@ @ }@i{rts-sjlj}
+@item @code{@ @ @ @ }Tasking @tab native Solaris threads library
+@item @code{@ @ @ @ }Exceptions @tab SJLJ
+@*
+@item @b{x86-linux}
+@item @code{@ @ }@i{rts-native (default)}
+@item @code{@ @ @ @ }Tasking @tab LinuxThread library
+@item @code{@ @ @ @ }Exceptions @tab ZCX
+@*
+@item @code{@ @ }@i{rts-fsu}
+@item @code{@ @ @ @ }Tasking @tab FSU threads library
+@item @code{@ @ @ @ }Exceptions @tab SJLJ
+@*
+@item @code{@ @ }@i{rts-sjlj}
+@item @code{@ @ @ @ }Tasking @tab LinuxThread library
+@item @code{@ @ @ @ }Exceptions @tab SJLJ
+@*
+@item @b{x86-windows}
+@item @code{@ @ }@i{rts-native (default)}
+@item @code{@ @ @ @ }Tasking @tab native Win32 threads
+@item @code{@ @ @ @ }Exceptions @tab SJLJ
+@*
+@end multitable
+
+
+
+@node Specifying a Run-Time Library
+@section Specifying a Run-Time Library
+
+@noindent
+The @file{adainclude} subdirectory containing the sources of the GNAT
+run-time library, and the @file{adalib} subdirectory containing the
+@file{ALI} files and the static and/or shared GNAT library, are located
+in the gcc target-dependent area:
+
+@smallexample
+target=$prefix/lib/gcc-lib/gcc-@i{dumpmachine}/gcc-@i{dumpversion}/
+@end smallexample
+
+@noindent
+As indicated above, on some platforms several run-time libraries are supplied.
+These libraries are installed in the target dependent area and
+contain a complete source and binary subdirectory. The detailed description
+below explains the differences between the different libraries in terms of
+their thread support.
+
+The default run-time library (when GNAT is installed) is @emph{rts-native}.
+This default run time is selected by the means of soft links.
+For example on x86-linux:
+
+@smallexample
+@group
+ $(target-dir)
+ |
+ +--- adainclude----------+
+ | |
+ +--- adalib-----------+ |
+ | | |
+ +--- rts-native | |
+ | | | |
+ | +--- adainclude <---+
+ | | |
+ | +--- adalib <----+
+ |
+ +--- rts-fsu
+ | |
+ | +--- adainclude
+ | |
+ | +--- adalib
+ |
+ +--- rts-sjlj
+ |
+ +--- adainclude
+ |
+ +--- adalib
+@end group
+@end smallexample
+
+@noindent
+If the @i{rts-fsu} library is to be selected on a permanent basis,
+these soft links can be modified with the following commands:
+
+@smallexample
+$ cd $target
+$ rm -f adainclude adalib
+$ ln -s rts-fsu/adainclude adainclude
+$ ln -s rts-fsu/adalib adalib
+@end smallexample
+
+@noindent
+Alternatively, you can specify @file{rts-fsu/adainclude} in the file
+@file{$target/ada_source_path} and @file{rts-fsu/adalib} in
+@file{$target/ada_object_path}.
+
+Selecting another run-time library temporarily can be
+achieved by the regular mechanism for GNAT object or source path selection:
+
+@itemize @bullet
+@item
+Set the environment variables:
+
+@smallexample
+$ ADA_INCLUDE_PATH=$target/rts-fsu/adainclude:$ADA_INCLUDE_PATH
+$ ADA_OBJECTS_PATH=$target/rts-fsu/adalib:$ADA_OBJECTS_PATH
+$ export ADA_INCLUDE_PATH ADA_OBJECTS_PATH
+@end smallexample
+
+@item
+Use @option{-aI$target/rts-fsu/adainclude}
+and @option{-aO$target/rts-fsu/adalib}
+on the @command{gnatmake} command line
+
+@item
+Use the switch @option{--RTS}; e.g., @option{--RTS=fsu}
+@cindex @option{--RTS} option
+@end itemize
+
+@noindent
+You can similarly switch to @emph{rts-sjlj}.
+
+@node Choosing between Native and FSU Threads Libraries
+@section Choosing between Native and FSU Threads Libraries
+@cindex Native threads library
+@cindex FSU threads library
+
+@noindent
+Some GNAT implementations offer a choice between
+native threads and FSU threads.
+
+@itemize @bullet
+@item
+The @emph{native threads} library correspond to the standard system threads
+implementation (e.g. LinuxThreads on GNU/Linux,
+@cindex LinuxThreads library
+POSIX threads on AIX, or
+Solaris threads on Solaris). When this option is chosen, GNAT provides
+a full and accurate implementation of the core language tasking model
+as described in Chapter 9 of the Ada Reference Manual,
+but might not (and probably does not) implement
+the exact semantics as specified in @w{Annex D} (the Real-Time Systems Annex).
+@cindex Annex D (Real-Time Systems Annex) compliance
+@cindex Real-Time Systems Annex compliance
+Indeed, the reason that a choice of libraries is offered
+on a given target is because some of the
+ACATS tests for @w{Annex D} fail using the native threads library.
+As far as possible, this library is implemented
+in accordance with Ada semantics (e.g., modifying priorities as required
+to simulate ceiling locking),
+but there are often slight inaccuracies, most often in the area of
+absolutely respecting the priority rules on a single
+processor.
+Moreover, it is not possible in general to define the exact behavior,
+because the native threads implementations
+are not well enough documented.
+
+On systems where the @code{SCHED_FIFO} POSIX scheduling policy is supported,
+@cindex POSIX scheduling policies
+@cindex @code{SCHED_FIFO} scheduling policy
+native threads will provide a behavior very close to the @w{Annex D}
+requirements (i.e., a run-till-blocked scheduler with fixed priorities), but
+on some systems (in particular GNU/Linux and Solaris), you need to have root
+privileges to use the @code{SCHED_FIFO} policy.
+
+@item
+The @emph{FSU threads} library provides a completely accurate implementation
+of @w{Annex D}.
+Thus, operating with this library, GNAT is 100% compliant with both the core
+and all @w{Annex D}
+requirements.
+The formal validations for implementations offering
+a choice of threads packages are always carried out using the FSU
+threads option.
+@end itemize
+
+@noindent
+From these considerations, it might seem that FSU threads are the
+better choice,
+but that is by no means always the case. The FSU threads package
+operates with all Ada tasks appearing to the system to be a single
+thread. This is often considerably more efficient than operating
+with separate threads, since for example, switching between tasks
+can be accomplished without the (in some cases considerable)
+overhead of a context switch between two system threads. However,
+it means that you may well lose concurrency at the system
+level. Notably, some system operations (such as I/O) may block all
+tasks in a program and not just the calling task. More
+significantly, the FSU threads approach likely means you cannot
+take advantage of multiple processors, since for this you need
+separate threads (or even separate processes) to operate on
+different processors.
+
+For most programs, the native threads library is
+usually the better choice. Use the FSU threads if absolute
+conformance to @w{Annex D} is important for your application, or if
+you find that the improved efficiency of FSU threads is significant to you.
+
+Note also that to take full advantage of Florist and Glade, it is highly
+recommended that you use native threads.
+
+
+@node Choosing the Scheduling Policy
+@section Choosing the Scheduling Policy
+
+@noindent
+When using a POSIX threads implementation, you have a choice of several
+scheduling policies: @code{SCHED_FIFO},
+@cindex @code{SCHED_FIFO} scheduling policy
+@code{SCHED_RR}
+@cindex @code{SCHED_RR} scheduling policy
+and @code{SCHED_OTHER}.
+@cindex @code{SCHED_OTHER} scheduling policy
+Typically, the default is @code{SCHED_OTHER}, while using @code{SCHED_FIFO}
+or @code{SCHED_RR} requires special (e.g., root) privileges.
+
+By default, GNAT uses the @code{SCHED_OTHER} policy. To specify
+@code{SCHED_FIFO},
+@cindex @code{SCHED_FIFO} scheduling policy
+you can use one of the following:
+
+@itemize @bullet
+@item
+@code{pragma Time_Slice (0.0)}
+@cindex pragma Time_Slice
+@item
+the corresponding binder option @option{-T0}
+@cindex @option{-T0} option
+@item
+@code{pragma Task_Dispatching_Policy (FIFO_Within_Priorities)}
+@cindex pragma Task_Dispatching_Policy
+@end itemize
+
+@noindent
+To specify @code{SCHED_RR},
+@cindex @code{SCHED_RR} scheduling policy
+you should use @code{pragma Time_Slice} with a
+value greater than @code{0.0}, or else use the corresponding @option{-T}
+binder option.
+
+
+
+@node Solaris-Specific Considerations
+@section Solaris-Specific Considerations
+@cindex Solaris Sparc threads libraries
+
+@noindent
+This section addresses some topics related to the various threads libraries
+on Sparc Solaris and then provides some information on building and
+debugging 64-bit applications.
+
+@menu
+* Solaris Threads Issues::
+* Building and Debugging 64-bit Applications::
+@end menu
+
+
+@node Solaris Threads Issues
+@subsection Solaris Threads Issues
+
+@noindent
+Starting with version 3.14, GNAT under Solaris comes with a new tasking
+run-time library based on POSIX threads --- @emph{rts-pthread}.
+@cindex rts-pthread threads library
+This run-time library has the advantage of being mostly shared across all
+POSIX-compliant thread implementations, and it also provides under
+@w{Solaris 8} the @code{PTHREAD_PRIO_INHERIT}
+@cindex @code{PTHREAD_PRIO_INHERIT} policy (under rts-pthread)
+and @code{PTHREAD_PRIO_PROTECT}
+@cindex @code{PTHREAD_PRIO_PROTECT} policy (under rts-pthread)
+semantics that can be selected using the predefined pragma
+@code{Locking_Policy}
+@cindex pragma Locking_Policy (under rts-pthread)
+with respectively
+@code{Inheritance_Locking} and @code{Ceiling_Locking} as the policy.
+@cindex @code{Inheritance_Locking} (under rts-pthread)
+@cindex @code{Ceiling_Locking} (under rts-pthread)
+
+As explained above, the native run-time library is based on the Solaris thread
+library (@code{libthread}) and is the default library.
+The FSU run-time library is based on the FSU threads.
+@cindex FSU threads library
+
+Starting with Solaris 2.5.1, when the Solaris threads library is used
+(this is the default), programs
+compiled with GNAT can automatically take advantage of
+and can thus execute on multiple processors.
+The user can alternatively specify a processor on which the program should run
+to emulate a single-processor system. The multiprocessor / uniprocessor choice
+is made by
+setting the environment variable @code{GNAT_PROCESSOR}
+@cindex @code{GNAT_PROCESSOR} environment variable (on Sparc Solaris)
+to one of the following:
+
+@table @code
+@item -2
+Use the default configuration (run the program on all
+ available processors) - this is the same as having
+ @code{GNAT_PROCESSOR} unset
+
+@item -1
+Let the run-time implementation choose one processor and run the program on
+ that processor
+
+@item 0 .. Last_Proc
+Run the program on the specified processor.
+ @code{Last_Proc} is equal to @code{_SC_NPROCESSORS_CONF - 1}
+(where @code{_SC_NPROCESSORS_CONF} is a system variable).
+@end table
+
+
+@node Building and Debugging 64-bit Applications
+@subsection Building and Debugging 64-bit Applications
+
+@noindent
+In a 64-bit application, all the sources involved must be compiled with the
+@option{-m64} command-line option, and a specific GNAT library (compiled with
+this option) is required.
+The easiest way to build a 64bit application is to add
+@option{-m64 --RTS=m64} to the @command{gnatmake} flags.
+
+To debug these applications, dwarf-2 debug information is required, so you
+have to add @option{-gdwarf-2} to your gnatmake arguments.
+In addition, a special
+version of gdb, called @command{gdb64}, needs to be used.
+
+To summarize, building and debugging a ``Hello World'' program in 64-bit mode
+amounts to:
+
+@smallexample
+ $ gnatmake -m64 -gdwarf-2 --RTS=m64 hello.adb
+ $ gdb64 hello
+@end smallexample
+
+
+
+@node IRIX-Specific Considerations
+@section IRIX-Specific Considerations
+@cindex IRIX thread library
+
+@noindent
+On SGI IRIX, the thread library depends on which compiler is used.
+The @emph{o32 ABI} compiler comes with a run-time library based on the
+user-level @code{athread}
+library. Thus kernel-level capabilities such as nonblocking system
+calls or time slicing can only be achieved reliably by specifying different
+@code{sprocs} via the pragma @code{Task_Info}
+@cindex pragma Task_Info (and IRIX threads)
+and the
+@code{System.Task_Info} package.
+@cindex @code{System.Task_Info} package (and IRIX threads)
+See the @cite{GNAT Reference Manual} for further information.
+
+The @emph{n32 ABI} compiler comes with a run-time library based on the
+kernel POSIX threads and thus does not have the limitations mentioned above.
+
+
+@node Linux-Specific Considerations
+@section Linux-Specific Considerations
+@cindex Linux threads libraries
+
+@noindent
+The default thread library under GNU/Linux has the following disadvantages
+compared to other native thread libraries:
+
+@itemize @bullet
+@item The size of the task's stack is limited to 2 megabytes.
+@item The signal model is not POSIX compliant, which means that to send a
+ signal to the process, you need to send the signal to all threads,
+ 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
+@appendix Example of Binder Output File
+
+@noindent
+This Appendix displays the source code for @command{gnatbind}'s output
+file generated for a simple ``Hello World'' program.
+Comments have been added for clarification purposes.
+
+
+@smallexample @c adanocomment
+@iftex
+@leftskip=0cm
+@end iftex
+-- The package is called Ada_Main unless this name is actually used
+-- as a unit name in the partition, in which case some other unique
+-- name is used.
+
+with System;
+package ada_main is
+
+ Elab_Final_Code : Integer;
+ pragma Import (C, Elab_Final_Code, "__gnat_inside_elab_final_code");
+
+ -- The main program saves the parameters (argument count,
+ -- argument values, environment pointer) in global variables
+ -- for later access by other units including
+ -- Ada.Command_Line.
+
+ gnat_argc : Integer;
+ gnat_argv : System.Address;
+ gnat_envp : System.Address;
+
+ -- The actual variables are stored in a library routine. This
+ -- is useful for some shared library situations, where there
+ -- are problems if variables are not in the library.
+
+ pragma Import (C, gnat_argc);
+ pragma Import (C, gnat_argv);
+ pragma Import (C, gnat_envp);
+
+ -- The exit status is similarly an external location
+
+ gnat_exit_status : Integer;
+ pragma Import (C, gnat_exit_status);
+
+ GNAT_Version : constant String :=
+ "GNAT Version: 3.15w (20010315)";
+ pragma Export (C, GNAT_Version, "__gnat_version");
+
+ -- This is the generated adafinal routine that performs
+ -- finalization at the end of execution. In the case where
+ -- Ada is the main program, this main program makes a call
+ -- to adafinal at program termination.
+
+ procedure adafinal;
+ pragma Export (C, adafinal, "adafinal");
+
+ -- This is the generated adainit routine that performs
+ -- initialization at the start of execution. In the case
+ -- where Ada is the main program, this main program makes
+ -- a call to adainit at program startup.
+
+ procedure adainit;
+ pragma Export (C, adainit, "adainit");
+
+ -- This routine is called at the start of execution. It is
+ -- a dummy routine that is used by the debugger to breakpoint
+ -- at the start of execution.
+
+ procedure Break_Start;
+ pragma Import (C, Break_Start, "__gnat_break_start");
+
+ -- This is the actual generated main program (it would be
+ -- suppressed if the no main program switch were used). As
+ -- required by standard system conventions, this program has
+ -- the external name main.
+
+ function main
+ (argc : Integer;
+ argv : System.Address;
+ envp : System.Address)
+ return Integer;
+ pragma Export (C, main, "main");
+
+ -- The following set of constants give the version
+ -- identification values for every unit in the bound
+ -- partition. This identification is computed from all
+ -- dependent semantic units, and corresponds to the
+ -- string that would be returned by use of the
+ -- Body_Version or Version attributes.
+
+ type Version_32 is mod 2 ** 32;
+ u00001 : constant Version_32 := 16#7880BEB3#;
+ u00002 : constant Version_32 := 16#0D24CBD0#;
+ u00003 : constant Version_32 := 16#3283DBEB#;
+ u00004 : constant Version_32 := 16#2359F9ED#;
+ u00005 : constant Version_32 := 16#664FB847#;
+ u00006 : constant Version_32 := 16#68E803DF#;
+ u00007 : constant Version_32 := 16#5572E604#;
+ u00008 : constant Version_32 := 16#46B173D8#;
+ u00009 : constant Version_32 := 16#156A40CF#;
+ u00010 : constant Version_32 := 16#033DABE0#;
+ u00011 : constant Version_32 := 16#6AB38FEA#;
+ u00012 : constant Version_32 := 16#22B6217D#;
+ u00013 : constant Version_32 := 16#68A22947#;
+ u00014 : constant Version_32 := 16#18CC4A56#;
+ u00015 : constant Version_32 := 16#08258E1B#;
+ u00016 : constant Version_32 := 16#367D5222#;
+ u00017 : constant Version_32 := 16#20C9ECA4#;
+ u00018 : constant Version_32 := 16#50D32CB6#;
+ u00019 : constant Version_32 := 16#39A8BB77#;
+ u00020 : constant Version_32 := 16#5CF8FA2B#;
+ u00021 : constant Version_32 := 16#2F1EB794#;
+ u00022 : constant Version_32 := 16#31AB6444#;
+ u00023 : constant Version_32 := 16#1574B6E9#;
+ u00024 : constant Version_32 := 16#5109C189#;
+ u00025 : constant Version_32 := 16#56D770CD#;
+ u00026 : constant Version_32 := 16#02F9DE3D#;
+ u00027 : constant Version_32 := 16#08AB6B2C#;
+ u00028 : constant Version_32 := 16#3FA37670#;
+ u00029 : constant Version_32 := 16#476457A0#;
+ u00030 : constant Version_32 := 16#731E1B6E#;
+ u00031 : constant Version_32 := 16#23C2E789#;
+ u00032 : constant Version_32 := 16#0F1BD6A1#;
+ u00033 : constant Version_32 := 16#7C25DE96#;
+ u00034 : constant Version_32 := 16#39ADFFA2#;
+ u00035 : constant Version_32 := 16#571DE3E7#;
+ u00036 : constant Version_32 := 16#5EB646AB#;
+ u00037 : constant Version_32 := 16#4249379B#;
+ u00038 : constant Version_32 := 16#0357E00A#;
+ u00039 : constant Version_32 := 16#3784FB72#;
+ u00040 : constant Version_32 := 16#2E723019#;
+ u00041 : constant Version_32 := 16#623358EA#;
+ u00042 : constant Version_32 := 16#107F9465#;
+ u00043 : constant Version_32 := 16#6843F68A#;
+ u00044 : constant Version_32 := 16#63305874#;
+ u00045 : constant Version_32 := 16#31E56CE1#;
+ u00046 : constant Version_32 := 16#02917970#;
+ u00047 : constant Version_32 := 16#6CCBA70E#;
+ u00048 : constant Version_32 := 16#41CD4204#;
+ u00049 : constant Version_32 := 16#572E3F58#;
+ u00050 : constant Version_32 := 16#20729FF5#;
+ u00051 : constant Version_32 := 16#1D4F93E8#;
+ u00052 : constant Version_32 := 16#30B2EC3D#;
+ u00053 : constant Version_32 := 16#34054F96#;
+ u00054 : constant Version_32 := 16#5A199860#;
+ u00055 : constant Version_32 := 16#0E7F912B#;
+ u00056 : constant Version_32 := 16#5760634A#;
+ u00057 : constant Version_32 := 16#5D851835#;
+
+ -- The following Export pragmas export the version numbers
+ -- with symbolic names ending in B (for body) or S
+ -- (for spec) so that they can be located in a link. The
+ -- information provided here is sufficient to track down
+ -- the exact versions of units used in a given build.
+
+ pragma Export (C, u00001, "helloB");
+ pragma Export (C, u00002, "system__standard_libraryB");
+ pragma Export (C, u00003, "system__standard_libraryS");
+ pragma Export (C, u00004, "adaS");
+ pragma Export (C, u00005, "ada__text_ioB");
+ pragma Export (C, u00006, "ada__text_ioS");
+ pragma Export (C, u00007, "ada__exceptionsB");
+ pragma Export (C, u00008, "ada__exceptionsS");
+ pragma Export (C, u00009, "gnatS");
+ pragma Export (C, u00010, "gnat__heap_sort_aB");
+ pragma Export (C, u00011, "gnat__heap_sort_aS");
+ pragma Export (C, u00012, "systemS");
+ pragma Export (C, u00013, "system__exception_tableB");
+ pragma Export (C, u00014, "system__exception_tableS");
+ pragma Export (C, u00015, "gnat__htableB");
+ pragma Export (C, u00016, "gnat__htableS");
+ pragma Export (C, u00017, "system__exceptionsS");
+ pragma Export (C, u00018, "system__machine_state_operationsB");
+ pragma Export (C, u00019, "system__machine_state_operationsS");
+ pragma Export (C, u00020, "system__machine_codeS");
+ pragma Export (C, u00021, "system__storage_elementsB");
+ pragma Export (C, u00022, "system__storage_elementsS");
+ pragma Export (C, u00023, "system__secondary_stackB");
+ pragma Export (C, u00024, "system__secondary_stackS");
+ pragma Export (C, u00025, "system__parametersB");
+ pragma Export (C, u00026, "system__parametersS");
+ pragma Export (C, u00027, "system__soft_linksB");
+ pragma Export (C, u00028, "system__soft_linksS");
+ pragma Export (C, u00029, "system__stack_checkingB");
+ pragma Export (C, u00030, "system__stack_checkingS");
+ pragma Export (C, u00031, "system__tracebackB");
+ pragma Export (C, u00032, "system__tracebackS");
+ pragma Export (C, u00033, "ada__streamsS");
+ pragma Export (C, u00034, "ada__tagsB");
+ pragma Export (C, u00035, "ada__tagsS");
+ pragma Export (C, u00036, "system__string_opsB");
+ pragma Export (C, u00037, "system__string_opsS");
+ pragma Export (C, u00038, "interfacesS");
+ pragma Export (C, u00039, "interfaces__c_streamsB");
+ pragma Export (C, u00040, "interfaces__c_streamsS");
+ pragma Export (C, u00041, "system__file_ioB");
+ pragma Export (C, u00042, "system__file_ioS");
+ pragma Export (C, u00043, "ada__finalizationB");
+ pragma Export (C, u00044, "ada__finalizationS");
+ pragma Export (C, u00045, "system__finalization_rootB");
+ pragma Export (C, u00046, "system__finalization_rootS");
+ pragma Export (C, u00047, "system__finalization_implementationB");
+ pragma Export (C, u00048, "system__finalization_implementationS");
+ pragma Export (C, u00049, "system__string_ops_concat_3B");
+ pragma Export (C, u00050, "system__string_ops_concat_3S");
+ pragma Export (C, u00051, "system__stream_attributesB");
+ pragma Export (C, u00052, "system__stream_attributesS");
+ pragma Export (C, u00053, "ada__io_exceptionsS");
+ pragma Export (C, u00054, "system__unsigned_typesS");
+ pragma Export (C, u00055, "system__file_control_blockS");
+ pragma Export (C, u00056, "ada__finalization__list_controllerB");
+ pragma Export (C, u00057, "ada__finalization__list_controllerS");
+
+ -- BEGIN ELABORATION ORDER
+ -- ada (spec)
+ -- gnat (spec)
+ -- gnat.heap_sort_a (spec)
+ -- gnat.heap_sort_a (body)
+ -- gnat.htable (spec)
+ -- gnat.htable (body)
+ -- interfaces (spec)
+ -- system (spec)
+ -- system.machine_code (spec)
+ -- system.parameters (spec)
+ -- system.parameters (body)
+ -- interfaces.c_streams (spec)
+ -- interfaces.c_streams (body)
+ -- system.standard_library (spec)
+ -- ada.exceptions (spec)
+ -- system.exception_table (spec)
+ -- system.exception_table (body)
+ -- ada.io_exceptions (spec)
+ -- system.exceptions (spec)
+ -- system.storage_elements (spec)
+ -- system.storage_elements (body)
+ -- system.machine_state_operations (spec)
+ -- system.machine_state_operations (body)
+ -- system.secondary_stack (spec)
+ -- system.stack_checking (spec)
+ -- system.soft_links (spec)
+ -- system.soft_links (body)
+ -- system.stack_checking (body)
+ -- system.secondary_stack (body)
+ -- system.standard_library (body)
+ -- system.string_ops (spec)
+ -- system.string_ops (body)
+ -- ada.tags (spec)
+ -- ada.tags (body)
+ -- ada.streams (spec)
+ -- system.finalization_root (spec)
+ -- system.finalization_root (body)
+ -- system.string_ops_concat_3 (spec)
+ -- system.string_ops_concat_3 (body)
+ -- system.traceback (spec)
+ -- system.traceback (body)
+ -- ada.exceptions (body)
+ -- system.unsigned_types (spec)
+ -- system.stream_attributes (spec)
+ -- system.stream_attributes (body)
+ -- system.finalization_implementation (spec)
+ -- system.finalization_implementation (body)
+ -- ada.finalization (spec)
+ -- ada.finalization (body)
+ -- ada.finalization.list_controller (spec)
+ -- ada.finalization.list_controller (body)
+ -- system.file_control_block (spec)
+ -- system.file_io (spec)
+ -- system.file_io (body)
+ -- ada.text_io (spec)
+ -- ada.text_io (body)
+ -- hello (body)
+ -- END ELABORATION ORDER
+
+end ada_main;
+
+-- The following source file name pragmas allow the generated file
+-- names to be unique for different main programs. They are needed
+-- since the package name will always be Ada_Main.
+
+pragma Source_File_Name (ada_main, Spec_File_Name => "b~hello.ads");
+pragma Source_File_Name (ada_main, Body_File_Name => "b~hello.adb");
+
+-- Generated package body for Ada_Main starts here
+
+package body ada_main is
+
+ -- The actual finalization is performed by calling the
+ -- library routine in System.Standard_Library.Adafinal
+
+ procedure Do_Finalize;
+ pragma Import (C, Do_Finalize, "system__standard_library__adafinal");
+
+ -------------
+ -- adainit --
+ -------------
+
+@findex adainit
+ procedure adainit is
+
+ -- These booleans are set to True once the associated unit has
+ -- been elaborated. It is also used to avoid elaborating the
+ -- same unit twice.
+
+ E040 : Boolean;
+ pragma Import (Ada, E040, "interfaces__c_streams_E");
+
+ E008 : Boolean;
+ pragma Import (Ada, E008, "ada__exceptions_E");
+
+ E014 : Boolean;
+ pragma Import (Ada, E014, "system__exception_table_E");
+
+ E053 : Boolean;
+ pragma Import (Ada, E053, "ada__io_exceptions_E");
+
+ E017 : Boolean;
+ pragma Import (Ada, E017, "system__exceptions_E");
+
+ E024 : Boolean;
+ pragma Import (Ada, E024, "system__secondary_stack_E");
+
+ E030 : Boolean;
+ pragma Import (Ada, E030, "system__stack_checking_E");
+
+ E028 : Boolean;
+ pragma Import (Ada, E028, "system__soft_links_E");
+
+ E035 : Boolean;
+ pragma Import (Ada, E035, "ada__tags_E");
+
+ E033 : Boolean;
+ pragma Import (Ada, E033, "ada__streams_E");
+
+ E046 : Boolean;
+ pragma Import (Ada, E046, "system__finalization_root_E");
+
+ E048 : Boolean;
+ pragma Import (Ada, E048, "system__finalization_implementation_E");
+
+ E044 : Boolean;
+ pragma Import (Ada, E044, "ada__finalization_E");
+
+ E057 : Boolean;
+ pragma Import (Ada, E057, "ada__finalization__list_controller_E");
+
+ E055 : Boolean;
+ pragma Import (Ada, E055, "system__file_control_block_E");
+
+ E042 : Boolean;
+ pragma Import (Ada, E042, "system__file_io_E");
+
+ E006 : Boolean;
+ pragma Import (Ada, E006, "ada__text_io_E");
+
+ -- Set_Globals is a library routine that stores away the
+ -- value of the indicated set of global values in global
+ -- variables within the library.
+
+ procedure Set_Globals
+ (Main_Priority : Integer;
+ Time_Slice_Value : Integer;
+ WC_Encoding : Character;
+ Locking_Policy : Character;
+ Queuing_Policy : Character;
+ Task_Dispatching_Policy : Character;
+ Adafinal : System.Address;
+ Unreserve_All_Interrupts : Integer;
+ Exception_Tracebacks : Integer);
+@findex __gnat_set_globals
+ pragma Import (C, Set_Globals, "__gnat_set_globals");
+
+ -- SDP_Table_Build is a library routine used to build the
+ -- exception tables. See unit Ada.Exceptions in files
+ -- a-except.ads/adb for full details of how zero cost
+ -- exception handling works. This procedure, the call to
+ -- it, and the two following tables are all omitted if the
+ -- build is in longjmp/setjump exception mode.
+
+@findex SDP_Table_Build
+@findex Zero Cost Exceptions
+ procedure SDP_Table_Build
+ (SDP_Addresses : System.Address;
+ SDP_Count : Natural;
+ Elab_Addresses : System.Address;
+ Elab_Addr_Count : Natural);
+ pragma Import (C, SDP_Table_Build, "__gnat_SDP_Table_Build");
+
+ -- Table of Unit_Exception_Table addresses. Used for zero
+ -- cost exception handling to build the top level table.
+
+ ST : aliased constant array (1 .. 23) of System.Address := (
+ Hello'UET_Address,
+ Ada.Text_Io'UET_Address,
+ Ada.Exceptions'UET_Address,
+ Gnat.Heap_Sort_A'UET_Address,
+ System.Exception_Table'UET_Address,
+ System.Machine_State_Operations'UET_Address,
+ System.Secondary_Stack'UET_Address,
+ System.Parameters'UET_Address,
+ System.Soft_Links'UET_Address,
+ System.Stack_Checking'UET_Address,
+ System.Traceback'UET_Address,
+ Ada.Streams'UET_Address,
+ Ada.Tags'UET_Address,
+ System.String_Ops'UET_Address,
+ Interfaces.C_Streams'UET_Address,
+ System.File_Io'UET_Address,
+ Ada.Finalization'UET_Address,
+ System.Finalization_Root'UET_Address,
+ System.Finalization_Implementation'UET_Address,
+ System.String_Ops_Concat_3'UET_Address,
+ System.Stream_Attributes'UET_Address,
+ System.File_Control_Block'UET_Address,
+ Ada.Finalization.List_Controller'UET_Address);
+
+ -- Table of addresses of elaboration routines. Used for
+ -- zero cost exception handling to make sure these
+ -- addresses are included in the top level procedure
+ -- address table.
+
+ EA : aliased constant array (1 .. 23) of System.Address := (
+ adainit'Code_Address,
+ Do_Finalize'Code_Address,
+ Ada.Exceptions'Elab_Spec'Address,
+ System.Exceptions'Elab_Spec'Address,
+ Interfaces.C_Streams'Elab_Spec'Address,
+ System.Exception_Table'Elab_Body'Address,
+ Ada.Io_Exceptions'Elab_Spec'Address,
+ System.Stack_Checking'Elab_Spec'Address,
+ System.Soft_Links'Elab_Body'Address,
+ System.Secondary_Stack'Elab_Body'Address,
+ Ada.Tags'Elab_Spec'Address,
+ Ada.Tags'Elab_Body'Address,
+ Ada.Streams'Elab_Spec'Address,
+ System.Finalization_Root'Elab_Spec'Address,
+ Ada.Exceptions'Elab_Body'Address,
+ System.Finalization_Implementation'Elab_Spec'Address,
+ System.Finalization_Implementation'Elab_Body'Address,
+ Ada.Finalization'Elab_Spec'Address,
+ Ada.Finalization.List_Controller'Elab_Spec'Address,
+ System.File_Control_Block'Elab_Spec'Address,
+ System.File_Io'Elab_Body'Address,
+ Ada.Text_Io'Elab_Spec'Address,
+ Ada.Text_Io'Elab_Body'Address);
+
+ -- Start of processing for adainit
+
+ begin
+
+ -- Call SDP_Table_Build to build the top level procedure
+ -- table for zero cost exception handling (omitted in
+ -- longjmp/setjump mode).
+
+ SDP_Table_Build (ST'Address, 23, EA'Address, 23);
+
+ -- Call Set_Globals to record various information for
+ -- this partition. The values are derived by the binder
+ -- from information stored in the ali files by the compiler.
+
+@findex __gnat_set_globals
+ Set_Globals
+ (Main_Priority => -1,
+ -- Priority of main program, -1 if no pragma Priority used
+
+ Time_Slice_Value => -1,
+ -- Time slice from Time_Slice pragma, -1 if none used
+
+ WC_Encoding => 'b',
+ -- Wide_Character encoding used, default is brackets
+
+ Locking_Policy => ' ',
+ -- Locking_Policy used, default of space means not
+ -- specified, otherwise it is the first character of
+ -- the policy name.
+
+ Queuing_Policy => ' ',
+ -- Queuing_Policy used, default of space means not
+ -- specified, otherwise it is the first character of
+ -- the policy name.
+
+ Task_Dispatching_Policy => ' ',
+ -- Task_Dispatching_Policy used, default of space means
+ -- not specified, otherwise first character of the
+ -- policy name.
+
+ Adafinal => System.Null_Address,
+ -- Address of Adafinal routine, not used anymore
+
+ Unreserve_All_Interrupts => 0,
+ -- Set true if pragma Unreserve_All_Interrupts was used
+
+ Exception_Tracebacks => 0);
+ -- Indicates if exception tracebacks are enabled
+
+ Elab_Final_Code := 1;
+
+ -- Now we have the elaboration calls for all units in the partition.
+ -- The Elab_Spec and Elab_Body attributes generate references to the
+ -- implicit elaboration procedures generated by the compiler for
+ -- each unit that requires elaboration.
+
+ if not E040 then
+ Interfaces.C_Streams'Elab_Spec;
+ end if;
+ E040 := True;
+ if not E008 then
+ Ada.Exceptions'Elab_Spec;
+ end if;
+ if not E014 then
+ System.Exception_Table'Elab_Body;
+ E014 := True;
+ end if;
+ if not E053 then
+ Ada.Io_Exceptions'Elab_Spec;
+ E053 := True;
+ end if;
+ if not E017 then
+ System.Exceptions'Elab_Spec;
+ E017 := True;
+ end if;
+ if not E030 then
+ System.Stack_Checking'Elab_Spec;
+ end if;
+ if not E028 then
+ System.Soft_Links'Elab_Body;
+ E028 := True;
+ end if;
+ E030 := True;
+ if not E024 then
+ System.Secondary_Stack'Elab_Body;
+ E024 := True;
+ end if;
+ if not E035 then
+ Ada.Tags'Elab_Spec;
+ end if;
+ if not E035 then
+ Ada.Tags'Elab_Body;
+ E035 := True;
+ end if;
+ if not E033 then
+ Ada.Streams'Elab_Spec;
+ E033 := True;
+ end if;
+ if not E046 then
+ System.Finalization_Root'Elab_Spec;
+ end if;
+ E046 := True;
+ if not E008 then
+ Ada.Exceptions'Elab_Body;
+ E008 := True;
+ end if;
+ if not E048 then
+ System.Finalization_Implementation'Elab_Spec;
+ end if;
+ if not E048 then
+ System.Finalization_Implementation'Elab_Body;
+ E048 := True;
+ end if;
+ if not E044 then
+ Ada.Finalization'Elab_Spec;
+ end if;
+ E044 := True;
+ if not E057 then
+ Ada.Finalization.List_Controller'Elab_Spec;
+ end if;
+ E057 := True;
+ if not E055 then
+ System.File_Control_Block'Elab_Spec;
+ E055 := True;
+ end if;
+ if not E042 then
+ System.File_Io'Elab_Body;
+ E042 := True;
+ end if;
+ if not E006 then
+ Ada.Text_Io'Elab_Spec;
+ end if;
+ if not E006 then
+ Ada.Text_Io'Elab_Body;
+ E006 := True;
+ end if;
+
+ Elab_Final_Code := 0;
+ end adainit;
+
+ --------------
+ -- adafinal --
+ --------------
+
+@findex adafinal
+ procedure adafinal is
+ begin
+ Do_Finalize;
+ end adafinal;
+
+ ----------
+ -- main --
+ ----------
+
+ -- main is actually a function, as in the ANSI C standard,
+ -- defined to return the exit status. The three parameters
+ -- are the argument count, argument values and environment
+ -- pointer.
+
+@findex Main Program
+ function main
+ (argc : Integer;
+ argv : System.Address;
+ envp : System.Address)
+ return Integer
+ is
+ -- The initialize routine performs low level system
+ -- initialization using a standard library routine which
+ -- sets up signal handling and performs any other
+ -- required setup. The routine can be found in file
+ -- a-init.c.
+
+@findex __gnat_initialize
+ procedure initialize;
+ pragma Import (C, initialize, "__gnat_initialize");
+
+ -- The finalize routine performs low level system
+ -- finalization using a standard library routine. The
+ -- routine is found in file a-final.c and in the standard
+ -- distribution is a dummy routine that does nothing, so
+ -- really this is a hook for special user finalization.
+
+@findex __gnat_finalize
+ procedure finalize;
+ pragma Import (C, finalize, "__gnat_finalize");
+
+ -- We get to the main program of the partition by using
+ -- pragma Import because if we try to with the unit and
+ -- call it Ada style, then not only do we waste time
+ -- recompiling it, but also, we don't really know the right
+ -- switches (e.g. identifier character set) to be used
+ -- to compile it.
+
+ procedure Ada_Main_Program;
+ pragma Import (Ada, Ada_Main_Program, "_ada_hello");
+
+ -- Start of processing for main
+
+ begin
+ -- Save global variables
+
+ gnat_argc := argc;
+ gnat_argv := argv;
+ gnat_envp := envp;
+
+ -- Call low level system initialization
+
+ Initialize;
+
+ -- Call our generated Ada initialization routine
+
+ adainit;
+
+ -- This is the point at which we want the debugger to get
+ -- control
+
+ Break_Start;
+
+ -- Now we call the main program of the partition
+
+ Ada_Main_Program;
+
+ -- Perform Ada finalization
+
+ adafinal;
+
+ -- Perform low level system finalization
+
+ Finalize;
+
+ -- Return the proper exit status
+ return (gnat_exit_status);
+ end;
+
+-- This section is entirely comments, so it has no effect on the
+-- compilation of the Ada_Main package. It provides the list of
+-- object files and linker options, as well as some standard
+-- libraries needed for the link. The gnatlink utility parses
+-- this b~hello.adb file to read these comment lines to generate
+-- the appropriate command line arguments for the call to the
+-- system linker. The BEGIN/END lines are used for sentinels for
+-- this parsing operation.
+
+-- The exact file names will of course depend on the environment,
+-- host/target and location of files on the host system.
+
+@findex Object file list
+-- BEGIN Object file/option list
+ -- ./hello.o
+ -- -L./
+ -- -L/usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/
+ -- /usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/libgnat.a
+-- END Object file/option list
+
+end ada_main;
+@end smallexample
+
+@noindent
+The Ada code in the above example is exactly what is generated by the
+binder. We have added comments to more clearly indicate the function
+of each part of the generated @code{Ada_Main} package.
+
+The code is standard Ada in all respects, and can be processed by any
+tools that handle Ada. In particular, it is possible to use the debugger
+in Ada mode to debug the generated @code{Ada_Main} package. For example,
+suppose that for reasons that you do not understand, your program is crashing
+during elaboration of the body of @code{Ada.Text_IO}. To locate this bug,
+you can place a breakpoint on the call:
+
+@smallexample @c ada
+Ada.Text_Io'Elab_Body;
+@end smallexample
+
+@noindent
+and trace the elaboration routine for this package to find out where
+the problem might be (more usually of course you would be debugging
+elaboration code in your own application).
+
+
+@node Elaboration Order Handling in GNAT
+@appendix Elaboration Order Handling in GNAT
+@cindex Order of elaboration
+@cindex Elaboration control
+
+@menu
+* Elaboration Code in Ada 95::
+* Checking the Elaboration Order in Ada 95::
+* Controlling the Elaboration Order in Ada 95::
+* Controlling Elaboration in GNAT - Internal Calls::
+* Controlling Elaboration in GNAT - External Calls::
+* Default Behavior in GNAT - Ensuring Safety::
+* Treatment of Pragma Elaborate::
+* Elaboration Issues for Library Tasks::
+* Mixing Elaboration Models::
+* What to Do If the Default Elaboration Behavior Fails::
+* Elaboration for Access-to-Subprogram Values::
+* Summary of Procedures for Elaboration Control::
+* Other Elaboration Order Considerations::
+@end menu
+
+@noindent
+This chapter describes the handling of elaboration code in Ada 95 and
+in GNAT, and discusses how the order of elaboration of program units can
+be controlled in GNAT, either automatically or with explicit programming
+features.
+
+@node Elaboration Code in Ada 95
+@section Elaboration Code in Ada 95
+
+@noindent
+Ada 95 provides rather general mechanisms for executing code at elaboration
+time, that is to say before the main program starts executing. Such code arises
+in three contexts:
+
+@table @asis
+@item Initializers for variables.
+Variables declared at the library level, in package specs or bodies, can
+require initialization that is performed at elaboration time, as in:
+@smallexample @c ada
+@cartouche
+Sqrt_Half : Float := Sqrt (0.5);
+@end cartouche
+@end smallexample
+
+@item Package initialization code
+Code in a @code{BEGIN-END} section at the outer level of a package body is
+executed as part of the package body elaboration code.
+
+@item Library level task allocators
+Tasks that are declared using task allocators at the library level
+start executing immediately and hence can execute at elaboration time.
+@end table
+
+@noindent
+Subprogram calls are possible in any of these contexts, which means that
+any arbitrary part of the program may be executed as part of the elaboration
+code. It is even possible to write a program which does all its work at
+elaboration time, with a null main program, although stylistically this
+would usually be considered an inappropriate way to structure
+a program.
+
+An important concern arises in the context of elaboration code:
+we have to be sure that it is executed in an appropriate order. What we
+have is a series of elaboration code sections, potentially one section
+for each unit in the program. It is important that these execute
+in the correct order. Correctness here means that, taking the above
+example of the declaration of @code{Sqrt_Half},
+if some other piece of
+elaboration code references @code{Sqrt_Half},
+then it must run after the
+section of elaboration code that contains the declaration of
+@code{Sqrt_Half}.
+
+There would never be any order of elaboration problem if we made a rule
+that whenever you @code{with} a unit, you must elaborate both the spec and body
+of that unit before elaborating the unit doing the @code{with}'ing:
+
+@smallexample @c ada
+@group
+@cartouche
+with Unit_1;
+package Unit_2 is ...
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+would require that both the body and spec of @code{Unit_1} be elaborated
+before the spec of @code{Unit_2}. However, a rule like that would be far too
+restrictive. In particular, it would make it impossible to have routines
+in separate packages that were mutually recursive.
+
+You might think that a clever enough compiler could look at the actual
+elaboration code and determine an appropriate correct order of elaboration,
+but in the general case, this is not possible. Consider the following
+example.
+
+In the body of @code{Unit_1}, we have a procedure @code{Func_1}
+that references
+the variable @code{Sqrt_1}, which is declared in the elaboration code
+of the body of @code{Unit_1}:
+
+@smallexample @c ada
+@cartouche
+Sqrt_1 : Float := Sqrt (0.1);
+@end cartouche
+@end smallexample
+
+@noindent
+The elaboration code of the body of @code{Unit_1} also contains:
+
+@smallexample @c ada
+@group
+@cartouche
+if expression_1 = 1 then
+ Q := Unit_2.Func_2;
+end if;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+@code{Unit_2} is exactly parallel,
+it has a procedure @code{Func_2} that references
+the variable @code{Sqrt_2}, which is declared in the elaboration code of
+the body @code{Unit_2}:
+
+@smallexample @c ada
+@cartouche
+Sqrt_2 : Float := Sqrt (0.1);
+@end cartouche
+@end smallexample
+
+@noindent
+The elaboration code of the body of @code{Unit_2} also contains:
+
+@smallexample @c ada
+@group
+@cartouche
+if expression_2 = 2 then
+ Q := Unit_1.Func_1;
+end if;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Now the question is, which of the following orders of elaboration is
+acceptable:
+
+@smallexample
+@group
+Spec of Unit_1
+Spec of Unit_2
+Body of Unit_1
+Body of Unit_2
+@end group
+@end smallexample
+
+@noindent
+or
+
+@smallexample
+@group
+Spec of Unit_2
+Spec of Unit_1
+Body of Unit_2
+Body of Unit_1
+@end group
+@end smallexample
+
+@noindent
+If you carefully analyze the flow here, you will see that you cannot tell
+at compile time the answer to this question.
+If @code{expression_1} is not equal to 1,
+and @code{expression_2} is not equal to 2,
+then either order is acceptable, because neither of the function calls is
+executed. If both tests evaluate to true, then neither order is acceptable
+and in fact there is no correct order.
+
+If one of the two expressions is true, and the other is false, then one
+of the above orders is correct, and the other is incorrect. For example,
+if @code{expression_1} = 1 and @code{expression_2} /= 2,
+then the call to @code{Func_2}
+will occur, but not the call to @code{Func_1.}
+This means that it is essential
+to elaborate the body of @code{Unit_1} before
+the body of @code{Unit_2}, so the first
+order of elaboration is correct and the second is wrong.
+
+By making @code{expression_1} and @code{expression_2}
+depend on input data, or perhaps
+the time of day, we can make it impossible for the compiler or binder
+to figure out which of these expressions will be true, and hence it
+is impossible to guarantee a safe order of elaboration at run time.
+
+@node Checking the Elaboration Order in Ada 95
+@section Checking the Elaboration Order in Ada 95
+
+@noindent
+In some languages that involve the same kind of elaboration problems,
+e.g. Java and C++, the programmer is expected to worry about these
+ordering problems himself, and it is common to
+write a program in which an incorrect elaboration order gives
+surprising results, because it references variables before they
+are initialized.
+Ada 95 is designed to be a safe language, and a programmer-beware approach is
+clearly not sufficient. Consequently, the language provides three lines
+of defense:
+
+@table @asis
+@item Standard rules
+Some standard rules restrict the possible choice of elaboration
+order. In particular, if you @code{with} a unit, then its spec is always
+elaborated before the unit doing the @code{with}. Similarly, a parent
+spec is always elaborated before the child spec, and finally
+a spec is always elaborated before its corresponding body.
+
+@item Dynamic elaboration checks
+@cindex Elaboration checks
+@cindex Checks, elaboration
+Dynamic checks are made at run time, so that if some entity is accessed
+before it is elaborated (typically by means of a subprogram call)
+then the exception (@code{Program_Error}) is raised.
+
+@item Elaboration control
+Facilities are provided for the programmer to specify the desired order
+of elaboration.
+@end table
+
+Let's look at these facilities in more detail. First, the rules for
+dynamic checking. One possible rule would be simply to say that the
+exception is raised if you access a variable which has not yet been
+elaborated. The trouble with this approach is that it could require
+expensive checks on every variable reference. Instead Ada 95 has two
+rules which are a little more restrictive, but easier to check, and
+easier to state:
+
+@table @asis
+@item Restrictions on calls
+A subprogram can only be called at elaboration time if its body
+has been elaborated. The rules for elaboration given above guarantee
+that the spec of the subprogram has been elaborated before the
+call, but not the body. If this rule is violated, then the
+exception @code{Program_Error} is raised.
+
+@item Restrictions on instantiations
+A generic unit can only be instantiated if the body of the generic
+unit has been elaborated. Again, the rules for elaboration given above
+guarantee that the spec of the generic unit has been elaborated
+before the instantiation, but not the body. If this rule is
+violated, then the exception @code{Program_Error} is raised.
+@end table
+
+@noindent
+The idea is that if the body has been elaborated, then any variables
+it references must have been elaborated; by checking for the body being
+elaborated we guarantee that none of its references causes any
+trouble. As we noted above, this is a little too restrictive, because a
+subprogram that has no non-local references in its body may in fact be safe
+to call. However, it really would be unsafe to rely on this, because
+it would mean that the caller was aware of details of the implementation
+in the body. This goes against the basic tenets of Ada.
+
+A plausible implementation can be described as follows.
+A Boolean variable is associated with each subprogram
+and each generic unit. This variable is initialized to False, and is set to
+True at the point body is elaborated. Every call or instantiation checks the
+variable, and raises @code{Program_Error} if the variable is False.
+
+Note that one might think that it would be good enough to have one Boolean
+variable for each package, but that would not deal with cases of trying
+to call a body in the same package as the call
+that has not been elaborated yet.
+Of course a compiler may be able to do enough analysis to optimize away
+some of the Boolean variables as unnecessary, and @code{GNAT} indeed
+does such optimizations, but still the easiest conceptual model is to
+think of there being one variable per subprogram.
+
+@node Controlling the Elaboration Order in Ada 95
+@section Controlling the Elaboration Order in Ada 95
+
+@noindent
+In the previous section we discussed the rules in Ada 95 which ensure
+that @code{Program_Error} is raised if an incorrect elaboration order is
+chosen. This prevents erroneous executions, but we need mechanisms to
+specify a correct execution and avoid the exception altogether.
+To achieve this, Ada 95 provides a number of features for controlling
+the order of elaboration. We discuss these features in this section.
+
+First, there are several ways of indicating to the compiler that a given
+unit has no elaboration problems:
+
+@table @asis
+@item packages that do not require a body
+In Ada 95, a library package that does not require a body does not permit
+a body. This means that if we have a such a package, as in:
+
+@smallexample @c ada
+@group
+@cartouche
+package Definitions is
+ generic
+ type m is new integer;
+ package Subp is
+ type a is array (1 .. 10) of m;
+ type b is array (1 .. 20) of m;
+ end Subp;
+end Definitions;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+A package that @code{with}'s @code{Definitions} may safely instantiate
+@code{Definitions.Subp} because the compiler can determine that there
+definitely is no package body to worry about in this case
+
+@item pragma Pure
+@cindex pragma Pure
+@findex Pure
+Places sufficient restrictions on a unit to guarantee that
+no call to any subprogram in the unit can result in an
+elaboration problem. This means that the compiler does not need
+to worry about the point of elaboration of such units, and in
+particular, does not need to check any calls to any subprograms
+in this unit.
+
+@item pragma Preelaborate
+@findex Preelaborate
+@cindex pragma Preelaborate
+This pragma places slightly less stringent restrictions on a unit than
+does pragma Pure,
+but these restrictions are still sufficient to ensure that there
+are no elaboration problems with any calls to the unit.
+
+@item pragma Elaborate_Body
+@findex Elaborate_Body
+@cindex pragma Elaborate_Body
+This pragma requires that the body of a unit be elaborated immediately
+after its spec. Suppose a unit @code{A} has such a pragma,
+and unit @code{B} does
+a @code{with} of unit @code{A}. Recall that the standard rules require
+the spec of unit @code{A}
+to be elaborated before the @code{with}'ing unit; given the pragma in
+@code{A}, we also know that the body of @code{A}
+will be elaborated before @code{B}, so
+that calls to @code{A} are safe and do not need a check.
+@end table
+
+@noindent
+Note that,
+unlike pragma @code{Pure} and pragma @code{Preelaborate},
+the use of
+@code{Elaborate_Body} does not guarantee that the program is
+free of elaboration problems, because it may not be possible
+to satisfy the requested elaboration order.
+Let's go back to the example with @code{Unit_1} and @code{Unit_2}.
+If a programmer
+marks @code{Unit_1} as @code{Elaborate_Body},
+and not @code{Unit_2,} then the order of
+elaboration will be:
+
+@smallexample
+@group
+Spec of Unit_2
+Spec of Unit_1
+Body of Unit_1
+Body of Unit_2
+@end group
+@end smallexample
+
+@noindent
+Now that means that the call to @code{Func_1} in @code{Unit_2}
+need not be checked,
+it must be safe. But the call to @code{Func_2} in
+@code{Unit_1} may still fail if
+@code{Expression_1} is equal to 1,
+and the programmer must still take
+responsibility for this not being the case.
+
+If all units carry a pragma @code{Elaborate_Body}, then all problems are
+eliminated, except for calls entirely within a body, which are
+in any case fully under programmer control. However, using the pragma
+everywhere is not always possible.
+In particular, for our @code{Unit_1}/@code{Unit_2} example, if
+we marked both of them as having pragma @code{Elaborate_Body}, then
+clearly there would be no possible elaboration order.
+
+The above pragmas allow a server to guarantee safe use by clients, and
+clearly this is the preferable approach. Consequently a good rule in
+Ada 95 is to mark units as @code{Pure} or @code{Preelaborate} if possible,
+and if this is not possible,
+mark them as @code{Elaborate_Body} if possible.
+As we have seen, there are situations where neither of these
+three pragmas can be used.
+So we also provide methods for clients to control the
+order of elaboration of the servers on which they depend:
+
+@table @asis
+@item pragma Elaborate (unit)
+@findex Elaborate
+@cindex pragma Elaborate
+This pragma is placed in the context clause, after a @code{with} clause,
+and it requires that the body of the named unit be elaborated before
+the unit in which the pragma occurs. The idea is to use this pragma
+if the current unit calls at elaboration time, directly or indirectly,
+some subprogram in the named unit.
+
+@item pragma Elaborate_All (unit)
+@findex Elaborate_All
+@cindex pragma Elaborate_All
+This is a stronger version of the Elaborate pragma. Consider the
+following example:
+
+@smallexample
+Unit A @code{with}'s unit B and calls B.Func in elab code
+Unit B @code{with}'s unit C, and B.Func calls C.Func
+@end smallexample
+
+@noindent
+Now if we put a pragma @code{Elaborate (B)}
+in unit @code{A}, this ensures that the
+body of @code{B} is elaborated before the call, but not the
+body of @code{C}, so
+the call to @code{C.Func} could still cause @code{Program_Error} to
+be raised.
+
+The effect of a pragma @code{Elaborate_All} is stronger, it requires
+not only that the body of the named unit be elaborated before the
+unit doing the @code{with}, but also the bodies of all units that the
+named unit uses, following @code{with} links transitively. For example,
+if we put a pragma @code{Elaborate_All (B)} in unit @code{A},
+then it requires
+not only that the body of @code{B} be elaborated before @code{A},
+but also the
+body of @code{C}, because @code{B} @code{with}'s @code{C}.
+@end table
+
+@noindent
+We are now in a position to give a usage rule in Ada 95 for avoiding
+elaboration problems, at least if dynamic dispatching and access to
+subprogram values are not used. We will handle these cases separately
+later.
+
+The rule is simple. If a unit has elaboration code that can directly or
+indirectly make a call to a subprogram in a @code{with}'ed unit, or instantiate
+a generic unit in a @code{with}'ed unit,
+then if the @code{with}'ed unit does not have
+pragma @code{Pure} or @code{Preelaborate}, then the client should have
+a pragma @code{Elaborate_All}
+for the @code{with}'ed unit. By following this rule a client is
+assured that calls can be made without risk of an exception.
+If this rule is not followed, then a program may be in one of four
+states:
+
+@table @asis
+@item No order exists
+No order of elaboration exists which follows the rules, taking into
+account any @code{Elaborate}, @code{Elaborate_All},
+or @code{Elaborate_Body} pragmas. In
+this case, an Ada 95 compiler must diagnose the situation at bind
+time, and refuse to build an executable program.
+
+@item One or more orders exist, all incorrect
+One or more acceptable elaboration orders exists, and all of them
+generate an elaboration order problem. In this case, the binder
+can build an executable program, but @code{Program_Error} will be raised
+when the program is run.
+
+@item Several orders exist, some right, some incorrect
+One or more acceptable elaboration orders exists, and some of them
+work, and some do not. The programmer has not controlled
+the order of elaboration, so the binder may or may not pick one of
+the correct orders, and the program may or may not raise an
+exception when it is run. This is the worst case, because it means
+that the program may fail when moved to another compiler, or even
+another version of the same compiler.
+
+@item One or more orders exists, all correct
+One ore more acceptable elaboration orders exist, and all of them
+work. In this case the program runs successfully. This state of
+affairs can be guaranteed by following the rule we gave above, but
+may be true even if the rule is not followed.
+@end table
+
+@noindent
+Note that one additional advantage of following our Elaborate_All rule
+is that the program continues to stay in the ideal (all orders OK) state
+even if maintenance
+changes some bodies of some subprograms. Conversely, if a program that does
+not follow this rule happens to be safe at some point, this state of affairs
+may deteriorate silently as a result of maintenance changes.
+
+You may have noticed that the above discussion did not mention
+the use of @code{Elaborate_Body}. This was a deliberate omission. If you
+@code{with} an @code{Elaborate_Body} unit, it still may be the case that
+code in the body makes calls to some other unit, so it is still necessary
+to use @code{Elaborate_All} on such units.
+
+@node Controlling Elaboration in GNAT - Internal Calls
+@section Controlling Elaboration in GNAT - Internal Calls
+
+@noindent
+In the case of internal calls, i.e. calls within a single package, the
+programmer has full control over the order of elaboration, and it is up
+to the programmer to elaborate declarations in an appropriate order. For
+example writing:
+
+@smallexample @c ada
+@group
+@cartouche
+function One return Float;
+
+Q : Float := One;
+
+function One return Float is
+begin
+ return 1.0;
+end One;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+will obviously raise @code{Program_Error} at run time, because function
+One will be called before its body is elaborated. In this case GNAT will
+generate a warning that the call will raise @code{Program_Error}:
+
+@smallexample
+@group
+@cartouche
+ 1. procedure y is
+ 2. function One return Float;
+ 3.
+ 4. Q : Float := One;
+ |
+ >>> warning: cannot call "One" before body is elaborated
+ >>> warning: Program_Error will be raised at run time
+
+ 5.
+ 6. function One return Float is
+ 7. begin
+ 8. return 1.0;
+ 9. end One;
+10.
+11. begin
+12. null;
+13. end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Note that in this particular case, it is likely that the call is safe, because
+the function @code{One} does not access any global variables.
+Nevertheless in Ada 95, we do not want the validity of the check to depend on
+the contents of the body (think about the separate compilation case), so this
+is still wrong, as we discussed in the previous sections.
+
+The error is easily corrected by rearranging the declarations so that the
+body of One appears before the declaration containing the call
+(note that in Ada 95,
+declarations can appear in any order, so there is no restriction that
+would prevent this reordering, and if we write:
+
+@smallexample @c ada
+@group
+@cartouche
+function One return Float;
+
+function One return Float is
+begin
+ return 1.0;
+end One;
+
+Q : Float := One;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+then all is well, no warning is generated, and no
+@code{Program_Error} exception
+will be raised.
+Things are more complicated when a chain of subprograms is executed:
+
+@smallexample @c ada
+@group
+@cartouche
+function A return Integer;
+function B return Integer;
+function C return Integer;
+
+function B return Integer is begin return A; end;
+function C return Integer is begin return B; end;
+
+X : Integer := C;
+
+function A return Integer is begin return 1; end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Now the call to @code{C}
+at elaboration time in the declaration of @code{X} is correct, because
+the body of @code{C} is already elaborated,
+and the call to @code{B} within the body of
+@code{C} is correct, but the call
+to @code{A} within the body of @code{B} is incorrect, because the body
+of @code{A} has not been elaborated, so @code{Program_Error}
+will be raised on the call to @code{A}.
+In this case GNAT will generate a
+warning that @code{Program_Error} may be
+raised at the point of the call. Let's look at the warning:
+
+@smallexample
+@group
+@cartouche
+ 1. procedure x is
+ 2. function A return Integer;
+ 3. function B return Integer;
+ 4. function C return Integer;
+ 5.
+ 6. function B return Integer is begin return A; end;
+ |
+ >>> warning: call to "A" before body is elaborated may
+ raise Program_Error
+ >>> warning: "B" called at line 7
+ >>> warning: "C" called at line 9
+
+ 7. function C return Integer is begin return B; end;
+ 8.
+ 9. X : Integer := C;
+10.
+11. function A return Integer is begin return 1; end;
+12.
+13. begin
+14. null;
+15. end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Note that the message here says ``may raise'', instead of the direct case,
+where the message says ``will be raised''. That's because whether
+@code{A} is
+actually called depends in general on run-time flow of control.
+For example, if the body of @code{B} said
+
+@smallexample @c ada
+@group
+@cartouche
+function B return Integer is
+begin
+ if some-condition-depending-on-input-data then
+ return A;
+ else
+ return 1;
+ end if;
+end B;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+then we could not know until run time whether the incorrect call to A would
+actually occur, so @code{Program_Error} might
+or might not be raised. It is possible for a compiler to
+do a better job of analyzing bodies, to
+determine whether or not @code{Program_Error}
+might be raised, but it certainly
+couldn't do a perfect job (that would require solving the halting problem
+and is provably impossible), and because this is a warning anyway, it does
+not seem worth the effort to do the analysis. Cases in which it
+would be relevant are rare.
+
+In practice, warnings of either of the forms given
+above will usually correspond to
+real errors, and should be examined carefully and eliminated.
+In the rare case where a warning is bogus, it can be suppressed by any of
+the following methods:
+
+@itemize @bullet
+@item
+Compile with the @option{-gnatws} switch set
+
+@item
+Suppress @code{Elaboration_Check} for the called subprogram
+
+@item
+Use pragma @code{Warnings_Off} to turn warnings off for the call
+@end itemize
+
+@noindent
+For the internal elaboration check case,
+GNAT by default generates the
+necessary run-time checks to ensure
+that @code{Program_Error} is raised if any
+call fails an elaboration check. Of course this can only happen if a
+warning has been issued as described above. The use of pragma
+@code{Suppress (Elaboration_Check)} may (but is not guaranteed to) suppress
+some of these checks, meaning that it may be possible (but is not
+guaranteed) for a program to be able to call a subprogram whose body
+is not yet elaborated, without raising a @code{Program_Error} exception.
+
+@node Controlling Elaboration in GNAT - External Calls
+@section Controlling Elaboration in GNAT - External Calls
+
+@noindent
+The previous section discussed the case in which the execution of a
+particular thread of elaboration code occurred entirely within a
+single unit. This is the easy case to handle, because a programmer
+has direct and total control over the order of elaboration, and
+furthermore, checks need only be generated in cases which are rare
+and which the compiler can easily detect.
+The situation is more complex when separate compilation is taken into account.
+Consider the following:
+
+@smallexample @c ada
+@cartouche
+@group
+package Math is
+ function Sqrt (Arg : Float) return Float;
+end Math;
+
+package body Math is
+ function Sqrt (Arg : Float) return Float is
+ begin
+ ...
+ end Sqrt;
+end Math;
+@end group
+@group
+with Math;
+package Stuff is
+ X : Float := Math.Sqrt (0.5);
+end Stuff;
+
+with Stuff;
+procedure Main is
+begin
+ ...
+end Main;
+@end group
+@end cartouche
+@end smallexample
+
+@noindent
+where @code{Main} is the main program. When this program is executed, the
+elaboration code must first be executed, and one of the jobs of the
+binder is to determine the order in which the units of a program are
+to be elaborated. In this case we have four units: the spec and body
+of @code{Math},
+the spec of @code{Stuff} and the body of @code{Main}).
+In what order should the four separate sections of elaboration code
+be executed?
+
+There are some restrictions in the order of elaboration that the binder
+can choose. In particular, if unit U has a @code{with}
+for a package @code{X}, then you
+are assured that the spec of @code{X}
+is elaborated before U , but you are
+not assured that the body of @code{X}
+is elaborated before U.
+This means that in the above case, the binder is allowed to choose the
+order:
+
+@smallexample
+spec of Math
+spec of Stuff
+body of Math
+body of Main
+@end smallexample
+
+@noindent
+but that's not good, because now the call to @code{Math.Sqrt}
+that happens during
+the elaboration of the @code{Stuff}
+spec happens before the body of @code{Math.Sqrt} is
+elaborated, and hence causes @code{Program_Error} exception to be raised.
+At first glance, one might say that the binder is misbehaving, because
+obviously you want to elaborate the body of something you @code{with}
+first, but
+that is not a general rule that can be followed in all cases. Consider
+
+@smallexample @c ada
+@group
+@cartouche
+package X is ...
+
+package Y is ...
+
+with X;
+package body Y is ...
+
+with Y;
+package body X is ...
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+This is a common arrangement, and, apart from the order of elaboration
+problems that might arise in connection with elaboration code, this works fine.
+A rule that says that you must first elaborate the body of anything you
+@code{with} cannot work in this case:
+the body of @code{X} @code{with}'s @code{Y},
+which means you would have to
+elaborate the body of @code{Y} first, but that @code{with}'s @code{X},
+which means
+you have to elaborate the body of @code{X} first, but ... and we have a
+loop that cannot be broken.
+
+It is true that the binder can in many cases guess an order of elaboration
+that is unlikely to cause a @code{Program_Error}
+exception to be raised, and it tries to do so (in the
+above example of @code{Math/Stuff/Spec}, the GNAT binder will
+by default
+elaborate the body of @code{Math} right after its spec, so all will be well).
+
+However, a program that blindly relies on the binder to be helpful can
+get into trouble, as we discussed in the previous sections, so
+GNAT
+provides a number of facilities for assisting the programmer in
+developing programs that are robust with respect to elaboration order.
+
+@node Default Behavior in GNAT - Ensuring Safety
+@section Default Behavior in GNAT - Ensuring Safety
+
+@noindent
+The default behavior in GNAT ensures elaboration safety. In its
+default mode GNAT implements the
+rule we previously described as the right approach. Let's restate it:
+
+@itemize
+@item
+@emph{If a unit has elaboration code that can directly or indirectly make a
+call to a subprogram in a @code{with}'ed unit, or instantiate a generic unit
+in a @code{with}'ed unit, then if the @code{with}'ed unit
+does not have pragma @code{Pure} or
+@code{Preelaborate}, then the client should have an
+@code{Elaborate_All} for the @code{with}'ed unit.}
+@end itemize
+
+@noindent
+By following this rule a client is assured that calls and instantiations
+can be made without risk of an exception.
+
+In this mode GNAT traces all calls that are potentially made from
+elaboration code, and puts in any missing implicit @code{Elaborate_All}
+pragmas.
+The advantage of this approach is that no elaboration problems
+are possible if the binder can find an elaboration order that is
+consistent with these implicit @code{Elaborate_All} pragmas. The
+disadvantage of this approach is that no such order may exist.
+
+If the binder does not generate any diagnostics, then it means that it
+has found an elaboration order that is guaranteed to be safe. However,
+the binder may still be relying on implicitly generated
+@code{Elaborate_All} pragmas so portability to other compilers than
+GNAT is not guaranteed.
+
+If it is important to guarantee portability, then the compilations should
+use the
+@option{-gnatwl}
+(warn on elaboration problems) switch. This will cause warning messages
+to be generated indicating the missing @code{Elaborate_All} pragmas.
+Consider the following source program:
+
+@smallexample @c ada
+@group
+@cartouche
+with k;
+package j is
+ m : integer := k.r;
+end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+where it is clear that there
+should be a pragma @code{Elaborate_All}
+for unit @code{k}. An implicit pragma will be generated, and it is
+likely that the binder will be able to honor it. However, if you want
+to port this program to some other Ada compiler than GNAT.
+it is safer to include the pragma explicitly in the source. If this
+unit is compiled with the
+@option{-gnatwl}
+switch, then the compiler outputs a warning:
+
+@smallexample
+@group
+@cartouche
+1. with k;
+2. package j is
+3. m : integer := k.r;
+ |
+ >>> warning: call to "r" may raise Program_Error
+ >>> warning: missing pragma Elaborate_All for "k"
+
+4. end;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+and these warnings can be used as a guide for supplying manually
+the missing pragmas. It is usually a bad idea to use this warning
+option during development. That's because it will warn you when
+you need to put in a pragma, but cannot warn you when it is time
+to take it out. So the use of pragma Elaborate_All may lead to
+unnecessary dependencies and even false circularities.
+
+This default mode is more restrictive than the Ada Reference
+Manual, and it is possible to construct programs which will compile
+using the dynamic model described there, but will run into a
+circularity using the safer static model we have described.
+
+Of course any Ada compiler must be able to operate in a mode
+consistent with the requirements of the Ada Reference Manual,
+and in particular must have the capability of implementing the
+standard dynamic model of elaboration with run-time checks.
+
+In GNAT, this standard mode can be achieved either by the use of
+the @option{-gnatE} switch on the compiler (@code{gcc} or @code{gnatmake})
+command, or by the use of the configuration pragma:
+
+@smallexample @c ada
+pragma Elaboration_Checks (RM);
+@end smallexample
+
+@noindent
+Either approach will cause the unit affected to be compiled using the
+standard dynamic run-time elaboration checks described in the Ada
+Reference Manual. The static model is generally preferable, since it
+is clearly safer to rely on compile and link time checks rather than
+run-time checks. However, in the case of legacy code, it may be
+difficult to meet the requirements of the static model. This
+issue is further discussed in
+@ref{What to Do If the Default Elaboration Behavior Fails}.
+
+Note that the static model provides a strict subset of the allowed
+behavior and programs of the Ada Reference Manual, so if you do
+adhere to the static model and no circularities exist,
+then you are assured that your program will
+work using the dynamic model, providing that you remove any
+pragma Elaborate statements from the source.
+
+@node Treatment of Pragma Elaborate
+@section Treatment of Pragma Elaborate
+@cindex Pragma Elaborate
+
+@noindent
+The use of @code{pragma Elaborate}
+should generally be avoided in Ada 95 programs.
+The reason for this is that there is no guarantee that transitive calls
+will be properly handled. Indeed at one point, this pragma was placed
+in Annex J (Obsolescent Features), on the grounds that it is never useful.
+
+Now that's a bit restrictive. In practice, the case in which
+@code{pragma Elaborate} is useful is when the caller knows that there
+are no transitive calls, or that the called unit contains all necessary
+transitive @code{pragma Elaborate} statements, and legacy code often
+contains such uses.
+
+Strictly speaking the static mode in GNAT should ignore such pragmas,
+since there is no assurance at compile time that the necessary safety
+conditions are met. In practice, this would cause GNAT to be incompatible
+with correctly written Ada 83 code that had all necessary
+@code{pragma Elaborate} statements in place. Consequently, we made the
+decision that GNAT in its default mode will believe that if it encounters
+a @code{pragma Elaborate} then the programmer knows what they are doing,
+and it will trust that no elaboration errors can occur.
+
+The result of this decision is two-fold. First to be safe using the
+static mode, you should remove all @code{pragma Elaborate} statements.
+Second, when fixing circularities in existing code, you can selectively
+use @code{pragma Elaborate} statements to convince the static mode of
+GNAT that it need not generate an implicit @code{pragma Elaborate_All}
+statement.
+
+When using the static mode with @option{-gnatwl}, any use of
+@code{pragma Elaborate} will generate a warning about possible
+problems.
+
+@node Elaboration Issues for Library Tasks
+@section Elaboration Issues for Library Tasks
+@cindex Library tasks, elaboration issues
+@cindex Elaboration of library tasks
+
+@noindent
+In this section we examine special elaboration issues that arise for
+programs that declare library level tasks.
+
+Generally the model of execution of an Ada program is that all units are
+elaborated, and then execution of the program starts. However, the
+declaration of library tasks definitely does not fit this model. The
+reason for this is that library tasks start as soon as they are declared
+(more precisely, as soon as the statement part of the enclosing package
+body is reached), that is to say before elaboration
+of the program is complete. This means that if such a task calls a
+subprogram, or an entry in another task, the callee may or may not be
+elaborated yet, and in the standard
+Reference Manual model of dynamic elaboration checks, you can even
+get timing dependent Program_Error exceptions, since there can be
+a race between the elaboration code and the task code.
+
+The static model of elaboration in GNAT seeks to avoid all such
+dynamic behavior, by being conservative, and the conservative
+approach in this particular case is to assume that all the code
+in a task body is potentially executed at elaboration time if
+a task is declared at the library level.
+
+This can definitely result in unexpected circularities. Consider
+the following example
+
+@smallexample @c ada
+package Decls is
+ task Lib_Task is
+ entry Start;
+ end Lib_Task;
+
+ type My_Int is new Integer;
+
+ function Ident (M : My_Int) return My_Int;
+end Decls;
+
+with Utils;
+package body Decls is
+ task body Lib_Task is
+ begin
+ accept Start;
+ Utils.Put_Val (2);
+ end Lib_Task;
+
+ function Ident (M : My_Int) return My_Int is
+ begin
+ return M;
+ end Ident;
+end Decls;
+
+with Decls;
+package Utils is
+ procedure Put_Val (Arg : Decls.My_Int);
+end Utils;
+
+with Text_IO;
+package body Utils is
+ procedure Put_Val (Arg : Decls.My_Int) is
+ begin
+ Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg)));
+ end Put_Val;
+end Utils;
+
+with Decls;
+procedure Main is
+begin
+ Decls.Lib_Task.Start;
+end;
+@end smallexample
+
+@noindent
+If the above example is compiled in the default static elaboration
+mode, then a circularity occurs. The circularity comes from the call
+@code{Utils.Put_Val} in the task body of @code{Decls.Lib_Task}. Since
+this call occurs in elaboration code, we need an implicit pragma
+@code{Elaborate_All} for @code{Utils}. This means that not only must
+the spec and body of @code{Utils} be elaborated before the body
+of @code{Decls}, but also the spec and body of any unit that is
+@code{with'ed} by the body of @code{Utils} must also be elaborated before
+the body of @code{Decls}. This is the transitive implication of
+pragma @code{Elaborate_All} and it makes sense, because in general
+the body of @code{Put_Val} might have a call to something in a
+@code{with'ed} unit.
+
+In this case, the body of Utils (actually its spec) @code{with's}
+@code{Decls}. Unfortunately this means that the body of @code{Decls}
+must be elaborated before itself, in case there is a call from the
+body of @code{Utils}.
+
+Here is the exact chain of events we are worrying about:
+
+@enumerate
+@item
+In the body of @code{Decls} a call is made from within the body of a library
+task to a subprogram in the package @code{Utils}. Since this call may
+occur at elaboration time (given that the task is activated at elaboration
+time), we have to assume the worst, i.e. that the
+call does happen at elaboration time.
+
+@item
+This means that the body and spec of @code{Util} must be elaborated before
+the body of @code{Decls} so that this call does not cause an access before
+elaboration.
+
+@item
+Within the body of @code{Util}, specifically within the body of
+@code{Util.Put_Val} there may be calls to any unit @code{with}'ed
+by this package.
+
+@item
+One such @code{with}'ed package is package @code{Decls}, so there
+might be a call to a subprogram in @code{Decls} in @code{Put_Val}.
+In fact there is such a call in this example, but we would have to
+assume that there was such a call even if it were not there, since
+we are not supposed to write the body of @code{Decls} knowing what
+is in the body of @code{Utils}; certainly in the case of the
+static elaboration model, the compiler does not know what is in
+other bodies and must assume the worst.
+
+@item
+This means that the spec and body of @code{Decls} must also be
+elaborated before we elaborate the unit containing the call, but
+that unit is @code{Decls}! This means that the body of @code{Decls}
+must be elaborated before itself, and that's a circularity.
+@end enumerate
+
+@noindent
+Indeed, if you add an explicit pragma Elaborate_All for @code{Utils} in
+the body of @code{Decls} you will get a true Ada Reference Manual
+circularity that makes the program illegal.
+
+In practice, we have found that problems with the static model of
+elaboration in existing code often arise from library tasks, so
+we must address this particular situation.
+
+Note that if we compile and run the program above, using the dynamic model of
+elaboration (that is to say use the @option{-gnatE} switch),
+then it compiles, binds,
+links, and runs, printing the expected result of 2. Therefore in some sense
+the circularity here is only apparent, and we need to capture
+the properties of this program that distinguish it from other library-level
+tasks that have real elaboration problems.
+
+We have four possible answers to this question:
+
+@itemize @bullet
+
+@item
+Use the dynamic model of elaboration.
+
+If we use the @option{-gnatE} switch, then as noted above, the program works.
+Why is this? If we examine the task body, it is apparent that the task cannot
+proceed past the
+@code{accept} statement until after elaboration has been completed, because
+the corresponding entry call comes from the main program, not earlier.
+This is why the dynamic model works here. But that's really giving
+up on a precise analysis, and we prefer to take this approach only if we cannot
+solve the
+problem in any other manner. So let us examine two ways to reorganize
+the program to avoid the potential elaboration problem.
+
+@item
+Split library tasks into separate packages.
+
+Write separate packages, so that library tasks are isolated from
+other declarations as much as possible. Let us look at a variation on
+the above program.
+
+@smallexample @c ada
+package Decls1 is
+ task Lib_Task is
+ entry Start;
+ end Lib_Task;
+end Decls1;
+
+with Utils;
+package body Decls1 is
+ task body Lib_Task is
+ begin
+ accept Start;
+ Utils.Put_Val (2);
+ end Lib_Task;
+end Decls1;
+
+package Decls2 is
+ type My_Int is new Integer;
+ function Ident (M : My_Int) return My_Int;
+end Decls2;
+
+with Utils;
+package body Decls2 is
+ function Ident (M : My_Int) return My_Int is
+ begin
+ return M;
+ end Ident;
+end Decls2;
+
+with Decls2;
+package Utils is
+ procedure Put_Val (Arg : Decls2.My_Int);
+end Utils;
+
+with Text_IO;
+package body Utils is
+ procedure Put_Val (Arg : Decls2.My_Int) is
+ begin
+ Text_IO.Put_Line (Decls2.My_Int'Image (Decls2.Ident (Arg)));
+ end Put_Val;
+end Utils;
+
+with Decls1;
+procedure Main is
+begin
+ Decls1.Lib_Task.Start;
+end;
+@end smallexample
+
+@noindent
+All we have done is to split @code{Decls} into two packages, one
+containing the library task, and one containing everything else. Now
+there is no cycle, and the program compiles, binds, links and executes
+using the default static model of elaboration.
+
+@item
+Declare separate task types.
+
+A significant part of the problem arises because of the use of the
+single task declaration form. This means that the elaboration of
+the task type, and the elaboration of the task itself (i.e. the
+creation of the task) happen at the same time. A good rule
+of style in Ada 95 is to always create explicit task types. By
+following the additional step of placing task objects in separate
+packages from the task type declaration, many elaboration problems
+are avoided. Here is another modified example of the example program:
+
+@smallexample @c ada
+package Decls is
+ task type Lib_Task_Type is
+ entry Start;
+ end Lib_Task_Type;
+
+ type My_Int is new Integer;
+
+ function Ident (M : My_Int) return My_Int;
+end Decls;
+
+with Utils;
+package body Decls is
+ task body Lib_Task_Type is
+ begin
+ accept Start;
+ Utils.Put_Val (2);
+ end Lib_Task_Type;
+
+ function Ident (M : My_Int) return My_Int is
+ begin
+ return M;
+ end Ident;
+end Decls;
+
+with Decls;
+package Utils is
+ procedure Put_Val (Arg : Decls.My_Int);
+end Utils;
+
+with Text_IO;
+package body Utils is
+ procedure Put_Val (Arg : Decls.My_Int) is
+ begin
+ Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg)));
+ end Put_Val;
+end Utils;
+
+with Decls;
+package Declst is
+ Lib_Task : Decls.Lib_Task_Type;
+end Declst;
+
+with Declst;
+procedure Main is
+begin
+ Declst.Lib_Task.Start;
+end;
+@end smallexample
+
+@noindent
+What we have done here is to replace the @code{task} declaration in
+package @code{Decls} with a @code{task type} declaration. Then we
+introduce a separate package @code{Declst} to contain the actual
+task object. This separates the elaboration issues for
+the @code{task type}
+declaration, which causes no trouble, from the elaboration issues
+of the task object, which is also unproblematic, since it is now independent
+of the elaboration of @code{Utils}.
+This separation of concerns also corresponds to
+a generally sound engineering principle of separating declarations
+from instances. This version of the program also compiles, binds, links,
+and executes, generating the expected output.
+
+@item
+Use No_Entry_Calls_In_Elaboration_Code restriction.
+@cindex No_Entry_Calls_In_Elaboration_Code
+
+The previous two approaches described how a program can be restructured
+to avoid the special problems caused by library task bodies. in practice,
+however, such restructuring may be difficult to apply to existing legacy code,
+so we must consider solutions that do not require massive rewriting.
+
+Let us consider more carefully why our original sample program works
+under the dynamic model of elaboration. The reason is that the code
+in the task body blocks immediately on the @code{accept}
+statement. Now of course there is nothing to prohibit elaboration
+code from making entry calls (for example from another library level task),
+so we cannot tell in isolation that
+the task will not execute the accept statement during elaboration.
+
+However, in practice it is very unusual to see elaboration code
+make any entry calls, and the pattern of tasks starting
+at elaboration time and then immediately blocking on @code{accept} or
+@code{select} statements is very common. What this means is that
+the compiler is being too pessimistic when it analyzes the
+whole package body as though it might be executed at elaboration
+time.
+
+If we know that the elaboration code contains no entry calls, (a very safe
+assumption most of the time, that could almost be made the default
+behavior), then we can compile all units of the program under control
+of the following configuration pragma:
+
+@smallexample
+pragma Restrictions (No_Entry_Calls_In_Elaboration_Code);
+@end smallexample
+
+@noindent
+This pragma can be placed in the @file{gnat.adc} file in the usual
+manner. If we take our original unmodified program and compile it
+in the presence of a @file{gnat.adc} containing the above pragma,
+then once again, we can compile, bind, link, and execute, obtaining
+the expected result. In the presence of this pragma, the compiler does
+not trace calls in a task body, that appear after the first @code{accept}
+or @code{select} statement, and therefore does not report a potential
+circularity in the original program.
+
+The compiler will check to the extent it can that the above
+restriction is not violated, but it is not always possible to do a
+complete check at compile time, so it is important to use this
+pragma only if the stated restriction is in fact met, that is to say
+no task receives an entry call before elaboration of all units is completed.
+
+@end itemize
+
+@node Mixing Elaboration Models
+@section Mixing Elaboration Models
+@noindent
+So far, we have assumed that the entire program is either compiled
+using the dynamic model or static model, ensuring consistency. It
+is possible to mix the two models, but rules have to be followed
+if this mixing is done to ensure that elaboration checks are not
+omitted.
+
+The basic rule is that @emph{a unit compiled with the static model cannot
+be @code{with'ed} by a unit compiled with the dynamic model}. The
+reason for this is that in the static model, a unit assumes that
+its clients guarantee to use (the equivalent of) pragma
+@code{Elaborate_All} so that no elaboration checks are required
+in inner subprograms, and this assumption is violated if the
+client is compiled with dynamic checks.
+
+The precise rule is as follows. A unit that is compiled with dynamic
+checks can only @code{with} a unit that meets at least one of the
+following criteria:
+
+@itemize @bullet
+
+@item
+The @code{with'ed} unit is itself compiled with dynamic elaboration
+checks (that is with the @option{-gnatE} switch.
+
+@item
+The @code{with'ed} unit is an internal GNAT implementation unit from
+the System, Interfaces, Ada, or GNAT hierarchies.
+
+@item
+The @code{with'ed} unit has pragma Preelaborate or pragma Pure.
+
+@item
+The @code{with'ing} unit (that is the client) has an explicit pragma
+@code{Elaborate_All} for the @code{with'ed} unit.
+
+@end itemize
+
+@noindent
+If this rule is violated, that is if a unit with dynamic elaboration
+checks @code{with's} a unit that does not meet one of the above four
+criteria, then the binder (@code{gnatbind}) will issue a warning
+similar to that in the following example:
+
+@smallexample
+warning: "x.ads" has dynamic elaboration checks and with's
+warning: "y.ads" which has static elaboration checks
+@end smallexample
+
+@noindent
+These warnings indicate that the rule has been violated, and that as a result
+elaboration checks may be missed in the resulting executable file.
+This warning may be suppressed using the @option{-ws} binder switch
+in the usual manner.
+
+One useful application of this mixing rule is in the case of a subsystem
+which does not itself @code{with} units from the remainder of the
+application. In this case, the entire subsystem can be compiled with
+dynamic checks to resolve a circularity in the subsystem, while
+allowing the main application that uses this subsystem to be compiled
+using the more reliable default static model.
+
+@node What to Do If the Default Elaboration Behavior Fails
+@section What to Do If the Default Elaboration Behavior Fails
+
+@noindent
+If the binder cannot find an acceptable order, it outputs detailed
+diagnostics. For example:
+@smallexample
+@group
+@iftex
+@leftskip=0cm
+@end iftex
+error: elaboration circularity detected
+info: "proc (body)" must be elaborated before "pack (body)"
+info: reason: Elaborate_All probably needed in unit "pack (body)"
+info: recompile "pack (body)" with -gnatwl
+info: for full details
+info: "proc (body)"
+info: is needed by its spec:
+info: "proc (spec)"
+info: which is withed by:
+info: "pack (body)"
+info: "pack (body)" must be elaborated before "proc (body)"
+info: reason: pragma Elaborate in unit "proc (body)"
+@end group
+
+@end smallexample
+
+@noindent
+In this case we have a cycle that the binder cannot break. On the one
+hand, there is an explicit pragma Elaborate in @code{proc} for
+@code{pack}. This means that the body of @code{pack} must be elaborated
+before the body of @code{proc}. On the other hand, there is elaboration
+code in @code{pack} that calls a subprogram in @code{proc}. This means
+that for maximum safety, there should really be a pragma
+Elaborate_All in @code{pack} for @code{proc} which would require that
+the body of @code{proc} be elaborated before the body of
+@code{pack}. Clearly both requirements cannot be satisfied.
+Faced with a circularity of this kind, you have three different options.
+
+@table @asis
+@item Fix the program
+The most desirable option from the point of view of long-term maintenance
+is to rearrange the program so that the elaboration problems are avoided.
+One useful technique is to place the elaboration code into separate
+child packages. Another is to move some of the initialization code to
+explicitly called subprograms, where the program controls the order
+of initialization explicitly. Although this is the most desirable option,
+it may be impractical and involve too much modification, especially in
+the case of complex legacy code.
+
+@item Perform dynamic checks
+If the compilations are done using the
+@option{-gnatE}
+(dynamic elaboration check) switch, then GNAT behaves in
+a quite different manner. Dynamic checks are generated for all calls
+that could possibly result in raising an exception. With this switch,
+the compiler does not generate implicit @code{Elaborate_All} pragmas.
+The behavior then is exactly as specified in the Ada 95 Reference Manual.
+The binder will generate an executable program that may or may not
+raise @code{Program_Error}, and then it is the programmer's job to ensure
+that it does not raise an exception. Note that it is important to
+compile all units with the switch, it cannot be used selectively.
+
+@item Suppress checks
+The drawback of dynamic checks is that they generate a
+significant overhead at run time, both in space and time. If you
+are absolutely sure that your program cannot raise any elaboration
+exceptions, and you still want to use the dynamic elaboration model,
+then you can use the configuration pragma
+@code{Suppress (Elaboration_Check)} to suppress all such checks. For
+example this pragma could be placed in the @file{gnat.adc} file.
+
+@item Suppress checks selectively
+When you know that certain calls in elaboration code cannot possibly
+lead to an elaboration error, and the binder nevertheless generates warnings
+on those calls and inserts Elaborate_All pragmas that lead to elaboration
+circularities, it is possible to remove those warnings locally and obtain
+a program that will bind. Clearly this can be unsafe, and it is the
+responsibility of the programmer to make sure that the resulting program has
+no elaboration anomalies. The pragma @code{Suppress (Elaboration_Check)} can
+be used with different granularity to suppress warnings and break
+elaboration circularities:
+
+@itemize @bullet
+@item
+Place the pragma that names the called subprogram in the declarative part
+that contains the call.
+
+@item
+Place the pragma in the declarative part, without naming an entity. This
+disables warnings on all calls in the corresponding declarative region.
+
+@item
+Place the pragma in the package spec that declares the called subprogram,
+and name the subprogram. This disables warnings on all elaboration calls to
+that subprogram.
+
+@item
+Place the pragma in the package spec that declares the called subprogram,
+without naming any entity. This disables warnings on all elaboration calls to
+all subprograms declared in this spec.
+
+@item Use Pragma Elaborate
+As previously described in section @xref{Treatment of Pragma Elaborate},
+GNAT in static mode assumes that a @code{pragma} Elaborate indicates correctly
+that no elaboration checks are required on calls to the designated unit.
+There may be cases in which the caller knows that no transitive calls
+can occur, so that a @code{pragma Elaborate} will be sufficient in a
+case where @code{pragma Elaborate_All} would cause a circularity.
+@end itemize
+
+@noindent
+These five cases are listed in order of decreasing safety, and therefore
+require increasing programmer care in their application. Consider the
+following program:
+
+@smallexample @c adanocomment
+package Pack1 is
+ function F1 return Integer;
+ X1 : Integer;
+end Pack1;
+
+package Pack2 is
+ function F2 return Integer;
+ function Pure (x : integer) return integer;
+ -- pragma Suppress (Elaboration_Check, On => Pure); -- (3)
+ -- pragma Suppress (Elaboration_Check); -- (4)
+end Pack2;
+
+with Pack2;
+package body Pack1 is
+ function F1 return Integer is
+ begin
+ return 100;
+ end F1;
+ Val : integer := Pack2.Pure (11); -- Elab. call (1)
+begin
+ declare
+ -- pragma Suppress(Elaboration_Check, Pack2.F2); -- (1)
+ -- pragma Suppress(Elaboration_Check); -- (2)
+ begin
+ X1 := Pack2.F2 + 1; -- Elab. call (2)
+ end;
+end Pack1;
+
+with Pack1;
+package body Pack2 is
+ function F2 return Integer is
+ begin
+ return Pack1.F1;
+ end F2;
+ function Pure (x : integer) return integer is
+ begin
+ return x ** 3 - 3 * x;
+ end;
+end Pack2;
+
+with Pack1, Ada.Text_IO;
+procedure Proc3 is
+begin
+ Ada.Text_IO.Put_Line(Pack1.X1'Img); -- 101
+end Proc3;
+@end smallexample
+In the absence of any pragmas, an attempt to bind this program produces
+the following diagnostics:
+@smallexample
+@group
+@iftex
+@leftskip=.5cm
+@end iftex
+error: elaboration circularity detected
+info: "pack1 (body)" must be elaborated before "pack1 (body)"
+info: reason: Elaborate_All probably needed in unit "pack1 (body)"
+info: recompile "pack1 (body)" with -gnatwl for full details
+info: "pack1 (body)"
+info: must be elaborated along with its spec:
+info: "pack1 (spec)"
+info: which is withed by:
+info: "pack2 (body)"
+info: which must be elaborated along with its spec:
+info: "pack2 (spec)"
+info: which is withed by:
+info: "pack1 (body)"
+@end group
+@end smallexample
+The sources of the circularity are the two calls to @code{Pack2.Pure} and
+@code{Pack2.F2} in the body of @code{Pack1}. We can see that the call to
+F2 is safe, even though F2 calls F1, because the call appears after the
+elaboration of the body of F1. Therefore the pragma (1) is safe, and will
+remove the warning on the call. It is also possible to use pragma (2)
+because there are no other potentially unsafe calls in the block.
+
+@noindent
+The call to @code{Pure} is safe because this function does not depend on the
+state of @code{Pack2}. Therefore any call to this function is safe, and it
+is correct to place pragma (3) in the corresponding package spec.
+
+@noindent
+Finally, we could place pragma (4) in the spec of @code{Pack2} to disable
+warnings on all calls to functions declared therein. Note that this is not
+necessarily safe, and requires more detailed examination of the subprogram
+bodies involved. In particular, a call to @code{F2} requires that @code{F1}
+be already elaborated.
+@end table
+
+@noindent
+It is hard to generalize on which of these four approaches should be
+taken. Obviously if it is possible to fix the program so that the default
+treatment works, this is preferable, but this may not always be practical.
+It is certainly simple enough to use
+@option{-gnatE}
+but the danger in this case is that, even if the GNAT binder
+finds a correct elaboration order, it may not always do so,
+and certainly a binder from another Ada compiler might not. A
+combination of testing and analysis (for which the warnings generated
+with the
+@option{-gnatwl}
+switch can be useful) must be used to ensure that the program is free
+of errors. One switch that is useful in this testing is the
+@option{^-p (pessimistic elaboration order)^/PESSIMISTIC_ELABORATION_ORDER^}
+switch for
+@code{gnatbind}.
+Normally the binder tries to find an order that has the best chance of
+of avoiding elaboration problems. With this switch, the binder
+plays a devil's advocate role, and tries to choose the order that
+has the best chance of failing. If your program works even with this
+switch, then it has a better chance of being error free, but this is still
+not a guarantee.
+
+For an example of this approach in action, consider the C-tests (executable
+tests) from the ACVC suite. If these are compiled and run with the default
+treatment, then all but one of them succeed without generating any error
+diagnostics from the binder. However, there is one test that fails, and
+this is not surprising, because the whole point of this test is to ensure
+that the compiler can handle cases where it is impossible to determine
+a correct order statically, and it checks that an exception is indeed
+raised at run time.
+
+This one test must be compiled and run using the
+@option{-gnatE}
+switch, and then it passes. Alternatively, the entire suite can
+be run using this switch. It is never wrong to run with the dynamic
+elaboration switch if your code is correct, and we assume that the
+C-tests are indeed correct (it is less efficient, but efficiency is
+not a factor in running the ACVC tests.)
+
+@node Elaboration for Access-to-Subprogram Values
+@section Elaboration for Access-to-Subprogram Values
+@cindex Access-to-subprogram
+
+@noindent
+The introduction of access-to-subprogram types in Ada 95 complicates
+the handling of elaboration. The trouble is that it becomes
+impossible to tell at compile time which procedure
+is being called. This means that it is not possible for the binder
+to analyze the elaboration requirements in this case.
+
+If at the point at which the access value is created
+(i.e., the evaluation of @code{P'Access} for a subprogram @code{P}),
+the body of the subprogram is
+known to have been elaborated, then the access value is safe, and its use
+does not require a check. This may be achieved by appropriate arrangement
+of the order of declarations if the subprogram is in the current unit,
+or, if the subprogram is in another unit, by using pragma
+@code{Pure}, @code{Preelaborate}, or @code{Elaborate_Body}
+on the referenced unit.
+
+If the referenced body is not known to have been elaborated at the point
+the access value is created, then any use of the access value must do a
+dynamic check, and this dynamic check will fail and raise a
+@code{Program_Error} exception if the body has not been elaborated yet.
+GNAT will generate the necessary checks, and in addition, if the
+@option{-gnatwl}
+switch is set, will generate warnings that such checks are required.
+
+The use of dynamic dispatching for tagged types similarly generates
+a requirement for dynamic checks, and premature calls to any primitive
+operation of a tagged type before the body of the operation has been
+elaborated, will result in the raising of @code{Program_Error}.
+
+@node Summary of Procedures for Elaboration Control
+@section Summary of Procedures for Elaboration Control
+@cindex Elaboration control
+
+@noindent
+First, compile your program with the default options, using none of
+the special elaboration control switches. If the binder successfully
+binds your program, then you can be confident that, apart from issues
+raised by the use of access-to-subprogram types and dynamic dispatching,
+the program is free of elaboration errors. If it is important that the
+program be portable, then use the
+@option{-gnatwl}
+switch to generate warnings about missing @code{Elaborate_All}
+pragmas, and supply the missing pragmas.
+
+If the program fails to bind using the default static elaboration
+handling, then you can fix the program to eliminate the binder
+message, or recompile the entire program with the
+@option{-gnatE} switch to generate dynamic elaboration checks,
+and, if you are sure there really are no elaboration problems,
+use a global pragma @code{Suppress (Elaboration_Check)}.
+
+@node Other Elaboration Order Considerations
+@section Other Elaboration Order Considerations
+@noindent
+This section has been entirely concerned with the issue of finding a valid
+elaboration order, as defined by the Ada Reference Manual. In a case
+where several elaboration orders are valid, the task is to find one
+of the possible valid elaboration orders (and the static model in GNAT
+will ensure that this is achieved).
+
+The purpose of the elaboration rules in the Ada Reference Manual is to
+make sure that no entity is accessed before it has been elaborated. For
+a subprogram, this means that the spec and body must have been elaborated
+before the subprogram is called. For an object, this means that the object
+must have been elaborated before its value is read or written. A violation
+of either of these two requirements is an access before elaboration order,
+and this section has been all about avoiding such errors.
+
+In the case where more than one order of elaboration is possible, in the
+sense that access before elaboration errors are avoided, then any one of
+the orders is ``correct'' in the sense that it meets the requirements of
+the Ada Reference Manual, and no such error occurs.
+
+However, it may be the case for a given program, that there are
+constraints on the order of elaboration that come not from consideration
+of avoiding elaboration errors, but rather from extra-lingual logic
+requirements. Consider this example:
+
+@smallexample @c ada
+with Init_Constants;
+package Constants is
+ X : Integer := 0;
+ Y : Integer := 0;
+end Constants;
+
+package Init_Constants is
+ procedure P; -- require a body
+end Init_Constants;
+
+with Constants;
+package body Init_Constants is
+ procedure P is begin null; end;
+begin
+ Constants.X := 3;
+ Constants.Y := 4;
+end Init_Constants;
+
+with Constants;
+package Calc is
+ Z : Integer := Constants.X + Constants.Y;
+end Calc;
+
+with Calc;
+with Text_IO; use Text_IO;
+procedure Main is
+begin
+ Put_Line (Calc.Z'Img);
+end Main;
+@end smallexample
+
+@noindent
+In this example, there is more than one valid order of elaboration. For
+example both the following are correct orders:
+
+@smallexample
+Init_Constants spec
+Constants spec
+Calc spec
+Init_Constants body
+Main body
+
+ and
+
+Init_Constants spec
+Init_Constants body
+Constants spec
+Calc spec
+Main body
+@end smallexample
+
+@noindent
+There is no language rule to prefer one or the other, both are correct
+from an order of elaboration point of view. But the programmatic effects
+of the two orders are very different. In the first, the elaboration routine
+of @code{Calc} initializes @code{Z} to zero, and then the main program
+runs with this value of zero. But in the second order, the elaboration
+routine of @code{Calc} runs after the body of Init_Constants has set
+@code{X} and @code{Y} and thus @code{Z} is set to 7 before @code{Main}
+runs.
+
+One could perhaps by applying pretty clever non-artificial intelligence
+to the situation guess that it is more likely that the second order of
+elaboration is the one desired, but there is no formal linguistic reason
+to prefer one over the other. In fact in this particular case, GNAT will
+prefer the second order, because of the rule that bodies are elaborated
+as soon as possible, but it's just luck that this is what was wanted
+(if indeed the second order was preferred).
+
+If the program cares about the order of elaboration routines in a case like
+this, it is important to specify the order required. In this particular
+case, that could have been achieved by adding to the spec of Calc:
+
+@smallexample @c ada
+pragma Elaborate_All (Constants);
+@end smallexample
+
+@noindent
+which requires that the body (if any) and spec of @code{Constants},
+as well as the body and spec of any unit @code{with}'ed by
+@code{Constants} be elaborated before @code{Calc} is elaborated.
+
+Clearly no automatic method can always guess which alternative you require,
+and if you are working with legacy code that had constraints of this kind
+which were not properly specified by adding @code{Elaborate} or
+@code{Elaborate_All} pragmas, then indeed it is possible that two different
+compilers can choose different orders.
+
+The @code{gnatbind}
+@option{^-p^/PESSIMISTIC_ELABORATION^} switch may be useful in smoking
+out problems. This switch causes bodies to be elaborated as late as possible
+instead of as early as possible. In the example above, it would have forced
+the choice of the first elaboration order. If you get different results
+when using this switch, and particularly if one set of results is right,
+and one is wrong as far as you are concerned, it shows that you have some
+missing @code{Elaborate} pragmas. For the example above, we have the
+following output:
+
+@smallexample
+gnatmake -f -q main
+main
+ 7
+gnatmake -f -q main -bargs -p
+main
+ 0
+@end smallexample
+
+@noindent
+It is of course quite unlikely that both these results are correct, so
+it is up to you in a case like this to investigate the source of the
+difference, by looking at the two elaboration orders that are chosen,
+and figuring out which is correct, and then adding the necessary
+@code{Elaborate_All} pragmas to ensure the desired order.
+
+
+@node Inline Assembler
+@appendix Inline Assembler
+
+@noindent
+If you need to write low-level software that interacts directly
+with the hardware, Ada provides two ways to incorporate assembly
+language code into your program. First, you can import and invoke
+external routines written in assembly language, an Ada feature fully
+supported by GNAT. However, for small sections of code it may be simpler
+or more efficient to include assembly language statements directly
+in your Ada source program, using the facilities of the implementation-defined
+package @code{System.Machine_Code}, which incorporates the gcc
+Inline Assembler. The Inline Assembler approach offers a number of advantages,
+including the following:
+
+@itemize @bullet
+@item No need to use non-Ada tools
+@item Consistent interface over different targets
+@item Automatic usage of the proper calling conventions
+@item Access to Ada constants and variables
+@item Definition of intrinsic routines
+@item Possibility of inlining a subprogram comprising assembler code
+@item Code optimizer can take Inline Assembler code into account
+@end itemize
+
+This chapter presents a series of examples to show you how to use
+the Inline Assembler. Although it focuses on the Intel x86,
+the general approach applies also to other processors.
+It is assumed that you are familiar with Ada
+and with assembly language programming.
+
+@menu
+* Basic Assembler Syntax::
+* A Simple Example of Inline Assembler::
+* Output Variables in Inline Assembler::
+* Input Variables in Inline Assembler::
+* Inlining Inline Assembler Code::
+* Other Asm Functionality::
+* A Complete Example::
+@end menu
+
+@c ---------------------------------------------------------------------------
+@node Basic Assembler Syntax
+@section Basic Assembler Syntax
+
+@noindent
+The assembler used by GNAT and gcc is based not on the Intel assembly
+language, but rather on a language that descends from the AT&T Unix
+assembler @emph{as} (and which is often referred to as ``AT&T syntax'').
+The following table summarizes the main features of @emph{as} syntax
+and points out the differences from the Intel conventions.
+See the gcc @emph{as} and @emph{gas} (an @emph{as} macro
+pre-processor) documentation for further information.
+
+@table @asis
+@item Register names
+gcc / @emph{as}: Prefix with ``%''; for example @code{%eax}
+@*
+Intel: No extra punctuation; for example @code{eax}
+
+@item Immediate operand
+gcc / @emph{as}: Prefix with ``$''; for example @code{$4}
+@*
+Intel: No extra punctuation; for example @code{4}
+
+@item Address
+gcc / @emph{as}: Prefix with ``$''; for example @code{$loc}
+@*
+Intel: No extra punctuation; for example @code{loc}
+
+@item Memory contents
+gcc / @emph{as}: No extra punctuation; for example @code{loc}
+@*
+Intel: Square brackets; for example @code{[loc]}
+
+@item Register contents
+gcc / @emph{as}: Parentheses; for example @code{(%eax)}
+@*
+Intel: Square brackets; for example @code{[eax]}
+
+@item Hexadecimal numbers
+gcc / @emph{as}: Leading ``0x'' (C language syntax); for example @code{0xA0}
+@*
+Intel: Trailing ``h''; for example @code{A0h}
+
+@item Operand size
+gcc / @emph{as}: Explicit in op code; for example @code{movw} to move
+a 16-bit word
+@*
+Intel: Implicit, deduced by assembler; for example @code{mov}
+
+@item Instruction repetition
+gcc / @emph{as}: Split into two lines; for example
+@*
+@code{rep}
+@*
+@code{stosl}
+@*
+Intel: Keep on one line; for example @code{rep stosl}
+
+@item Order of operands
+gcc / @emph{as}: Source first; for example @code{movw $4, %eax}
+@*
+Intel: Destination first; for example @code{mov eax, 4}
+@end table
+
+@c ---------------------------------------------------------------------------
+@node A Simple Example of Inline Assembler
+@section A Simple Example of Inline Assembler
+
+@noindent
+The following example will generate a single assembly language statement,
+@code{nop}, which does nothing. Despite its lack of run-time effect,
+the example will be useful in illustrating the basics of
+the Inline Assembler facility.
+
+@smallexample @c ada
+@group
+with System.Machine_Code; use System.Machine_Code;
+procedure Nothing is
+begin
+ Asm ("nop");
+end Nothing;
+@end group
+@end smallexample
+
+@code{Asm} is a procedure declared in package @code{System.Machine_Code};
+here it takes one parameter, a @emph{template string} that must be a static
+expression and that will form the generated instruction.
+@code{Asm} may be regarded as a compile-time procedure that parses
+the template string and additional parameters (none here),
+from which it generates a sequence of assembly language instructions.
+
+The examples in this chapter will illustrate several of the forms
+for invoking @code{Asm}; a complete specification of the syntax
+is found in the @cite{GNAT Reference Manual}.
+
+Under the standard GNAT conventions, the @code{Nothing} procedure
+should be in a file named @file{nothing.adb}.
+You can build the executable in the usual way:
+@smallexample
+gnatmake nothing
+@end smallexample
+However, the interesting aspect of this example is not its run-time behavior
+but rather the generated assembly code.
+To see this output, invoke the compiler as follows:
+@smallexample
+ gcc -c -S -fomit-frame-pointer -gnatp @file{nothing.adb}
+@end smallexample
+where the options are:
+
+@table @code
+@item -c
+compile only (no bind or link)
+@item -S
+generate assembler listing
+@item -fomit-frame-pointer
+do not set up separate stack frames
+@item -gnatp
+do not add runtime checks
+@end table
+
+This gives a human-readable assembler version of the code. The resulting
+file will have the same name as the Ada source file, but with a @code{.s}
+extension. In our example, the file @file{nothing.s} has the following
+contents:
+
+@smallexample
+@group
+.file "nothing.adb"
+gcc2_compiled.:
+___gnu_compiled_ada:
+.text
+ .align 4
+.globl __ada_nothing
+__ada_nothing:
+#APP
+ nop
+#NO_APP
+ jmp L1
+ .align 2,0x90
+L1:
+ ret
+@end group
+@end smallexample
+
+The assembly code you included is clearly indicated by
+the compiler, between the @code{#APP} and @code{#NO_APP}
+delimiters. The character before the 'APP' and 'NOAPP'
+can differ on different targets. For example, GNU/Linux uses '#APP' while
+on NT you will see '/APP'.
+
+If you make a mistake in your assembler code (such as using the
+wrong size modifier, or using a wrong operand for the instruction) GNAT
+will report this error in a temporary file, which will be deleted when
+the compilation is finished. Generating an assembler file will help
+in such cases, since you can assemble this file separately using the
+@emph{as} assembler that comes with gcc.
+
+Assembling the file using the command
+
+@smallexample
+as @file{nothing.s}
+@end smallexample
+@noindent
+will give you error messages whose lines correspond to the assembler
+input file, so you can easily find and correct any mistakes you made.
+If there are no errors, @emph{as} will generate an object file
+@file{nothing.out}.
+
+@c ---------------------------------------------------------------------------
+@node Output Variables in Inline Assembler
+@section Output Variables in Inline Assembler
+
+@noindent
+The examples in this section, showing how to access the processor flags,
+illustrate how to specify the destination operands for assembly language
+statements.
+
+@smallexample @c ada
+@group
+with Interfaces; use Interfaces;
+with Ada.Text_IO; use Ada.Text_IO;
+with System.Machine_Code; use System.Machine_Code;
+procedure Get_Flags is
+ Flags : Unsigned_32;
+ use ASCII;
+begin
+ Asm ("pushfl" & LF & HT & -- push flags on stack
+ "popl %%eax" & LF & HT & -- load eax with flags
+ "movl %%eax, %0", -- store flags in variable
+ Outputs => Unsigned_32'Asm_Output ("=g", Flags));
+ Put_Line ("Flags register:" & Flags'Img);
+end Get_Flags;
+@end group
+@end smallexample
+
+In order to have a nicely aligned assembly listing, we have separated
+multiple assembler statements in the Asm template string with linefeed
+(ASCII.LF) and horizontal tab (ASCII.HT) characters.
+The resulting section of the assembly output file is:
+
+@smallexample
+@group
+#APP
+ pushfl
+ popl %eax
+ movl %eax, -40(%ebp)
+#NO_APP
+@end group
+@end smallexample
+
+It would have been legal to write the Asm invocation as:
+
+@smallexample
+Asm ("pushfl popl %%eax movl %%eax, %0")
+@end smallexample
+
+but in the generated assembler file, this would come out as:
+
+@smallexample
+#APP
+ pushfl popl %eax movl %eax, -40(%ebp)
+#NO_APP
+@end smallexample
+
+which is not so convenient for the human reader.
+
+We use Ada comments
+at the end of each line to explain what the assembler instructions
+actually do. This is a useful convention.
+
+When writing Inline Assembler instructions, you need to precede each register
+and variable name with a percent sign. Since the assembler already requires
+a percent sign at the beginning of a register name, you need two consecutive
+percent signs for such names in the Asm template string, thus @code{%%eax}.
+In the generated assembly code, one of the percent signs will be stripped off.
+
+Names such as @code{%0}, @code{%1}, @code{%2}, etc., denote input or output
+variables: operands you later define using @code{Input} or @code{Output}
+parameters to @code{Asm}.
+An output variable is illustrated in
+the third statement in the Asm template string:
+@smallexample
+movl %%eax, %0
+@end smallexample
+The intent is to store the contents of the eax register in a variable that can
+be accessed in Ada. Simply writing @code{movl %%eax, Flags} would not
+necessarily work, since the compiler might optimize by using a register
+to hold Flags, and the expansion of the @code{movl} instruction would not be
+aware of this optimization. The solution is not to store the result directly
+but rather to advise the compiler to choose the correct operand form;
+that is the purpose of the @code{%0} output variable.
+
+Information about the output variable is supplied in the @code{Outputs}
+parameter to @code{Asm}:
+@smallexample
+Outputs => Unsigned_32'Asm_Output ("=g", Flags));
+@end smallexample
+
+The output is defined by the @code{Asm_Output} attribute of the target type;
+the general format is
+@smallexample
+Type'Asm_Output (constraint_string, variable_name)
+@end smallexample
+
+The constraint string directs the compiler how
+to store/access the associated variable. In the example
+@smallexample
+Unsigned_32'Asm_Output ("=m", Flags);
+@end smallexample
+the @code{"m"} (memory) constraint tells the compiler that the variable
+@code{Flags} should be stored in a memory variable, thus preventing
+the optimizer from keeping it in a register. In contrast,
+@smallexample
+Unsigned_32'Asm_Output ("=r", Flags);
+@end smallexample
+uses the @code{"r"} (register) constraint, telling the compiler to
+store the variable in a register.
+
+If the constraint is preceded by the equal character (@strong{=}), it tells
+the compiler that the variable will be used to store data into it.
+
+In the @code{Get_Flags} example, we used the @code{"g"} (global) constraint,
+allowing the optimizer to choose whatever it deems best.
+
+There are a fairly large number of constraints, but the ones that are
+most useful (for the Intel x86 processor) are the following:
+
+@table @code
+@item =
+output constraint
+@item g
+global (i.e. can be stored anywhere)
+@item m
+in memory
+@item I
+a constant
+@item a
+use eax
+@item b
+use ebx
+@item c
+use ecx
+@item d
+use edx
+@item S
+use esi
+@item D
+use edi
+@item r
+use one of eax, ebx, ecx or edx
+@item q
+use one of eax, ebx, ecx, edx, esi or edi
+@end table
+
+The full set of constraints is described in the gcc and @emph{as}
+documentation; note that it is possible to combine certain constraints
+in one constraint string.
+
+You specify the association of an output variable with an assembler operand
+through the @code{%}@emph{n} notation, where @emph{n} is a non-negative
+integer. Thus in
+@smallexample @c ada
+@group
+Asm ("pushfl" & LF & HT & -- push flags on stack
+ "popl %%eax" & LF & HT & -- load eax with flags
+ "movl %%eax, %0", -- store flags in variable
+ Outputs => Unsigned_32'Asm_Output ("=g", Flags));
+@end group
+@end smallexample
+@noindent
+@code{%0} will be replaced in the expanded code by the appropriate operand,
+whatever
+the compiler decided for the @code{Flags} variable.
+
+In general, you may have any number of output variables:
+@itemize @bullet
+@item
+Count the operands starting at 0; thus @code{%0}, @code{%1}, etc.
+@item
+Specify the @code{Outputs} parameter as a parenthesized comma-separated list
+of @code{Asm_Output} attributes
+@end itemize
+
+For example:
+@smallexample @c ada
+@group
+Asm ("movl %%eax, %0" & LF & HT &
+ "movl %%ebx, %1" & LF & HT &
+ "movl %%ecx, %2",
+ Outputs => (Unsigned_32'Asm_Output ("=g", Var_A), -- %0 = Var_A
+ Unsigned_32'Asm_Output ("=g", Var_B), -- %1 = Var_B
+ Unsigned_32'Asm_Output ("=g", Var_C))); -- %2 = Var_C
+@end group
+@end smallexample
+@noindent
+where @code{Var_A}, @code{Var_B}, and @code{Var_C} are variables
+in the Ada program.
+
+As a variation on the @code{Get_Flags} example, we can use the constraints
+string to direct the compiler to store the eax register into the @code{Flags}
+variable, instead of including the store instruction explicitly in the
+@code{Asm} template string:
+
+@smallexample @c ada
+@group
+with Interfaces; use Interfaces;
+with Ada.Text_IO; use Ada.Text_IO;
+with System.Machine_Code; use System.Machine_Code;
+procedure Get_Flags_2 is
+ Flags : Unsigned_32;
+ use ASCII;
+begin
+ Asm ("pushfl" & LF & HT & -- push flags on stack
+ "popl %%eax", -- save flags in eax
+ Outputs => Unsigned_32'Asm_Output ("=a", Flags));
+ Put_Line ("Flags register:" & Flags'Img);
+end Get_Flags_2;
+@end group
+@end smallexample
+
+@noindent
+The @code{"a"} constraint tells the compiler that the @code{Flags}
+variable will come from the eax register. Here is the resulting code:
+
+@smallexample
+@group
+#APP
+ pushfl
+ popl %eax
+#NO_APP
+ movl %eax,-40(%ebp)
+@end group
+@end smallexample
+
+@noindent
+The compiler generated the store of eax into Flags after
+expanding the assembler code.
+
+Actually, there was no need to pop the flags into the eax register;
+more simply, we could just pop the flags directly into the program variable:
+
+@smallexample @c ada
+@group
+with Interfaces; use Interfaces;
+with Ada.Text_IO; use Ada.Text_IO;
+with System.Machine_Code; use System.Machine_Code;
+procedure Get_Flags_3 is
+ Flags : Unsigned_32;
+ use ASCII;
+begin
+ Asm ("pushfl" & LF & HT & -- push flags on stack
+ "pop %0", -- save flags in Flags
+ Outputs => Unsigned_32'Asm_Output ("=g", Flags));
+ Put_Line ("Flags register:" & Flags'Img);
+end Get_Flags_3;
+@end group
+@end smallexample
+
+@c ---------------------------------------------------------------------------
+@node Input Variables in Inline Assembler
+@section Input Variables in Inline Assembler
+
+@noindent
+The example in this section illustrates how to specify the source operands
+for assembly language statements.
+The program simply increments its input value by 1:
+
+@smallexample @c ada
+@group
+with Interfaces; use Interfaces;
+with Ada.Text_IO; use Ada.Text_IO;
+with System.Machine_Code; use System.Machine_Code;
+procedure Increment is
+
+ function Incr (Value : Unsigned_32) return Unsigned_32 is
+ Result : Unsigned_32;
+ begin
+ Asm ("incl %0",
+ Inputs => Unsigned_32'Asm_Input ("a", Value),
+ Outputs => Unsigned_32'Asm_Output ("=a", Result));
+ return Result;
+ end Incr;
+
+ Value : Unsigned_32;
+
+begin
+ Value := 5;
+ Put_Line ("Value before is" & Value'Img);
+ Value := Incr (Value);
+ Put_Line ("Value after is" & Value'Img);
+end Increment;
+@end group
+@end smallexample
+
+The @code{Outputs} parameter to @code{Asm} specifies
+that the result will be in the eax register and that it is to be stored
+in the @code{Result} variable.
+
+The @code{Inputs} parameter looks much like the @code{Outputs} parameter,
+but with an @code{Asm_Input} attribute.
+The @code{"="} constraint, indicating an output value, is not present.
+
+You can have multiple input variables, in the same way that you can have more
+than one output variable.
+
+The parameter count (%0, %1) etc, now starts at the first input
+statement, and continues with the output statements.
+When both parameters use the same variable, the
+compiler will treat them as the same %n operand, which is the case here.
+
+Just as the @code{Outputs} parameter causes the register to be stored into the
+target variable after execution of the assembler statements, so does the
+@code{Inputs} parameter cause its variable to be loaded into the register
+before execution of the assembler statements.
+
+Thus the effect of the @code{Asm} invocation is:
+@enumerate
+@item load the 32-bit value of @code{Value} into eax
+@item execute the @code{incl %eax} instruction
+@item store the contents of eax into the @code{Result} variable
+@end enumerate
+
+The resulting assembler file (with @option{-O2} optimization) contains:
+@smallexample
+@group
+_increment__incr.1:
+ subl $4,%esp
+ movl 8(%esp),%eax
+#APP
+ incl %eax
+#NO_APP
+ movl %eax,%edx
+ movl %ecx,(%esp)
+ addl $4,%esp
+ ret
+@end group
+@end smallexample
+
+@c ---------------------------------------------------------------------------
+@node Inlining Inline Assembler Code
+@section Inlining Inline Assembler Code
+
+@noindent
+For a short subprogram such as the @code{Incr} function in the previous
+section, the overhead of the call and return (creating / deleting the stack
+frame) can be significant, compared to the amount of code in the subprogram
+body. A solution is to apply Ada's @code{Inline} pragma to the subprogram,
+which directs the compiler to expand invocations of the subprogram at the
+point(s) of call, instead of setting up a stack frame for out-of-line calls.
+Here is the resulting program:
+
+@smallexample @c ada
+@group
+with Interfaces; use Interfaces;
+with Ada.Text_IO; use Ada.Text_IO;
+with System.Machine_Code; use System.Machine_Code;
+procedure Increment_2 is
+
+ function Incr (Value : Unsigned_32) return Unsigned_32 is
+ Result : Unsigned_32;
+ begin
+ Asm ("incl %0",
+ Inputs => Unsigned_32'Asm_Input ("a", Value),
+ Outputs => Unsigned_32'Asm_Output ("=a", Result));
+ return Result;
+ end Incr;
+ pragma Inline (Increment);
+
+ Value : Unsigned_32;
+
+begin
+ Value := 5;
+ Put_Line ("Value before is" & Value'Img);
+ Value := Increment (Value);
+ Put_Line ("Value after is" & Value'Img);
+end Increment_2;
+@end group
+@end smallexample
+
+Compile the program with both optimization (@option{-O2}) and inlining
+enabled (@option{-gnatpn} instead of @option{-gnatp}).
+
+The @code{Incr} function is still compiled as usual, but at the
+point in @code{Increment} where our function used to be called:
+
+@smallexample
+@group
+pushl %edi
+call _increment__incr.1
+@end group
+@end smallexample
+
+@noindent
+the code for the function body directly appears:
+
+@smallexample
+@group
+movl %esi,%eax
+#APP
+ incl %eax
+#NO_APP
+ movl %eax,%edx
+@end group
+@end smallexample
+
+@noindent
+thus saving the overhead of stack frame setup and an out-of-line call.
+
+@c ---------------------------------------------------------------------------
+@node Other Asm Functionality
+@section Other @code{Asm} Functionality
+
+@noindent
+This section describes two important parameters to the @code{Asm}
+procedure: @code{Clobber}, which identifies register usage;
+and @code{Volatile}, which inhibits unwanted optimizations.
+
+@menu
+* The Clobber Parameter::
+* The Volatile Parameter::
+@end menu
+
+@c ---------------------------------------------------------------------------
+@node The Clobber Parameter
+@subsection The @code{Clobber} Parameter
+
+@noindent
+One of the dangers of intermixing assembly language and a compiled language
+such as Ada is that the compiler needs to be aware of which registers are
+being used by the assembly code. In some cases, such as the earlier examples,
+the constraint string is sufficient to indicate register usage (e.g.,
+@code{"a"} for
+the eax register). But more generally, the compiler needs an explicit
+identification of the registers that are used by the Inline Assembly
+statements.
+
+Using a register that the compiler doesn't know about
+could be a side effect of an instruction (like @code{mull}
+storing its result in both eax and edx).
+It can also arise from explicit register usage in your
+assembly code; for example:
+@smallexample
+@group
+Asm ("movl %0, %%ebx" & LF & HT &
+ "movl %%ebx, %1",
+ Inputs => Unsigned_32'Asm_Input ("g", Var_In),
+ Outputs => Unsigned_32'Asm_Output ("=g", Var_Out));
+@end group
+@end smallexample
+@noindent
+where the compiler (since it does not analyze the @code{Asm} template string)
+does not know you are using the ebx register.
+
+In such cases you need to supply the @code{Clobber} parameter to @code{Asm},
+to identify the registers that will be used by your assembly code:
+
+@smallexample
+@group
+Asm ("movl %0, %%ebx" & LF & HT &
+ "movl %%ebx, %1",
+ Inputs => Unsigned_32'Asm_Input ("g", Var_In),
+ Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
+ Clobber => "ebx");
+@end group
+@end smallexample
+
+The Clobber parameter is a static string expression specifying the
+register(s) you are using. Note that register names are @emph{not} prefixed
+by a percent sign. Also, if more than one register is used then their names
+are separated by commas; e.g., @code{"eax, ebx"}
+
+The @code{Clobber} parameter has several additional uses:
+@enumerate
+@item Use ``register'' name @code{cc} to indicate that flags might have changed
+@item Use ``register'' name @code{memory} if you changed a memory location
+@end enumerate
+
+@c ---------------------------------------------------------------------------
+@node The Volatile Parameter
+@subsection The @code{Volatile} Parameter
+@cindex Volatile parameter
+
+@noindent
+Compiler optimizations in the presence of Inline Assembler may sometimes have
+unwanted effects. For example, when an @code{Asm} invocation with an input
+variable is inside a loop, the compiler might move the loading of the input
+variable outside the loop, regarding it as a one-time initialization.
+
+If this effect is not desired, you can disable such optimizations by setting
+the @code{Volatile} parameter to @code{True}; for example:
+
+@smallexample @c ada
+@group
+Asm ("movl %0, %%ebx" & LF & HT &
+ "movl %%ebx, %1",
+ Inputs => Unsigned_32'Asm_Input ("g", Var_In),
+ Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
+ Clobber => "ebx",
+ Volatile => True);
+@end group
+@end smallexample
+
+By default, @code{Volatile} is set to @code{False} unless there is no
+@code{Outputs} parameter.
+
+Although setting @code{Volatile} to @code{True} prevents unwanted
+optimizations, it will also disable other optimizations that might be
+important for efficiency. In general, you should set @code{Volatile}
+to @code{True} only if the compiler's optimizations have created
+problems.
+
+@c ---------------------------------------------------------------------------
+@node A Complete Example
+@section A Complete Example
+
+@noindent
+This section contains a complete program illustrating a realistic usage
+of GNAT's Inline Assembler capabilities. It comprises a main procedure
+@code{Check_CPU} and a package @code{Intel_CPU}.
+The package declares a collection of functions that detect the properties
+of the 32-bit x86 processor that is running the program.
+The main procedure invokes these functions and displays the information.
+
+The Intel_CPU package could be enhanced by adding functions to
+detect the type of x386 co-processor, the processor caching options and
+special operations such as the SIMD extensions.
+
+Although the Intel_CPU package has been written for 32-bit Intel
+compatible CPUs, it is OS neutral. It has been tested on DOS,
+Windows/NT and GNU/Linux.
+
+@menu
+* Check_CPU Procedure::
+* Intel_CPU Package Specification::
+* Intel_CPU Package Body::
+@end menu
+
+@c ---------------------------------------------------------------------------
+@node Check_CPU Procedure
+@subsection @code{Check_CPU} Procedure
+@cindex Check_CPU procedure
+
+@smallexample @c adanocomment
+---------------------------------------------------------------------
+-- --
+-- Uses the Intel_CPU package to identify the CPU the program is --
+-- running on, and some of the features it supports. --
+-- --
+---------------------------------------------------------------------
+
+with Intel_CPU; -- Intel CPU detection functions
+with Ada.Text_IO; -- Standard text I/O
+with Ada.Command_Line; -- To set the exit status
+
+procedure Check_CPU is
+
+ Type_Found : Boolean := False;
+ -- Flag to indicate that processor was identified
+
+ Features : Intel_CPU.Processor_Features;
+ -- The processor features
+
+ Signature : Intel_CPU.Processor_Signature;
+ -- The processor type signature
+
+begin
+
+ -----------------------------------
+ -- Display the program banner. --
+ -----------------------------------
+
+ Ada.Text_IO.Put_Line (Ada.Command_Line.Command_Name &
+ ": check Intel CPU version and features, v1.0");
+ Ada.Text_IO.Put_Line ("distribute freely, but no warranty whatsoever");
+ Ada.Text_IO.New_Line;
+
+ -----------------------------------------------------------------------
+ -- We can safely start with the assumption that we are on at least --
+ -- a x386 processor. If the CPUID instruction is present, then we --
+ -- have a later processor type. --
+ -----------------------------------------------------------------------
+
+ if Intel_CPU.Has_CPUID = False then
+
+ -- No CPUID instruction, so we assume this is indeed a x386
+ -- processor. We can still check if it has a FP co-processor.
+ if Intel_CPU.Has_FPU then
+ Ada.Text_IO.Put_Line
+ ("x386-type processor with a FP co-processor");
+ else
+ Ada.Text_IO.Put_Line
+ ("x386-type processor without a FP co-processor");
+ end if; -- check for FPU
+
+ -- Program done
+ Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Success);
+ return;
+
+ end if; -- check for CPUID
+
+ -----------------------------------------------------------------------
+ -- If CPUID is supported, check if this is a true Intel processor, --
+ -- if it is not, display a warning. --
+ -----------------------------------------------------------------------
+
+ if Intel_CPU.Vendor_ID /= Intel_CPU.Intel_Processor then
+ Ada.Text_IO.Put_Line ("*** This is a Intel compatible processor");
+ Ada.Text_IO.Put_Line ("*** Some information may be incorrect");
+ end if; -- check if Intel
+
+ ----------------------------------------------------------------------
+ -- With the CPUID instruction present, we can assume at least a --
+ -- x486 processor. If the CPUID support level is < 1 then we have --
+ -- to leave it at that. --
+ ----------------------------------------------------------------------
+
+ if Intel_CPU.CPUID_Level < 1 then
+
+ -- Ok, this is a x486 processor. we still can get the Vendor ID
+ Ada.Text_IO.Put_Line ("x486-type processor");
+ Ada.Text_IO.Put_Line ("Vendor ID is " & Intel_CPU.Vendor_ID);
+
+ -- We can also check if there is a FPU present
+ if Intel_CPU.Has_FPU then
+ Ada.Text_IO.Put_Line ("Floating-Point support");
+ else
+ Ada.Text_IO.Put_Line ("No Floating-Point support");
+ end if; -- check for FPU
+
+ -- Program done
+ Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Success);
+ return;
+
+ end if; -- check CPUID level
+
+ ---------------------------------------------------------------------
+ -- With a CPUID level of 1 we can use the processor signature to --
+ -- determine it's exact type. --
+ ---------------------------------------------------------------------
+
+ Signature := Intel_CPU.Signature;
+
+ ----------------------------------------------------------------------
+ -- Ok, now we go into a lot of messy comparisons to get the --
+ -- processor type. For clarity, no attememt to try to optimize the --
+ -- comparisons has been made. Note that since Intel_CPU does not --
+ -- support getting cache info, we cannot distinguish between P5 --
+ -- and Celeron types yet. --
+ ----------------------------------------------------------------------
+
+ -- x486SL
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0100# and
+ Signature.Model = 2#0100# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("x486SL processor");
+ end if;
+
+ -- x486DX2 Write-Back
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0100# and
+ Signature.Model = 2#0111# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("Write-Back Enhanced x486DX2 processor");
+ end if;
+
+ -- x486DX4
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0100# and
+ Signature.Model = 2#1000# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("x486DX4 processor");
+ end if;
+
+ -- x486DX4 Overdrive
+ if Signature.Processor_Type = 2#01# and
+ Signature.Family = 2#0100# and
+ Signature.Model = 2#1000# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("x486DX4 OverDrive processor");
+ end if;
+
+ -- Pentium (60, 66)
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0001# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("Pentium processor (60, 66)");
+ end if;
+
+ -- Pentium (75, 90, 100, 120, 133, 150, 166, 200)
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0010# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line
+ ("Pentium processor (75, 90, 100, 120, 133, 150, 166, 200)");
+ end if;
+
+ -- Pentium OverDrive (60, 66)
+ if Signature.Processor_Type = 2#01# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0001# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("Pentium OverDrive processor (60, 66)");
+ end if;
+
+ -- Pentium OverDrive (75, 90, 100, 120, 133, 150, 166, 200)
+ if Signature.Processor_Type = 2#01# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0010# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line
+ ("Pentium OverDrive cpu (75, 90, 100, 120, 133, 150, 166, 200)");
+ end if;
+
+ -- Pentium OverDrive processor for x486 processor-based systems
+ if Signature.Processor_Type = 2#01# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0011# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line
+ ("Pentium OverDrive processor for x486 processor-based systems");
+ end if;
+
+ -- Pentium processor with MMX technology (166, 200)
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0100# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line
+ ("Pentium processor with MMX technology (166, 200)");
+ end if;
+
+ -- Pentium OverDrive with MMX for Pentium (75, 90, 100, 120, 133)
+ if Signature.Processor_Type = 2#01# and
+ Signature.Family = 2#0101# and
+ Signature.Model = 2#0100# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line
+ ("Pentium OverDrive processor with MMX " &
+ "technology for Pentium processor (75, 90, 100, 120, 133)");
+ end if;
+
+ -- Pentium Pro processor
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0110# and
+ Signature.Model = 2#0001# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("Pentium Pro processor");
+ end if;
+
+ -- Pentium II processor, model 3
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0110# and
+ Signature.Model = 2#0011# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("Pentium II processor, model 3");
+ end if;
+
+ -- Pentium II processor, model 5 or Celeron processor
+ if Signature.Processor_Type = 2#00# and
+ Signature.Family = 2#0110# and
+ Signature.Model = 2#0101# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line
+ ("Pentium II processor, model 5 or Celeron processor");
+ end if;
+
+ -- Pentium Pro OverDrive processor
+ if Signature.Processor_Type = 2#01# and
+ Signature.Family = 2#0110# and
+ Signature.Model = 2#0011# then
+ Type_Found := True;
+ Ada.Text_IO.Put_Line ("Pentium Pro OverDrive processor");
+ end if;
+
+ -- If no type recognized, we have an unknown. Display what
+ -- we _do_ know
+ if Type_Found = False then
+ Ada.Text_IO.Put_Line ("Unknown processor");
+ end if;
+
+ -----------------------------------------
+ -- Display processor stepping level. --
+ -----------------------------------------
+
+ Ada.Text_IO.Put_Line ("Stepping level:" & Signature.Stepping'Img);
+
+ ---------------------------------
+ -- Display vendor ID string. --
+ ---------------------------------
+
+ Ada.Text_IO.Put_Line ("Vendor ID: " & Intel_CPU.Vendor_ID);
+
+ ------------------------------------
+ -- Get the processors features. --
+ ------------------------------------
+
+ Features := Intel_CPU.Features;
+
+ -----------------------------
+ -- Check for a FPU unit. --
+ -----------------------------
+
+ if Features.FPU = True then
+ Ada.Text_IO.Put_Line ("Floating-Point unit available");
+ else
+ Ada.Text_IO.Put_Line ("no Floating-Point unit");
+ end if; -- check for FPU
+
+ --------------------------------
+ -- List processor features. --
+ --------------------------------
+
+ Ada.Text_IO.Put_Line ("Supported features: ");
+
+ -- Virtual Mode Extension
+ if Features.VME = True then
+ Ada.Text_IO.Put_Line (" VME - Virtual Mode Extension");
+ end if;
+
+ -- Debugging Extension
+ if Features.DE = True then
+ Ada.Text_IO.Put_Line (" DE - Debugging Extension");
+ end if;
+
+ -- Page Size Extension
+ if Features.PSE = True then
+ Ada.Text_IO.Put_Line (" PSE - Page Size Extension");
+ end if;
+
+ -- Time Stamp Counter
+ if Features.TSC = True then
+ Ada.Text_IO.Put_Line (" TSC - Time Stamp Counter");
+ end if;
+
+ -- Model Specific Registers
+ if Features.MSR = True then
+ Ada.Text_IO.Put_Line (" MSR - Model Specific Registers");
+ end if;
+
+ -- Physical Address Extension
+ if Features.PAE = True then
+ Ada.Text_IO.Put_Line (" PAE - Physical Address Extension");
+ end if;
+
+ -- Machine Check Extension
+ if Features.MCE = True then
+ Ada.Text_IO.Put_Line (" MCE - Machine Check Extension");
+ end if;
+
+ -- CMPXCHG8 instruction supported
+ if Features.CX8 = True then
+ Ada.Text_IO.Put_Line (" CX8 - CMPXCHG8 instruction");
+ end if;
+
+ -- on-chip APIC hardware support
+ if Features.APIC = True then
+ Ada.Text_IO.Put_Line (" APIC - on-chip APIC hardware support");
+ end if;
+
+ -- Fast System Call
+ if Features.SEP = True then
+ Ada.Text_IO.Put_Line (" SEP - Fast System Call");
+ end if;
+
+ -- Memory Type Range Registers
+ if Features.MTRR = True then
+ Ada.Text_IO.Put_Line (" MTTR - Memory Type Range Registers");
+ end if;
+
+ -- Page Global Enable
+ if Features.PGE = True then
+ Ada.Text_IO.Put_Line (" PGE - Page Global Enable");
+ end if;
+
+ -- Machine Check Architecture
+ if Features.MCA = True then
+ Ada.Text_IO.Put_Line (" MCA - Machine Check Architecture");
+ end if;
+
+ -- Conditional Move Instruction Supported
+ if Features.CMOV = True then
+ Ada.Text_IO.Put_Line
+ (" CMOV - Conditional Move Instruction Supported");
+ end if;
+
+ -- Page Attribute Table
+ if Features.PAT = True then
+ Ada.Text_IO.Put_Line (" PAT - Page Attribute Table");
+ end if;
+
+ -- 36-bit Page Size Extension
+ if Features.PSE_36 = True then
+ Ada.Text_IO.Put_Line (" PSE_36 - 36-bit Page Size Extension");
+ end if;
+
+ -- MMX technology supported
+ if Features.MMX = True then
+ Ada.Text_IO.Put_Line (" MMX - MMX technology supported");
+ end if;
+
+ -- Fast FP Save and Restore
+ if Features.FXSR = True then
+ Ada.Text_IO.Put_Line (" FXSR - Fast FP Save and Restore");
+ end if;
+
+ ---------------------
+ -- Program done. --
+ ---------------------
+
+ Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Success);
+
+exception
+
+ when others =>
+ Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
+ raise;
+
+end Check_CPU;
+@end smallexample
+
+@c ---------------------------------------------------------------------------
+@node Intel_CPU Package Specification
+@subsection @code{Intel_CPU} Package Specification
+@cindex Intel_CPU package specification
+
+@smallexample @c adanocomment
+-------------------------------------------------------------------------
+-- --
+-- file: intel_cpu.ads --
+-- --
+-- ********************************************* --
+-- * WARNING: for 32-bit Intel processors only * --
+-- ********************************************* --
+-- --
+-- This package contains a number of subprograms that are useful in --
+-- determining the Intel x86 CPU (and the features it supports) on --
+-- which the program is running. --
+-- --
+-- The package is based upon the information given in the Intel --
+-- Application Note AP-485: "Intel Processor Identification and the --
+-- CPUID Instruction" as of April 1998. This application note can be --
+-- found on www.intel.com. --
+-- --
+-- It currently deals with 32-bit processors only, will not detect --
+-- features added after april 1998, and does not guarantee proper --
+-- results on Intel-compatible processors. --
+-- --
+-- Cache info and x386 fpu type detection are not supported. --
+-- --
+-- This package does not use any privileged instructions, so should --
+-- work on any OS running on a 32-bit Intel processor. --
+-- --
+-------------------------------------------------------------------------
+
+with Interfaces; use Interfaces;
+-- for using unsigned types
+
+with System.Machine_Code; use System.Machine_Code;
+-- for using inline assembler code
+
+with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
+-- for inserting control characters
+
+package Intel_CPU is
+
+ ----------------------
+ -- Processor bits --
+ ----------------------
+
+ subtype Num_Bits is Natural range 0 .. 31;
+ -- the number of processor bits (32)
+
+ --------------------------
+ -- Processor register --
+ --------------------------
+
+ -- define a processor register type for easy access to
+ -- the individual bits
+
+ type Processor_Register is array (Num_Bits) of Boolean;
+ pragma Pack (Processor_Register);
+ for Processor_Register'Size use 32;
+
+ -------------------------
+ -- Unsigned register --
+ -------------------------
+
+ -- define a processor register type for easy access to
+ -- the individual bytes
+
+ type Unsigned_Register is
+ record
+ L1 : Unsigned_8;
+ H1 : Unsigned_8;
+ L2 : Unsigned_8;
+ H2 : Unsigned_8;
+ end record;
+
+ for Unsigned_Register use
+ record
+ L1 at 0 range 0 .. 7;
+ H1 at 0 range 8 .. 15;
+ L2 at 0 range 16 .. 23;
+ H2 at 0 range 24 .. 31;
+ end record;
+
+ for Unsigned_Register'Size use 32;
+
+ ---------------------------------
+ -- Intel processor vendor ID --
+ ---------------------------------
+
+ Intel_Processor : constant String (1 .. 12) := "GenuineIntel";
+ -- indicates an Intel manufactured processor
+
+ ------------------------------------
+ -- Processor signature register --
+ ------------------------------------
+
+ -- a register type to hold the processor signature
+
+ type Processor_Signature is
+ record
+ Stepping : Natural range 0 .. 15;
+ Model : Natural range 0 .. 15;
+ Family : Natural range 0 .. 15;
+ Processor_Type : Natural range 0 .. 3;
+ Reserved : Natural range 0 .. 262143;
+ end record;
+
+ for Processor_Signature use
+ record
+ Stepping at 0 range 0 .. 3;
+ Model at 0 range 4 .. 7;
+ Family at 0 range 8 .. 11;
+ Processor_Type at 0 range 12 .. 13;
+ Reserved at 0 range 14 .. 31;
+ end record;
+
+ for Processor_Signature'Size use 32;
+
+ -----------------------------------
+ -- Processor features register --
+ -----------------------------------
+
+ -- a processor register to hold the processor feature flags
+
+ type Processor_Features is
+ record
+ FPU : Boolean; -- floating point unit on chip
+ VME : Boolean; -- virtual mode extension
+ DE : Boolean; -- debugging extension
+ PSE : Boolean; -- page size extension
+ TSC : Boolean; -- time stamp counter
+ MSR : Boolean; -- model specific registers
+ PAE : Boolean; -- physical address extension
+ MCE : Boolean; -- machine check extension
+ CX8 : Boolean; -- cmpxchg8 instruction
+ APIC : Boolean; -- on-chip apic hardware
+ Res_1 : Boolean; -- reserved for extensions
+ SEP : Boolean; -- fast system call
+ MTRR : Boolean; -- memory type range registers
+ PGE : Boolean; -- page global enable
+ MCA : Boolean; -- machine check architecture
+ CMOV : Boolean; -- conditional move supported
+ PAT : Boolean; -- page attribute table
+ PSE_36 : Boolean; -- 36-bit page size extension
+ Res_2 : Natural range 0 .. 31; -- reserved for extensions
+ MMX : Boolean; -- MMX technology supported
+ FXSR : Boolean; -- fast FP save and restore
+ Res_3 : Natural range 0 .. 127; -- reserved for extensions
+ end record;
+
+ for Processor_Features use
+ record
+ FPU at 0 range 0 .. 0;
+ VME at 0 range 1 .. 1;
+ DE at 0 range 2 .. 2;
+ PSE at 0 range 3 .. 3;
+ TSC at 0 range 4 .. 4;
+ MSR at 0 range 5 .. 5;
+ PAE at 0 range 6 .. 6;
+ MCE at 0 range 7 .. 7;
+ CX8 at 0 range 8 .. 8;
+ APIC at 0 range 9 .. 9;
+ Res_1 at 0 range 10 .. 10;
+ SEP at 0 range 11 .. 11;
+ MTRR at 0 range 12 .. 12;
+ PGE at 0 range 13 .. 13;
+ MCA at 0 range 14 .. 14;
+ CMOV at 0 range 15 .. 15;
+ PAT at 0 range 16 .. 16;
+ PSE_36 at 0 range 17 .. 17;
+ Res_2 at 0 range 18 .. 22;
+ MMX at 0 range 23 .. 23;
+ FXSR at 0 range 24 .. 24;
+ Res_3 at 0 range 25 .. 31;
+ end record;
+
+ for Processor_Features'Size use 32;
+
+ -------------------
+ -- Subprograms --
+ -------------------
+
+ function Has_FPU return Boolean;
+ -- return True if a FPU is found
+ -- use only if CPUID is not supported
+
+ function Has_CPUID return Boolean;
+ -- return True if the processor supports the CPUID instruction
+
+ function CPUID_Level return Natural;
+ -- return the CPUID support level (0, 1 or 2)
+ -- can only be called if the CPUID instruction is supported
+
+ function Vendor_ID return String;
+ -- return the processor vendor identification string
+ -- can only be called if the CPUID instruction is supported
+
+ function Signature return Processor_Signature;
+ -- return the processor signature
+ -- can only be called if the CPUID instruction is supported
+
+ function Features return Processor_Features;
+ -- return the processors features
+ -- can only be called if the CPUID instruction is supported
+
+private
+
+ ------------------------
+ -- EFLAGS bit names --
+ ------------------------
+
+ ID_Flag : constant Num_Bits := 21;
+ -- ID flag bit
+
+end Intel_CPU;
+@end smallexample
+
+@c ---------------------------------------------------------------------------
+@node Intel_CPU Package Body
+@subsection @code{Intel_CPU} Package Body
+@cindex Intel_CPU package body
+
+@smallexample @c adanocomment
+package body Intel_CPU is
+
+ ---------------------------
+ -- Detect FPU presence --
+ ---------------------------
+
+ -- There is a FPU present if we can set values to the FPU Status
+ -- and Control Words.
+
+ function Has_FPU return Boolean is
+
+ Register : Unsigned_16;
+ -- processor register to store a word
+
+ begin
+
+ -- check if we can change the status word
+ Asm (
+
+ -- the assembler code
+ "finit" & LF & HT & -- reset status word
+ "movw $0x5A5A, %%ax" & LF & HT & -- set value status word
+ "fnstsw %0" & LF & HT & -- save status word
+ "movw %%ax, %0", -- store status word
+
+ -- output stored in Register
+ -- register must be a memory location
+ Outputs => Unsigned_16'Asm_output ("=m", Register),
+
+ -- tell compiler that we used eax
+ Clobber => "eax");
+
+ -- if the status word is zero, there is no FPU
+ if Register = 0 then
+ return False; -- no status word
+ end if; -- check status word value
+
+ -- check if we can get the control word
+ Asm (
+
+ -- the assembler code
+ "fnstcw %0", -- save the control word
+
+ -- output into Register
+ -- register must be a memory location
+ Outputs => Unsigned_16'Asm_output ("=m", Register));
+
+ -- check the relevant bits
+ if (Register and 16#103F#) /= 16#003F# then
+ return False; -- no control word
+ end if; -- check control word value
+
+ -- FPU found
+ return True;
+
+ end Has_FPU;
+
+ --------------------------------
+ -- Detect CPUID instruction --
+ --------------------------------
+
+ -- The processor supports the CPUID instruction if it is possible
+ -- to change the value of ID flag bit in the EFLAGS register.
+
+ function Has_CPUID return Boolean is
+
+ Original_Flags, Modified_Flags : Processor_Register;
+ -- EFLAG contents before and after changing the ID flag
+
+ begin
+
+ -- try flipping the ID flag in the EFLAGS register
+ Asm (
+
+ -- the assembler code
+ "pushfl" & LF & HT & -- push EFLAGS on stack
+ "pop %%eax" & LF & HT & -- pop EFLAGS into eax
+ "movl %%eax, %0" & LF & HT & -- save EFLAGS content
+ "xor $0x200000, %%eax" & LF & HT & -- flip ID flag
+ "push %%eax" & LF & HT & -- push EFLAGS on stack
+ "popfl" & LF & HT & -- load EFLAGS register
+ "pushfl" & LF & HT & -- push EFLAGS on stack
+ "pop %1", -- save EFLAGS content
+
+ -- output values, may be anything
+ -- Original_Flags is %0
+ -- Modified_Flags is %1
+ Outputs =>
+ (Processor_Register'Asm_output ("=g", Original_Flags),
+ Processor_Register'Asm_output ("=g", Modified_Flags)),
+
+ -- tell compiler eax is destroyed
+ Clobber => "eax");
+
+ -- check if CPUID is supported
+ if Original_Flags(ID_Flag) /= Modified_Flags(ID_Flag) then
+ return True; -- ID flag was modified
+ else
+ return False; -- ID flag unchanged
+ end if; -- check for CPUID
+
+ end Has_CPUID;
+
+ -------------------------------
+ -- Get CPUID support level --
+ -------------------------------
+
+ function CPUID_Level return Natural is
+
+ Level : Unsigned_32;
+ -- returned support level
+
+ begin
+
+ -- execute CPUID, storing the results in the Level register
+ Asm (
+
+ -- the assembler code
+ "cpuid", -- execute CPUID
+
+ -- zero is stored in eax
+ -- returning the support level in eax
+ Inputs => Unsigned_32'Asm_input ("a", 0),
+
+ -- eax is stored in Level
+ Outputs => Unsigned_32'Asm_output ("=a", Level),
+
+ -- tell compiler ebx, ecx and edx registers are destroyed
+ Clobber => "ebx, ecx, edx");
+
+ -- return the support level
+ return Natural (Level);
+
+ end CPUID_Level;
+
+ --------------------------------
+ -- Get CPU Vendor ID String --
+ --------------------------------
+
+ -- The vendor ID string is returned in the ebx, ecx and edx register
+ -- after executing the CPUID instruction with eax set to zero.
+ -- In case of a true Intel processor the string returned is
+ -- "GenuineIntel"
+
+ function Vendor_ID return String is
+
+ Ebx, Ecx, Edx : Unsigned_Register;
+ -- registers containing the vendor ID string
+
+ Vendor_ID : String (1 .. 12);
+ -- the vendor ID string
+
+ begin
+
+ -- execute CPUID, storing the results in the processor registers
+ Asm (
+
+ -- the assembler code
+ "cpuid", -- execute CPUID
+
+ -- zero stored in eax
+ -- vendor ID string returned in ebx, ecx and edx
+ Inputs => Unsigned_32'Asm_input ("a", 0),
+
+ -- ebx is stored in Ebx
+ -- ecx is stored in Ecx
+ -- edx is stored in Edx
+ Outputs => (Unsigned_Register'Asm_output ("=b", Ebx),
+ Unsigned_Register'Asm_output ("=c", Ecx),
+ Unsigned_Register'Asm_output ("=d", Edx)));
+
+ -- now build the vendor ID string
+ Vendor_ID( 1) := Character'Val (Ebx.L1);
+ Vendor_ID( 2) := Character'Val (Ebx.H1);
+ Vendor_ID( 3) := Character'Val (Ebx.L2);
+ Vendor_ID( 4) := Character'Val (Ebx.H2);
+ Vendor_ID( 5) := Character'Val (Edx.L1);
+ Vendor_ID( 6) := Character'Val (Edx.H1);
+ Vendor_ID( 7) := Character'Val (Edx.L2);
+ Vendor_ID( 8) := Character'Val (Edx.H2);
+ Vendor_ID( 9) := Character'Val (Ecx.L1);
+ Vendor_ID(10) := Character'Val (Ecx.H1);
+ Vendor_ID(11) := Character'Val (Ecx.L2);
+ Vendor_ID(12) := Character'Val (Ecx.H2);
+
+ -- return string
+ return Vendor_ID;
+
+ end Vendor_ID;
+
+ -------------------------------
+ -- Get processor signature --
+ -------------------------------
+
+ function Signature return Processor_Signature is
+
+ Result : Processor_Signature;
+ -- processor signature returned
+
+ begin
+
+ -- execute CPUID, storing the results in the Result variable
+ Asm (
+
+ -- the assembler code
+ "cpuid", -- execute CPUID
+
+ -- one is stored in eax
+ -- processor signature returned in eax
+ Inputs => Unsigned_32'Asm_input ("a", 1),
+
+ -- eax is stored in Result
+ Outputs => Processor_Signature'Asm_output ("=a", Result),
+
+ -- tell compiler that ebx, ecx and edx are also destroyed
+ Clobber => "ebx, ecx, edx");
+
+ -- return processor signature
+ return Result;
+
+ end Signature;
+
+ ------------------------------
+ -- Get processor features --
+ ------------------------------
+
+ function Features return Processor_Features is
+
+ Result : Processor_Features;
+ -- processor features returned
+
+ begin
+
+ -- execute CPUID, storing the results in the Result variable
+ Asm (
+
+ -- the assembler code
+ "cpuid", -- execute CPUID
+
+ -- one stored in eax
+ -- processor features returned in edx
+ Inputs => Unsigned_32'Asm_input ("a", 1),
+
+ -- edx is stored in Result
+ Outputs => Processor_Features'Asm_output ("=d", Result),
+
+ -- tell compiler that ebx and ecx are also destroyed
+ Clobber => "ebx, ecx");
+
+ -- return processor signature
+ return Result;
+
+ end Features;
+
+end Intel_CPU;
+@end smallexample
+@c END OF INLINE ASSEMBLER CHAPTER
+@c ===============================
+
+
+
+@c ***********************************
+@c * Compatibility and Porting Guide *
+@c ***********************************
+@node Compatibility and Porting Guide
+@appendix Compatibility and Porting Guide
+
+@noindent
+This chapter describes the compatibility issues that may arise between
+GNAT and other Ada 83 and Ada 95 compilation systems, and shows how GNAT
+can expedite porting
+applications developed in other Ada environments.
+
+@menu
+* Compatibility with Ada 83::
+* Implementation-dependent characteristics::
+* Compatibility with DEC Ada 83::
+* Compatibility with Other Ada 95 Systems::
+* Representation Clauses::
+@end menu
+
+@node Compatibility with Ada 83
+@section Compatibility with Ada 83
+@cindex Compatibility (between Ada 83 and Ada 95)
+
+@noindent
+Ada 95 is designed to be highly upwards compatible with Ada 83. In
+particular, the design intention is that the difficulties associated
+with moving from Ada 83 to Ada 95 should be no greater than those
+that occur when moving from one Ada 83 system to another.
+
+However, there are a number of points at which there are minor
+incompatibilities. The @cite{Ada 95 Annotated Reference Manual} contains
+full details of these issues,
+and should be consulted for a complete treatment.
+In practice the
+following subsections treat the most likely issues to be encountered.
+
+@menu
+* Legal Ada 83 programs that are illegal in Ada 95::
+* More deterministic semantics::
+* Changed semantics::
+* Other language compatibility issues::
+@end menu
+
+@node Legal Ada 83 programs that are illegal in Ada 95
+@subsection Legal Ada 83 programs that are illegal in Ada 95
+
+@table @asis
+@item Character literals
+Some uses of character literals are ambiguous. Since Ada 95 has introduced
+@code{Wide_Character} as a new predefined character type, some uses of
+character literals that were legal in Ada 83 are illegal in Ada 95.
+For example:
+@smallexample @c ada
+ for Char in 'A' .. 'Z' loop ... end loop;
+@end smallexample
+@noindent
+The problem is that @code{'A'} and @code{'Z'} could be from either
+@code{Character} or @code{Wide_Character}. The simplest correction
+is to make the type explicit; e.g.:
+@smallexample @c ada
+ for Char in Character range 'A' .. 'Z' loop ... end loop;
+@end smallexample
+
+@item New reserved words
+The identifiers @code{abstract}, @code{aliased}, @code{protected},
+@code{requeue}, @code{tagged}, and @code{until} are reserved in Ada 95.
+Existing Ada 83 code using any of these identifiers must be edited to
+use some alternative name.
+
+@item Freezing rules
+The rules in Ada 95 are slightly different with regard to the point at
+which entities are frozen, and representation pragmas and clauses are
+not permitted past the freeze point. This shows up most typically in
+the form of an error message complaining that a representation item
+appears too late, and the appropriate corrective action is to move
+the item nearer to the declaration of the entity to which it refers.
+
+A particular case is that representation pragmas
+@ifset vms
+(including the
+extended DEC Ada 83 compatibility pragmas such as @code{Export_Procedure})
+@end ifset
+cannot be applied to a subprogram body. If necessary, a separate subprogram
+declaration must be introduced to which the pragma can be applied.
+
+@item Optional bodies for library packages
+In Ada 83, a package that did not require a package body was nevertheless
+allowed to have one. This lead to certain surprises in compiling large
+systems (situations in which the body could be unexpectedly ignored by the
+binder). In Ada 95, if a package does not require a body then it is not
+permitted to have a body. To fix this problem, simply remove a redundant
+body if it is empty, or, if it is non-empty, introduce a dummy declaration
+into the spec that makes the body required. One approach is to add a private
+part to the package declaration (if necessary), and define a parameterless
+procedure called @code{Requires_Body}, which must then be given a dummy
+procedure body in the package body, which then becomes required.
+Another approach (assuming that this does not introduce elaboration
+circularities) is to add an @code{Elaborate_Body} pragma to the package spec,
+since one effect of this pragma is to require the presence of a package body.
+
+@item @code{Numeric_Error} is now the same as @code{Constraint_Error}
+In Ada 95, the exception @code{Numeric_Error} is a renaming of
+@code{Constraint_Error}.
+This means that it is illegal to have separate exception handlers for
+the two exceptions. The fix is simply to remove the handler for the
+@code{Numeric_Error} case (since even in Ada 83, a compiler was free to raise
+@code{Constraint_Error} in place of @code{Numeric_Error} in all cases).
+
+@item Indefinite subtypes in generics
+In Ada 83, it was permissible to pass an indefinite type (e.g.@: @code{String})
+as the actual for a generic formal private type, but then the instantiation
+would be illegal if there were any instances of declarations of variables
+of this type in the generic body. In Ada 95, to avoid this clear violation
+of the methodological principle known as the ``contract model'',
+the generic declaration explicitly indicates whether
+or not such instantiations are permitted. If a generic formal parameter
+has explicit unknown discriminants, indicated by using @code{(<>)} after the
+type name, then it can be instantiated with indefinite types, but no
+stand-alone variables can be declared of this type. Any attempt to declare
+such a variable will result in an illegality at the time the generic is
+declared. If the @code{(<>)} notation is not used, then it is illegal
+to instantiate the generic with an indefinite type.
+This is the potential incompatibility issue when porting Ada 83 code to Ada 95.
+It will show up as a compile time error, and
+the fix is usually simply to add the @code{(<>)} to the generic declaration.
+@end table
+
+@node More deterministic semantics
+@subsection More deterministic semantics
+
+@table @asis
+@item Conversions
+Conversions from real types to integer types round away from 0. In Ada 83
+the conversion Integer(2.5) could deliver either 2 or 3 as its value. This
+implementation freedom was intended to support unbiased rounding in
+statistical applications, but in practice it interfered with portability.
+In Ada 95 the conversion semantics are unambiguous, and rounding away from 0
+is required. Numeric code may be affected by this change in semantics.
+Note, though, that this issue is no worse than already existed in Ada 83
+when porting code from one vendor to another.
+
+@item Tasking
+The Real-Time Annex introduces a set of policies that define the behavior of
+features that were implementation dependent in Ada 83, such as the order in
+which open select branches are executed.
+@end table
+
+@node Changed semantics
+@subsection Changed semantics
+
+@noindent
+The worst kind of incompatibility is one where a program that is legal in
+Ada 83 is also legal in Ada 95 but can have an effect in Ada 95 that was not
+possible in Ada 83. Fortunately this is extremely rare, but the one
+situation that you should be alert to is the change in the predefined type
+@code{Character} from 7-bit ASCII to 8-bit Latin-1.
+
+@table @asis
+@item range of @code{Character}
+The range of @code{Standard.Character} is now the full 256 characters
+of Latin-1, whereas in most Ada 83 implementations it was restricted
+to 128 characters. Although some of the effects of
+this change will be manifest in compile-time rejection of legal
+Ada 83 programs it is possible for a working Ada 83 program to have
+a different effect in Ada 95, one that was not permitted in Ada 83.
+As an example, the expression
+@code{Character'Pos(Character'Last)} returned @code{127} in Ada 83 and now
+delivers @code{255} as its value.
+In general, you should look at the logic of any
+character-processing Ada 83 program and see whether it needs to be adapted
+to work correctly with Latin-1. Note that the predefined Ada 95 API has a
+character handling package that may be relevant if code needs to be adapted
+to account for the additional Latin-1 elements.
+The desirable fix is to
+modify the program to accommodate the full character set, but in some cases
+it may be convenient to define a subtype or derived type of Character that
+covers only the restricted range.
+@cindex Latin-1
+@end table
+
+@node Other language compatibility issues
+@subsection Other language compatibility issues
+@table @asis
+@item @option{-gnat83 switch}
+All implementations of GNAT provide a switch that causes GNAT to operate
+in Ada 83 mode. In this mode, some but not all compatibility problems
+of the type described above are handled automatically. For example, the
+new Ada 95 reserved words are treated simply as identifiers as in Ada 83.
+However,
+in practice, it is usually advisable to make the necessary modifications
+to the program to remove the need for using this switch.
+See @ref{Compiling Ada 83 Programs}.
+
+@item Support for removed Ada 83 pragmas and attributes
+A number of pragmas and attributes from Ada 83 have been removed from Ada 95,
+generally because they have been replaced by other mechanisms. Ada 95
+compilers are allowed, but not required, to implement these missing
+elements. In contrast with some other Ada 95 compilers, GNAT implements all
+such pragmas and attributes, eliminating this compatibility concern. These
+include @code{pragma Interface} and the floating point type attributes
+(@code{Emax}, @code{Mantissa}, etc.), among other items.
+@end table
+
+
+@node Implementation-dependent characteristics
+@section Implementation-dependent characteristics
+@noindent
+Although the Ada language defines the semantics of each construct as
+precisely as practical, in some situations (for example for reasons of
+efficiency, or where the effect is heavily dependent on the host or target
+platform) the implementation is allowed some freedom. In porting Ada 83
+code to GNAT, you need to be aware of whether / how the existing code
+exercised such implementation dependencies. Such characteristics fall into
+several categories, and GNAT offers specific support in assisting the
+transition from certain Ada 83 compilers.
+
+@menu
+* Implementation-defined pragmas::
+* Implementation-defined attributes::
+* Libraries::
+* Elaboration order::
+* Target-specific aspects::
+@end menu
+
+
+@node Implementation-defined pragmas
+@subsection Implementation-defined pragmas
+
+@noindent
+Ada compilers are allowed to supplement the language-defined pragmas, and
+these are a potential source of non-portability. All GNAT-defined pragmas
+are described in the GNAT Reference Manual, and these include several that
+are specifically intended to correspond to other vendors' Ada 83 pragmas.
+For migrating from VADS, the pragma @code{Use_VADS_Size} may be useful.
+For
+compatibility with DEC Ada 83, GNAT supplies the pragmas
+@code{Extend_System}, @code{Ident}, @code{Inline_Generic},
+@code{Interface_Name}, @code{Passive}, @code{Suppress_All},
+and @code{Volatile}.
+Other relevant pragmas include @code{External} and @code{Link_With}.
+Some vendor-specific
+Ada 83 pragmas (@code{Share_Generic}, @code{Subtitle}, and @code{Title}) are
+recognized, thus
+avoiding compiler rejection of units that contain such pragmas; they are not
+relevant in a GNAT context and hence are not otherwise implemented.
+
+@node Implementation-defined attributes
+@subsection Implementation-defined attributes
+
+Analogous to pragmas, the set of attributes may be extended by an
+implementation. All GNAT-defined attributes are described in the
+@cite{GNAT Reference Manual}, and these include several that are specifically
+intended
+to correspond to other vendors' Ada 83 attributes. For migrating from VADS,
+the attribute @code{VADS_Size} may be useful. For compatibility with DEC
+Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and
+@code{Type_Class}.
+
+@node Libraries
+@subsection Libraries
+@noindent
+Vendors may supply libraries to supplement the standard Ada API. If Ada 83
+code uses vendor-specific libraries then there are several ways to manage
+this in Ada 95:
+@enumerate
+@item
+If the source code for the libraries (specifications and bodies) are
+available, then the libraries can be migrated in the same way as the
+application.
+@item
+If the source code for the specifications but not the bodies are
+available, then you can reimplement the bodies.
+@item
+Some new Ada 95 features obviate the need for library support. For
+example most Ada 83 vendors supplied a package for unsigned integers. The
+Ada 95 modular type feature is the preferred way to handle this need, so
+instead of migrating or reimplementing the unsigned integer package it may
+be preferable to retrofit the application using modular types.
+@end enumerate
+
+@node Elaboration order
+@subsection Elaboration order
+@noindent
+The implementation can choose any elaboration order consistent with the unit
+dependency relationship. This freedom means that some orders can result in
+Program_Error being raised due to an ``Access Before Elaboration'': an attempt
+to invoke a subprogram its body has been elaborated, or to instantiate a
+generic before the generic body has been elaborated. By default GNAT
+attempts to choose a safe order (one that will not encounter access before
+elaboration problems) by implicitly inserting Elaborate_All pragmas where
+needed. However, this can lead to the creation of elaboration circularities
+and a resulting rejection of the program by gnatbind. This issue is
+thoroughly described in @ref{Elaboration Order Handling in GNAT}.
+In brief, there are several
+ways to deal with this situation:
+
+@itemize @bullet
+@item
+Modify the program to eliminate the circularities, e.g. by moving
+elaboration-time code into explicitly-invoked procedures
+@item
+Constrain the elaboration order by including explicit @code{Elaborate_Body} or
+@code{Elaborate} pragmas, and then inhibit the generation of implicit
+@code{Elaborate_All}
+pragmas either globally (as an effect of the @option{-gnatE} switch) or locally
+(by selectively suppressing elaboration checks via pragma
+@code{Suppress(Elaboration_Check)} when it is safe to do so).
+@end itemize
+
+@node Target-specific aspects
+@subsection Target-specific aspects
+@noindent
+Low-level applications need to deal with machine addresses, data
+representations, interfacing with assembler code, and similar issues. If
+such an Ada 83 application is being ported to different target hardware (for
+example where the byte endianness has changed) then you will need to
+carefully examine the program logic; the porting effort will heavily depend
+on the robustness of the original design. Moreover, Ada 95 is sometimes
+incompatible with typical Ada 83 compiler practices regarding implicit
+packing, the meaning of the Size attribute, and the size of access values.
+GNAT's approach to these issues is described in @ref{Representation Clauses}.
+
+
+@node Compatibility with Other Ada 95 Systems
+@section Compatibility with Other Ada 95 Systems
+
+@noindent
+Providing that programs avoid the use of implementation dependent and
+implementation defined features of Ada 95, as documented in the Ada 95
+reference manual, there should be a high degree of portability between
+GNAT and other Ada 95 systems. The following are specific items which
+have proved troublesome in moving GNAT programs to other Ada 95
+compilers, but do not affect porting code to GNAT@.
+
+@table @asis
+@item Ada 83 Pragmas and Attributes
+Ada 95 compilers are allowed, but not required, to implement the missing
+Ada 83 pragmas and attributes that are no longer defined in Ada 95.
+GNAT implements all such pragmas and attributes, eliminating this as
+a compatibility concern, but some other Ada 95 compilers reject these
+pragmas and attributes.
+
+@item Special-needs Annexes
+GNAT implements the full set of special needs annexes. At the
+current time, it is the only Ada 95 compiler to do so. This means that
+programs making use of these features may not be portable to other Ada
+95 compilation systems.
+
+@item Representation Clauses
+Some other Ada 95 compilers implement only the minimal set of
+representation clauses required by the Ada 95 reference manual. GNAT goes
+far beyond this minimal set, as described in the next section.
+@end table
+
+@node Representation Clauses
+@section Representation Clauses
+
+@noindent
+The Ada 83 reference manual was quite vague in describing both the minimal
+required implementation of representation clauses, and also their precise
+effects. The Ada 95 reference manual is much more explicit, but the minimal
+set of capabilities required in Ada 95 is quite limited.
+
+GNAT implements the full required set of capabilities described in the
+Ada 95 reference manual, but also goes much beyond this, and in particular
+an effort has been made to be compatible with existing Ada 83 usage to the
+greatest extent possible.
+
+A few cases exist in which Ada 83 compiler behavior is incompatible with
+requirements in the Ada 95 reference manual. These are instances of
+intentional or accidental dependence on specific implementation dependent
+characteristics of these Ada 83 compilers. The following is a list of
+the cases most likely to arise in existing legacy Ada 83 code.
+
+@table @asis
+@item Implicit Packing
+Some Ada 83 compilers allowed a Size specification to cause implicit
+packing of an array or record. This could cause expensive implicit
+conversions for change of representation in the presence of derived
+types, and the Ada design intends to avoid this possibility.
+Subsequent AI's were issued to make it clear that such implicit
+change of representation in response to a Size clause is inadvisable,
+and this recommendation is represented explicitly in the Ada 95 RM
+as implementation advice that is followed by GNAT@.
+The problem will show up as an error
+message rejecting the size clause. The fix is simply to provide
+the explicit pragma @code{Pack}, or for more fine tuned control, provide
+a Component_Size clause.
+
+@item Meaning of Size Attribute
+The Size attribute in Ada 95 for discrete types is defined as being the
+minimal number of bits required to hold values of the type. For example,
+on a 32-bit machine, the size of Natural will typically be 31 and not
+32 (since no sign bit is required). Some Ada 83 compilers gave 31, and
+some 32 in this situation. This problem will usually show up as a compile
+time error, but not always. It is a good idea to check all uses of the
+'Size attribute when porting Ada 83 code. The GNAT specific attribute
+Object_Size can provide a useful way of duplicating the behavior of
+some Ada 83 compiler systems.
+
+@item Size of Access Types
+A common assumption in Ada 83 code is that an access type is in fact a pointer,
+and that therefore it will be the same size as a System.Address value. This
+assumption is true for GNAT in most cases with one exception. For the case of
+a pointer to an unconstrained array type (where the bounds may vary from one
+value of the access type to another), the default is to use a ``fat pointer'',
+which is represented as two separate pointers, one to the bounds, and one to
+the array. This representation has a number of advantages, including improved
+efficiency. However, it may cause some difficulties in porting existing Ada 83
+code which makes the assumption that, for example, pointers fit in 32 bits on
+a machine with 32-bit addressing.
+
+To get around this problem, GNAT also permits the use of ``thin pointers'' for
+access types in this case (where the designated type is an unconstrained array
+type). These thin pointers are indeed the same size as a System.Address value.
+To specify a thin pointer, use a size clause for the type, for example:
+
+@smallexample @c ada
+type X is access all String;
+for X'Size use Standard'Address_Size;
+@end smallexample
+
+@noindent
+which will cause the type X to be represented using a single pointer.
+When using this representation, the bounds are right behind the array.
+This representation is slightly less efficient, and does not allow quite
+such flexibility in the use of foreign pointers or in using the
+Unrestricted_Access attribute to create pointers to non-aliased objects.
+But for any standard portable use of the access type it will work in
+a functionally correct manner and allow porting of existing code.
+Note that another way of forcing a thin pointer representation
+is to use a component size clause for the element size in an array,
+or a record representation clause for an access field in a record.
+@end table
+
+@node Compatibility with DEC Ada 83
+@section Compatibility with DEC Ada 83
+
+@noindent
+The VMS version of GNAT fully implements all the pragmas and attributes
+provided by DEC Ada 83, as well as providing the standard DEC Ada 83
+libraries, including Starlet. In addition, data layouts and parameter
+passing conventions are highly compatible. This means that porting
+existing DEC Ada 83 code to GNAT in VMS systems should be easier than
+most other porting efforts. The following are some of the most
+significant differences between GNAT and DEC Ada 83.
+
+@table @asis
+@item Default floating-point representation
+In GNAT, the default floating-point format is IEEE, whereas in DEC Ada 83,
+it is VMS format. GNAT does implement the necessary pragmas
+(Long_Float, Float_Representation) for changing this default.
+
+@item System
+The package System in GNAT exactly corresponds to the definition in the
+Ada 95 reference manual, which means that it excludes many of the
+DEC Ada 83 extensions. However, a separate package Aux_DEC is provided
+that contains the additional definitions, and a special pragma,
+Extend_System allows this package to be treated transparently as an
+extension of package System.
+
+@item To_Address
+The definitions provided by Aux_DEC are exactly compatible with those
+in the DEC Ada 83 version of System, with one exception.
+DEC Ada provides the following declarations:
+
+@smallexample @c ada
+TO_ADDRESS (INTEGER)
+TO_ADDRESS (UNSIGNED_LONGWORD)
+TO_ADDRESS (universal_integer)
+@end smallexample
+
+@noindent
+The version of TO_ADDRESS taking a universal integer argument is in fact
+an extension to Ada 83 not strictly compatible with the reference manual.
+In GNAT, we are constrained to be exactly compatible with the standard,
+and this means we cannot provide this capability. In DEC Ada 83, the
+point of this definition is to deal with a call like:
+
+@smallexample @c ada
+TO_ADDRESS (16#12777#);
+@end smallexample
+
+@noindent
+Normally, according to the Ada 83 standard, one would expect this to be
+ambiguous, since it matches both the INTEGER and UNSIGNED_LONGWORD forms
+of TO_ADDRESS@. However, in DEC Ada 83, there is no ambiguity, since the
+definition using universal_integer takes precedence.
+
+In GNAT, since the version with universal_integer cannot be supplied, it is
+not possible to be 100% compatible. Since there are many programs using
+numeric constants for the argument to TO_ADDRESS, the decision in GNAT was
+to change the name of the function in the UNSIGNED_LONGWORD case, so the
+declarations provided in the GNAT version of AUX_Dec are:
+
+@smallexample @c ada
+function To_Address (X : Integer) return Address;
+pragma Pure_Function (To_Address);
+
+function To_Address_Long (X : Unsigned_Longword)
+ return Address;
+pragma Pure_Function (To_Address_Long);
+@end smallexample
+
+@noindent
+This means that programs using TO_ADDRESS for UNSIGNED_LONGWORD must
+change the name to TO_ADDRESS_LONG@.
+
+@item Task_Id values
+The Task_Id values assigned will be different in the two systems, and GNAT
+does not provide a specified value for the Task_Id of the environment task,
+which in GNAT is treated like any other declared task.
+@end table
+
+For full details on these and other less significant compatibility issues,
+see appendix E of the Digital publication entitled @cite{DEC Ada, Technical
+Overview and Comparison on DIGITAL Platforms}.
+
+For GNAT running on other than VMS systems, all the DEC Ada 83 pragmas and
+attributes are recognized, although only a subset of them can sensibly
+be implemented. The description of pragmas in this reference manual
+indicates whether or not they are applicable to non-VMS systems.
+
+
+
+@ifset unw
+@node Microsoft Windows Topics
+@appendix Microsoft Windows Topics
+@cindex Windows NT
+@cindex Windows 95
+@cindex Windows 98
+
+@noindent
+This chapter describes topics that are specific to the Microsoft Windows
+platforms (NT, 2000, and XP Professional).
+
+@menu
+* Using GNAT on Windows::
+* Using a network installation of GNAT::
+* CONSOLE and WINDOWS subsystems::
+* Temporary Files::
+* Mixed-Language Programming on Windows::
+* Windows Calling Conventions::
+* Introduction to Dynamic Link Libraries (DLLs)::
+* Using DLLs with GNAT::
+* Building DLLs with GNAT::
+* GNAT and Windows Resources::
+* Debugging a DLL::
+* GNAT and COM/DCOM Objects::
+@end menu
+
+@node Using GNAT on Windows
+@section Using GNAT on Windows
+
+@noindent
+One of the strengths of the GNAT technology is that its tool set
+(@code{gcc}, @code{gnatbind}, @code{gnatlink}, @code{gnatmake}, the
+@code{gdb} debugger, etc.) is used in the same way regardless of the
+platform.
+
+On Windows this tool set is complemented by a number of Microsoft-specific
+tools that have been provided to facilitate interoperability with Windows
+when this is required. With these tools:
+
+@itemize @bullet
+
+@item
+You can build applications using the @code{CONSOLE} or @code{WINDOWS}
+subsystems.
+
+@item
+You can use any Dynamically Linked Library (DLL) in your Ada code (both
+relocatable and non-relocatable DLLs are supported).
+
+@item
+You can build Ada DLLs for use in other applications. These applications
+can be written in a language other than Ada (e.g., C, C++, etc). Again both
+relocatable and non-relocatable Ada DLLs are supported.
+
+@item
+You can include Windows resources in your Ada application.
+
+@item
+You can use or create COM/DCOM objects.
+@end itemize
+
+@noindent
+Immediately below are listed all known general GNAT-for-Windows restrictions.
+Other restrictions about specific features like Windows Resources and DLLs
+are listed in separate sections below.
+
+@itemize @bullet
+
+@item
+It is not possible to use @code{GetLastError} and @code{SetLastError}
+when tasking, protected records, or exceptions are used. In these
+cases, in order to implement Ada semantics, the GNAT run-time system
+calls certain Win32 routines that set the last error variable to 0 upon
+success. It should be possible to use @code{GetLastError} and
+@code{SetLastError} when tasking, protected record, and exception
+features are not used, but it is not guaranteed to work.
+
+@item
+It is not possible to link against Microsoft libraries except for
+import libraries. The library must be built to be compatible with
+@file{MSVCRT.LIB} (/MD Microsoft compiler option), @file{LIBC.LIB} and
+@file{LIBCMT.LIB} (/ML or /MT Microsoft compiler options) are known to
+not be compatible with the GNAT runtime. Even if the library is
+compatible with @file{MSVCRT.LIB} it is not guaranteed to work.
+
+@item
+When the compilation environment is located on FAT32 drives, users may
+experience recompilations of the source files that have not changed if
+Daylight Saving Time (DST) state has changed since the last time files
+were compiled. NTFS drives do not have this problem.
+
+@item
+No components of the GNAT toolset use any entries in the Windows
+registry. The only entries that can be created are file associations and
+PATH settings, provided the user has chosen to create them at installation
+time, as well as some minimal book-keeping information needed to correctly
+uninstall or integrate different GNAT products.
+@end itemize
+
+@node Using a network installation of GNAT
+@section Using a network installation of GNAT
+
+@noindent
+Make sure the system on which GNAT is installed is accessible from the
+current machine, i.e. the install location is shared over the network.
+Shared resources are accessed on Windows by means of UNC paths, which
+have the format @code{\\server\sharename\path}
+
+In order to use such a network installation, simply add the UNC path of the
+@file{bin} directory of your GNAT installation in front of your PATH. For
+example, if GNAT is installed in @file{\GNAT} directory of a share location
+called @file{c-drive} on a machine @file{LOKI}, the following command will
+make it available:
+
+@code{@ @ @ path \\loki\c-drive\gnat\bin;%path%}
+
+Be aware that every compilation using the network installation results in the
+transfer of large amounts of data across the network and will likely cause
+serious performance penalty.
+
+@node CONSOLE and WINDOWS subsystems
+@section CONSOLE and WINDOWS subsystems
+@cindex CONSOLE Subsystem
+@cindex WINDOWS Subsystem
+@cindex -mwindows
+
+@noindent
+There are two main subsystems under Windows. The @code{CONSOLE} subsystem
+(which is the default subsystem) will always create a console when
+launching the application. This is not something desirable when the
+application has a Windows GUI. To get rid of this console the
+application must be using the @code{WINDOWS} subsystem. To do so
+the @option{-mwindows} linker option must be specified.
+
+@smallexample
+$ gnatmake winprog -largs -mwindows
+@end smallexample
+
+@node Temporary Files
+@section Temporary Files
+@cindex Temporary files
+
+@noindent
+It is possible to control where temporary files gets created by setting
+the TMP environment variable. The file will be created:
+
+@itemize
+@item Under the directory pointed to by the TMP environment variable if
+this directory exists.
+
+@item Under c:\temp, if the TMP environment variable is not set (or not
+pointing to a directory) and if this directory exists.
+
+@item Under the current working directory otherwise.
+@end itemize
+
+@noindent
+This allows you to determine exactly where the temporary
+file will be created. This is particularly useful in networked
+environments where you may not have write access to some
+directories.
+
+@node Mixed-Language Programming on Windows
+@section Mixed-Language Programming on Windows
+
+@noindent
+Developing pure Ada applications on Windows is no different than on
+other GNAT-supported platforms. However, when developing or porting an
+application that contains a mix of Ada and C/C++, the choice of your
+Windows C/C++ development environment conditions your overall
+interoperability strategy.
+
+If you use @code{gcc} to compile the non-Ada part of your application,
+there are no Windows-specific restrictions that affect the overall
+interoperability with your Ada code. If you plan to use
+Microsoft tools (e.g. Microsoft Visual C/C++), you should be aware of
+the following limitations:
+
+@itemize @bullet
+@item
+You cannot link your Ada code with an object or library generated with
+Microsoft tools if these use the @code{.tls} section (Thread Local
+Storage section) since the GNAT linker does not yet support this section.
+
+@item
+You cannot link your Ada code with an object or library generated with
+Microsoft tools if these use I/O routines other than those provided in
+the Microsoft DLL: @code{msvcrt.dll}. This is because the GNAT run time
+uses the services of @code{msvcrt.dll} for its I/Os. Use of other I/O
+libraries can cause a conflict with @code{msvcrt.dll} services. For
+instance Visual C++ I/O stream routines conflict with those in
+@code{msvcrt.dll}.
+@end itemize
+
+@noindent
+If you do want to use the Microsoft tools for your non-Ada code and hit one
+of the above limitations, you have two choices:
+
+@enumerate
+@item
+Encapsulate your non Ada code in a DLL to be linked with your Ada
+application. In this case, use the Microsoft or whatever environment to
+build the DLL and use GNAT to build your executable
+(@pxref{Using DLLs with GNAT}).
+
+@item
+Or you can encapsulate your Ada code in a DLL to be linked with the
+other part of your application. In this case, use GNAT to build the DLL
+(@pxref{Building DLLs with GNAT}) and use the Microsoft or whatever
+environment to build your executable.
+@end enumerate
+
+@node Windows Calling Conventions
+@section Windows Calling Conventions
+@findex Stdcall
+@findex APIENTRY
+
+@menu
+* C Calling Convention::
+* Stdcall Calling Convention::
+* DLL Calling Convention::
+@end menu
+
+@noindent
+When a subprogram @code{F} (caller) calls a subprogram @code{G}
+(callee), there are several ways to push @code{G}'s parameters on the
+stack and there are several possible scenarios to clean up the stack
+upon @code{G}'s return. A calling convention is an agreed upon software
+protocol whereby the responsibilities between the caller (@code{F}) and
+the callee (@code{G}) are clearly defined. Several calling conventions
+are available for Windows:
+
+@itemize @bullet
+@item
+@code{C} (Microsoft defined)
+
+@item
+@code{Stdcall} (Microsoft defined)
+
+@item
+@code{DLL} (GNAT specific)
+@end itemize
+
+@node C Calling Convention
+@subsection @code{C} Calling Convention
+
+@noindent
+This is the default calling convention used when interfacing to C/C++
+routines compiled with either @code{gcc} or Microsoft Visual C++.
+
+In the @code{C} calling convention subprogram parameters are pushed on the
+stack by the caller from right to left. The caller itself is in charge of
+cleaning up the stack after the call. In addition, the name of a routine
+with @code{C} calling convention is mangled by adding a leading underscore.
+
+The name to use on the Ada side when importing (or exporting) a routine
+with @code{C} calling convention is the name of the routine. For
+instance the C function:
+
+@smallexample
+int get_val (long);
+@end smallexample
+
+@noindent
+should be imported from Ada as follows:
+
+@smallexample @c ada
+@group
+function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
+pragma Import (C, Get_Val, External_Name => "get_val");
+@end group
+@end smallexample
+
+@noindent
+Note that in this particular case the @code{External_Name} parameter could
+have been omitted since, when missing, this parameter is taken to be the
+name of the Ada entity in lower case. When the @code{Link_Name} parameter
+is missing, as in the above example, this parameter is set to be the
+@code{External_Name} with a leading underscore.
+
+When importing a variable defined in C, you should always use the @code{C}
+calling convention unless the object containing the variable is part of a
+DLL (in which case you should use the @code{DLL} calling convention,
+@pxref{DLL Calling Convention}).
+
+@node Stdcall Calling Convention
+@subsection @code{Stdcall} Calling Convention
+
+@noindent
+This convention, which was the calling convention used for Pascal
+programs, is used by Microsoft for all the routines in the Win32 API for
+efficiency reasons. It must be used to import any routine for which this
+convention was specified.
+
+In the @code{Stdcall} calling convention subprogram parameters are pushed
+on the stack by the caller from right to left. The callee (and not the
+caller) is in charge of cleaning the stack on routine exit. In addition,
+the name of a routine with @code{Stdcall} calling convention is mangled by
+adding a leading underscore (as for the @code{C} calling convention) and a
+trailing @code{@@}@code{@i{nn}}, where @i{nn} is the overall size (in
+bytes) of the parameters passed to the routine.
+
+The name to use on the Ada side when importing a C routine with a
+@code{Stdcall} calling convention is the name of the C routine. The leading
+underscore and trailing @code{@@}@code{@i{nn}} are added automatically by
+the compiler. For instance the Win32 function:
+
+@smallexample
+@b{APIENTRY} int get_val (long);
+@end smallexample
+
+@noindent
+should be imported from Ada as follows:
+
+@smallexample @c ada
+@group
+function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
+pragma Import (Stdcall, Get_Val);
+-- On the x86 a long is 4 bytes, so the Link_Name is "_get_val@@4"
+@end group
+@end smallexample
+
+@noindent
+As for the @code{C} calling convention, when the @code{External_Name}
+parameter is missing, it is taken to be the name of the Ada entity in lower
+case. If instead of writing the above import pragma you write:
+
+@smallexample @c ada
+@group
+function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
+pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val");
+@end group
+@end smallexample
+
+@noindent
+then the imported routine is @code{_retrieve_val@@4}. However, if instead
+of specifying the @code{External_Name} parameter you specify the
+@code{Link_Name} as in the following example:
+
+@smallexample @c ada
+@group
+function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
+pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val");
+@end group
+@end smallexample
+
+@noindent
+then the imported routine is @code{retrieve_val@@4}, that is, there is no
+trailing underscore but the appropriate @code{@@}@code{@i{nn}} is always
+added at the end of the @code{Link_Name} by the compiler.
+
+@noindent
+Note, that in some special cases a DLL's entry point name lacks a trailing
+@code{@@}@code{@i{nn}} while the exported name generated for a call has it.
+The @code{gnatdll} tool, which creates the import library for the DLL, is able
+to handle those cases (see the description of the switches in
+@pxref{Using gnatdll} section).
+
+@node DLL Calling Convention
+@subsection @code{DLL} Calling Convention
+
+@noindent
+This convention, which is GNAT-specific, must be used when you want to
+import in Ada a variables defined in a DLL. For functions and procedures
+this convention is equivalent to the @code{Stdcall} convention. As an
+example, if a DLL contains a variable defined as:
+
+@smallexample
+int my_var;
+@end smallexample
+
+@noindent
+then, to access this variable from Ada you should write:
+
+@smallexample @c ada
+@group
+My_Var : Interfaces.C.int;
+pragma Import (DLL, My_Var);
+@end group
+@end smallexample
+
+The remarks concerning the @code{External_Name} and @code{Link_Name}
+parameters given in the previous sections equally apply to the @code{DLL}
+calling convention.
+
+@node Introduction to Dynamic Link Libraries (DLLs)
+@section Introduction to Dynamic Link Libraries (DLLs)
+@findex DLL
+
+@noindent
+A Dynamically Linked Library (DLL) is a library that can be shared by
+several applications running under Windows. A DLL can contain any number of
+routines and variables.
+
+One advantage of DLLs is that you can change and enhance them without
+forcing all the applications that depend on them to be relinked or
+recompiled. However, you should be aware than all calls to DLL routines are
+slower since, as you will understand below, such calls are indirect.
+
+To illustrate the remainder of this section, suppose that an application
+wants to use the services of a DLL @file{API.dll}. To use the services
+provided by @file{API.dll} you must statically link against an import
+library which contains a jump table with an entry for each routine and
+variable exported by the DLL. In the Microsoft world this import library is
+called @file{API.lib}. When using GNAT this import library is called either
+@file{libAPI.a} or @file{libapi.a} (names are case insensitive).
+
+After you have statically linked your application with the import library
+and you run your application, here is what happens:
+
+@enumerate
+@item
+Your application is loaded into memory.
+
+@item
+The DLL @file{API.dll} is mapped into the address space of your
+application. This means that:
+
+@itemize @bullet
+@item
+The DLL will use the stack of the calling thread.
+
+@item
+The DLL will use the virtual address space of the calling process.
+
+@item
+The DLL will allocate memory from the virtual address space of the calling
+process.
+
+@item
+Handles (pointers) can be safely exchanged between routines in the DLL
+routines and routines in the application using the DLL.
+@end itemize
+
+@item
+The entries in the @file{libAPI.a} or @file{API.lib} jump table which is
+part of your application are initialized with the addresses of the routines
+and variables in @file{API.dll}.
+
+@item
+If present in @file{API.dll}, routines @code{DllMain} or
+@code{DllMainCRTStartup} are invoked. These routines typically contain
+the initialization code needed for the well-being of the routines and
+variables exported by the DLL.
+@end enumerate
+
+@noindent
+There is an additional point which is worth mentioning. In the Windows
+world there are two kind of DLLs: relocatable and non-relocatable
+DLLs. Non-relocatable DLLs can only be loaded at a very specific address
+in the target application address space. If the addresses of two
+non-relocatable DLLs overlap and these happen to be used by the same
+application, a conflict will occur and the application will run
+incorrectly. Hence, when possible, it is always preferable to use and
+build relocatable DLLs. Both relocatable and non-relocatable DLLs are
+supported by GNAT. Note that the @option{-s} linker option (see GNU Linker
+User's Guide) removes the debugging symbols from the DLL but the DLL can
+still be relocated.
+
+As a side note, an interesting difference between Microsoft DLLs and
+Unix shared libraries, is the fact that on most Unix systems all public
+routines are exported by default in a Unix shared library, while under
+Windows the exported routines must be listed explicitly in a definition
+file (@pxref{The Definition File}).
+
+@node Using DLLs with GNAT
+@section Using DLLs with GNAT
+
+@menu
+* Creating an Ada Spec for the DLL Services::
+* Creating an Import Library::
+@end menu
+
+@noindent
+To use the services of a DLL, say @file{API.dll}, in your Ada application
+you must have:
+
+@enumerate
+@item
+The Ada spec for the routines and/or variables you want to access in
+@file{API.dll}. If not available this Ada spec must be built from the C/C++
+header files provided with the DLL.
+
+@item
+The import library (@file{libAPI.a} or @file{API.lib}). As previously
+mentioned an import library is a statically linked library containing the
+import table which will be filled at load time to point to the actual
+@file{API.dll} routines. Sometimes you don't have an import library for the
+DLL you want to use. The following sections will explain how to build one.
+
+@item
+The actual DLL, @file{API.dll}.
+@end enumerate
+
+@noindent
+Once you have all the above, to compile an Ada application that uses the
+services of @file{API.dll} and whose main subprogram is @code{My_Ada_App},
+you simply issue the command
+
+@smallexample
+$ gnatmake my_ada_app -largs -lAPI
+@end smallexample
+
+@noindent
+The argument @option{-largs -lAPI} at the end of the @code{gnatmake} command
+tells the GNAT linker to look first for a library named @file{API.lib}
+(Microsoft-style name) and if not found for a library named @file{libAPI.a}
+(GNAT-style name). Note that if the Ada package spec for @file{API.dll}
+contains the following pragma
+
+@smallexample @c ada
+pragma Linker_Options ("-lAPI");
+@end smallexample
+
+@noindent
+you do not have to add @option{-largs -lAPI} at the end of the @code{gnatmake}
+command.
+
+If any one of the items above is missing you will have to create it
+yourself. The following sections explain how to do so using as an
+example a fictitious DLL called @file{API.dll}.
+
+@node Creating an Ada Spec for the DLL Services
+@subsection Creating an Ada Spec for the DLL Services
+
+@noindent
+A DLL typically comes with a C/C++ header file which provides the
+definitions of the routines and variables exported by the DLL. The Ada
+equivalent of this header file is a package spec that contains definitions
+for the imported entities. If the DLL you intend to use does not come with
+an Ada spec you have to generate one such spec yourself. For example if
+the header file of @file{API.dll} is a file @file{api.h} containing the
+following two definitions:
+
+@smallexample
+@group
+@cartouche
+int some_var;
+int get (char *);
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+then the equivalent Ada spec could be:
+
+@smallexample @c ada
+@group
+@cartouche
+with Interfaces.C.Strings;
+package API is
+ use Interfaces;
+
+ Some_Var : C.int;
+ function Get (Str : C.Strings.Chars_Ptr) return C.int;
+
+private
+ pragma Import (C, Get);
+ pragma Import (DLL, Some_Var);
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Note that a variable is @strong{always imported with a DLL convention}. A
+function can have @code{C}, @code{Stdcall} or @code{DLL} convention. For
+subprograms, the @code{DLL} convention is a synonym of @code{Stdcall}
+(@pxref{Windows Calling Conventions}).
+
+@node Creating an Import Library
+@subsection Creating an Import Library
+@cindex Import library
+
+@menu
+* The Definition File::
+* GNAT-Style Import Library::
+* Microsoft-Style Import Library::
+@end menu
+
+@noindent
+If a Microsoft-style import library @file{API.lib} or a GNAT-style
+import library @file{libAPI.a} is available with @file{API.dll} you
+can skip this section. Otherwise read on.
+
+@node The Definition File
+@subsubsection The Definition File
+@cindex Definition file
+@findex .def
+
+@noindent
+As previously mentioned, and unlike Unix systems, the list of symbols
+that are exported from a DLL must be provided explicitly in Windows.
+The main goal of a definition file is precisely that: list the symbols
+exported by a DLL. A definition file (usually a file with a @code{.def}
+suffix) has the following structure:
+
+@smallexample
+@group
+@cartouche
+[LIBRARY @i{name}]
+[DESCRIPTION @i{string}]
+EXPORTS
+ @i{symbol1}
+ @i{symbol2}
+ ...
+@end cartouche
+@end group
+@end smallexample
+
+@table @code
+@item LIBRARY @i{name}
+This section, which is optional, gives the name of the DLL.
+
+@item DESCRIPTION @i{string}
+This section, which is optional, gives a description string that will be
+embedded in the import library.
+
+@item EXPORTS
+This section gives the list of exported symbols (procedures, functions or
+variables). For instance in the case of @file{API.dll} the @code{EXPORTS}
+section of @file{API.def} looks like:
+
+@smallexample
+@group
+@cartouche
+EXPORTS
+ some_var
+ get
+@end cartouche
+@end group
+@end smallexample
+@end table
+
+@noindent
+Note that you must specify the correct suffix (@code{@@}@code{@i{nn}})
+(@pxref{Windows Calling Conventions}) for a Stdcall
+calling convention function in the exported symbols list.
+
+@noindent
+There can actually be other sections in a definition file, but these
+sections are not relevant to the discussion at hand.
+
+@node GNAT-Style Import Library
+@subsubsection GNAT-Style Import Library
+
+@noindent
+To create a static import library from @file{API.dll} with the GNAT tools
+you should proceed as follows:
+
+@enumerate
+@item
+Create the definition file @file{API.def} (@pxref{The Definition File}).
+For that use the @code{dll2def} tool as follows:
+
+@smallexample
+$ dll2def API.dll > API.def
+@end smallexample
+
+@noindent
+@code{dll2def} is a very simple tool: it takes as input a DLL and prints
+to standard output the list of entry points in the DLL. Note that if
+some routines in the DLL have the @code{Stdcall} convention
+(@pxref{Windows Calling Conventions}) with stripped @code{@@}@i{nn}
+suffix then you'll have to edit @file{api.def} to add it, and specify
+@code{-k} to @code{gnatdll} when creating the import library.
+
+@noindent
+Here are some hints to find the right @code{@@}@i{nn} suffix.
+
+@enumerate
+@item
+If you have the Microsoft import library (.lib), it is possible to get
+the right symbols by using Microsoft @code{dumpbin} tool (see the
+corresponding Microsoft documentation for further details).
+
+@smallexample
+$ dumpbin /exports api.lib
+@end smallexample
+
+@item
+If you have a message about a missing symbol at link time the compiler
+tells you what symbol is expected. You just have to go back to the
+definition file and add the right suffix.
+@end enumerate
+
+@item
+Build the import library @code{libAPI.a}, using @code{gnatdll}
+(@pxref{Using gnatdll}) as follows:
+
+@smallexample
+$ gnatdll -e API.def -d API.dll
+@end smallexample
+
+@noindent
+@code{gnatdll} takes as input a definition file @file{API.def} and the
+name of the DLL containing the services listed in the definition file
+@file{API.dll}. The name of the static import library generated is
+computed from the name of the definition file as follows: if the
+definition file name is @i{xyz}@code{.def}, the import library name will
+be @code{lib}@i{xyz}@code{.a}. Note that in the previous example option
+@option{-e} could have been removed because the name of the definition
+file (before the ``@code{.def}'' suffix) is the same as the name of the
+DLL (@pxref{Using gnatdll} for more information about @code{gnatdll}).
+@end enumerate
+
+@node Microsoft-Style Import Library
+@subsubsection Microsoft-Style Import Library
+
+@noindent
+With GNAT you can either use a GNAT-style or Microsoft-style import
+library. A Microsoft import library is needed only if you plan to make an
+Ada DLL available to applications developed with Microsoft
+tools (@pxref{Mixed-Language Programming on Windows}).
+
+To create a Microsoft-style import library for @file{API.dll} you
+should proceed as follows:
+
+@enumerate
+@item
+Create the definition file @file{API.def} from the DLL. For this use either
+the @code{dll2def} tool as described above or the Microsoft @code{dumpbin}
+tool (see the corresponding Microsoft documentation for further details).
+
+@item
+Build the actual import library using Microsoft's @code{lib} utility:
+
+@smallexample
+$ lib -machine:IX86 -def:API.def -out:API.lib
+@end smallexample
+
+@noindent
+If you use the above command the definition file @file{API.def} must
+contain a line giving the name of the DLL:
+
+@smallexample
+LIBRARY "API"
+@end smallexample
+
+@noindent
+See the Microsoft documentation for further details about the usage of
+@code{lib}.
+@end enumerate
+
+@node Building DLLs with GNAT
+@section Building DLLs with GNAT
+@cindex DLLs, building
+
+@menu
+* Limitations When Using Ada DLLs from Ada::
+* Exporting Ada Entities::
+* Ada DLLs and Elaboration::
+* Ada DLLs and Finalization::
+* Creating a Spec for Ada DLLs::
+* Creating the Definition File::
+* Using gnatdll::
+@end menu
+
+@noindent
+This section explains how to build DLLs containing Ada code. These DLLs
+will be referred to as Ada DLLs in the remainder of this section.
+
+The steps required to build an Ada DLL that is to be used by Ada as well as
+non-Ada applications are as follows:
+
+@enumerate
+@item
+You need to mark each Ada @i{entity} exported by the DLL with a @code{C} or
+@code{Stdcall} calling convention to avoid any Ada name mangling for the
+entities exported by the DLL (@pxref{Exporting Ada Entities}). You can
+skip this step if you plan to use the Ada DLL only from Ada applications.
+
+@item
+Your Ada code must export an initialization routine which calls the routine
+@code{adainit} generated by @code{gnatbind} to perform the elaboration of
+the Ada code in the DLL (@pxref{Ada DLLs and Elaboration}). The initialization
+routine exported by the Ada DLL must be invoked by the clients of the DLL
+to initialize the DLL.
+
+@item
+When useful, the DLL should also export a finalization routine which calls
+routine @code{adafinal} generated by @code{gnatbind} to perform the
+finalization of the Ada code in the DLL (@pxref{Ada DLLs and Finalization}).
+The finalization routine exported by the Ada DLL must be invoked by the
+clients of the DLL when the DLL services are no further needed.
+
+@item
+You must provide a spec for the services exported by the Ada DLL in each
+of the programming languages to which you plan to make the DLL available.
+
+@item
+You must provide a definition file listing the exported entities
+(@pxref{The Definition File}).
+
+@item
+Finally you must use @code{gnatdll} to produce the DLL and the import
+library (@pxref{Using gnatdll}).
+@end enumerate
+
+@noindent
+Note that a relocatable DLL stripped using the @code{strip} binutils
+tool will not be relocatable anymore. To build a DLL without debug
+information pass @code{-largs -s} to @code{gnatdll}.
+
+@node Limitations When Using Ada DLLs from Ada
+@subsection Limitations When Using Ada DLLs from Ada
+
+@noindent
+When using Ada DLLs from Ada applications there is a limitation users
+should be aware of. Because on Windows the GNAT run time is not in a DLL of
+its own, each Ada DLL includes a part of the GNAT run time. Specifically,
+each Ada DLL includes the services of the GNAT run time that are necessary
+to the Ada code inside the DLL. As a result, when an Ada program uses an
+Ada DLL there are two independent GNAT run times: one in the Ada DLL and
+one in the main program.
+
+It is therefore not possible to exchange GNAT run-time objects between the
+Ada DLL and the main Ada program. Example of GNAT run-time objects are file
+handles (e.g. @code{Text_IO.File_Type}), tasks types, protected objects
+types, etc.
+
+It is completely safe to exchange plain elementary, array or record types,
+Windows object handles, etc.
+
+@node Exporting Ada Entities
+@subsection Exporting Ada Entities
+@cindex Export table
+
+@noindent
+Building a DLL is a way to encapsulate a set of services usable from any
+application. As a result, the Ada entities exported by a DLL should be
+exported with the @code{C} or @code{Stdcall} calling conventions to avoid
+any Ada name mangling. Please note that the @code{Stdcall} convention
+should only be used for subprograms, not for variables. As an example here
+is an Ada package @code{API}, spec and body, exporting two procedures, a
+function, and a variable:
+
+@smallexample @c ada
+@group
+@cartouche
+with Interfaces.C; use Interfaces;
+package API is
+ Count : C.int := 0;
+ function Factorial (Val : C.int) return C.int;
+
+ procedure Initialize_API;
+ procedure Finalize_API;
+ -- Initialization & Finalization routines. More in the next section.
+private
+ pragma Export (C, Initialize_API);
+ pragma Export (C, Finalize_API);
+ pragma Export (C, Count);
+ pragma Export (C, Factorial);
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@smallexample @c ada
+@group
+@cartouche
+package body API is
+ function Factorial (Val : C.int) return C.int is
+ Fact : C.int := 1;
+ begin
+ Count := Count + 1;
+ for K in 1 .. Val loop
+ Fact := Fact * K;
+ end loop;
+ return Fact;
+ end Factorial;
+
+ procedure Initialize_API is
+ procedure Adainit;
+ pragma Import (C, Adainit);
+ begin
+ Adainit;
+ end Initialize_API;
+
+ procedure Finalize_API is
+ procedure Adafinal;
+ pragma Import (C, Adafinal);
+ begin
+ Adafinal;
+ end Finalize_API;
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+If the Ada DLL you are building will only be used by Ada applications
+you do not have to export Ada entities with a @code{C} or @code{Stdcall}
+convention. As an example, the previous package could be written as
+follows:
+
+@smallexample @c ada
+@group
+@cartouche
+package API is
+ Count : Integer := 0;
+ function Factorial (Val : Integer) return Integer;
+
+ procedure Initialize_API;
+ procedure Finalize_API;
+ -- Initialization and Finalization routines.
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@smallexample @c ada
+@group
+@cartouche
+package body API is
+ function Factorial (Val : Integer) return Integer is
+ Fact : Integer := 1;
+ begin
+ Count := Count + 1;
+ for K in 1 .. Val loop
+ Fact := Fact * K;
+ end loop;
+ return Fact;
+ end Factorial;
+
+ ...
+ -- The remainder of this package body is unchanged.
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+Note that if you do not export the Ada entities with a @code{C} or
+@code{Stdcall} convention you will have to provide the mangled Ada names
+in the definition file of the Ada DLL
+(@pxref{Creating the Definition File}).
+
+@node Ada DLLs and Elaboration
+@subsection Ada DLLs and Elaboration
+@cindex DLLs and elaboration
+
+@noindent
+The DLL that you are building contains your Ada code as well as all the
+routines in the Ada library that are needed by it. The first thing a
+user of your DLL must do is elaborate the Ada code
+(@pxref{Elaboration Order Handling in GNAT}).
+
+To achieve this you must export an initialization routine
+(@code{Initialize_API} in the previous example), which must be invoked
+before using any of the DLL services. This elaboration routine must call
+the Ada elaboration routine @code{adainit} generated by the GNAT binder
+(@pxref{Binding with Non-Ada Main Programs}). See the body of
+@code{Initialize_Api} for an example. Note that the GNAT binder is
+automatically invoked during the DLL build process by the @code{gnatdll}
+tool (@pxref{Using gnatdll}).
+
+When a DLL is loaded, Windows systematically invokes a routine called
+@code{DllMain}. It would therefore be possible to call @code{adainit}
+directly from @code{DllMain} without having to provide an explicit
+initialization routine. Unfortunately, it is not possible to call
+@code{adainit} from the @code{DllMain} if your program has library level
+tasks because access to the @code{DllMain} entry point is serialized by
+the system (that is, only a single thread can execute ``through'' it at a
+time), which means that the GNAT run time will deadlock waiting for the
+newly created task to complete its initialization.
+
+@node Ada DLLs and Finalization
+@subsection Ada DLLs and Finalization
+@cindex DLLs and finalization
+
+@noindent
+When the services of an Ada DLL are no longer needed, the client code should
+invoke the DLL finalization routine, if available. The DLL finalization
+routine is in charge of releasing all resources acquired by the DLL. In the
+case of the Ada code contained in the DLL, this is achieved by calling
+routine @code{adafinal} generated by the GNAT binder
+(@pxref{Binding with Non-Ada Main Programs}).
+See the body of @code{Finalize_Api} for an
+example. As already pointed out the GNAT binder is automatically invoked
+during the DLL build process by the @code{gnatdll} tool
+(@pxref{Using gnatdll}).
+
+@node Creating a Spec for Ada DLLs
+@subsection Creating a Spec for Ada DLLs
+
+@noindent
+To use the services exported by the Ada DLL from another programming
+language (e.g. C), you have to translate the specs of the exported Ada
+entities in that language. For instance in the case of @code{API.dll},
+the corresponding C header file could look like:
+
+@smallexample
+@group
+@cartouche
+extern int *_imp__count;
+#define count (*_imp__count)
+int factorial (int);
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+It is important to understand that when building an Ada DLL to be used by
+other Ada applications, you need two different specs for the packages
+contained in the DLL: one for building the DLL and the other for using
+the DLL. This is because the @code{DLL} calling convention is needed to
+use a variable defined in a DLL, but when building the DLL, the variable
+must have either the @code{Ada} or @code{C} calling convention. As an
+example consider a DLL comprising the following package @code{API}:
+
+@smallexample @c ada
+@group
+@cartouche
+package API is
+ Count : Integer := 0;
+ ...
+ -- Remainder of the package omitted.
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+After producing a DLL containing package @code{API}, the spec that
+must be used to import @code{API.Count} from Ada code outside of the
+DLL is:
+
+@smallexample @c ada
+@group
+@cartouche
+package API is
+ Count : Integer;
+ pragma Import (DLL, Count);
+end API;
+@end cartouche
+@end group
+@end smallexample
+
+@node Creating the Definition File
+@subsection Creating the Definition File
+
+@noindent
+The definition file is the last file needed to build the DLL. It lists
+the exported symbols. As an example, the definition file for a DLL
+containing only package @code{API} (where all the entities are exported
+with a @code{C} calling convention) is:
+
+@smallexample
+@group
+@cartouche
+EXPORTS
+ count
+ factorial
+ finalize_api
+ initialize_api
+@end cartouche
+@end group
+@end smallexample
+
+@noindent
+If the @code{C} calling convention is missing from package @code{API},
+then the definition file contains the mangled Ada names of the above
+entities, which in this case are:
+
+@smallexample
+@group
+@cartouche
+EXPORTS
+ api__count
+ api__factorial
+ api__finalize_api
+ api__initialize_api
+@end cartouche
+@end group
+@end smallexample
+
+@node Using gnatdll
+@subsection Using @code{gnatdll}
+@findex gnatdll
+
+@menu
+* gnatdll Example::
+* gnatdll behind the Scenes::
+* Using dlltool::
+@end menu
+
+@noindent
+@code{gnatdll} is a tool to automate the DLL build process once all the Ada
+and non-Ada sources that make up your DLL have been compiled.
+@code{gnatdll} is actually in charge of two distinct tasks: build the
+static import library for the DLL and the actual DLL. The form of the
+@code{gnatdll} command is
+
+@smallexample
+@cartouche
+$ gnatdll [@var{switches}] @var{list-of-files} [-largs @var{opts}]
+@end cartouche
+@end smallexample
+
+@noindent
+where @i{list-of-files} is a list of ALI and object files. The object
+file list must be the exact list of objects corresponding to the non-Ada
+sources whose services are to be included in the DLL. The ALI file list
+must be the exact list of ALI files for the corresponding Ada sources
+whose services are to be included in the DLL. If @i{list-of-files} is
+missing, only the static import library is generated.
+
+@noindent
+You may specify any of the following switches to @code{gnatdll}:
+
+@table @code
+@item -a[@var{address}]
+@cindex @option{-a} (@code{gnatdll})
+Build a non-relocatable DLL at @var{address}. If @var{address} is not
+specified the default address @var{0x11000000} will be used. By default,
+when this switch is missing, @code{gnatdll} builds relocatable DLL. We
+advise the reader to build relocatable DLL.
+
+@item -b @var{address}
+@cindex @option{-b} (@code{gnatdll})
+Set the relocatable DLL base address. By default the address is
+@var{0x11000000}.
+
+@item -bargs @var{opts}
+@cindex @option{-bargs} (@code{gnatdll})
+Binder options. Pass @var{opts} to the binder.
+
+@item -d @var{dllfile}
+@cindex @option{-d} (@code{gnatdll})
+@var{dllfile} is the name of the DLL. This switch must be present for
+@code{gnatdll} to do anything. The name of the generated import library is
+obtained algorithmically from @var{dllfile} as shown in the following
+example: if @var{dllfile} is @code{xyz.dll}, the import library name is
+@code{libxyz.a}. The name of the definition file to use (if not specified
+by option @option{-e}) is obtained algorithmically from @var{dllfile}
+as shown in the following example:
+if @var{dllfile} is @code{xyz.dll}, the definition
+file used is @code{xyz.def}.
+
+@item -e @var{deffile}
+@cindex @option{-e} (@code{gnatdll})
+@var{deffile} is the name of the definition file.
+
+@item -g
+@cindex @option{-g} (@code{gnatdll})
+Generate debugging information. This information is stored in the object
+file and copied from there to the final DLL file by the linker,
+where it can be read by the debugger. You must use the
+@option{-g} switch if you plan on using the debugger or the symbolic
+stack traceback.
+
+@item -h
+@cindex @option{-h} (@code{gnatdll})
+Help mode. Displays @code{gnatdll} switch usage information.
+
+@item -Idir
+@cindex @option{-I} (@code{gnatdll})
+Direct @code{gnatdll} to search the @var{dir} directory for source and
+object files needed to build the DLL.
+(@pxref{Search Paths and the Run-Time Library (RTL)}).
+
+@item -k
+@cindex @option{-k} (@code{gnatdll})
+Removes the @code{@@}@i{nn} suffix from the import library's exported
+names, but keeps them for the link names. You must specify this
+option if you want to use a @code{Stdcall} function in a DLL for which
+the @code{@@}@i{nn} suffix has been removed. This is the case for most
+of the Windows NT DLL for example. This option has no effect when
+@option{-n} option is specified.
+
+@item -l @var{file}
+@cindex @option{-l} (@code{gnatdll})
+The list of ALI and object files used to build the DLL are listed in
+@var{file}, instead of being given in the command line. Each line in
+@var{file} contains the name of an ALI or object file.
+
+@item -n
+@cindex @option{-n} (@code{gnatdll})
+No Import. Do not create the import library.
+
+@item -q
+@cindex @option{-q} (@code{gnatdll})
+Quiet mode. Do not display unnecessary messages.
+
+@item -v
+@cindex @option{-v} (@code{gnatdll})
+Verbose mode. Display extra information.
+
+@item -largs @var{opts}
+@cindex @option{-largs} (@code{gnatdll})
+Linker options. Pass @var{opts} to the linker.
+@end table
+
+@node gnatdll Example
+@subsubsection @code{gnatdll} Example
+
+@noindent
+As an example the command to build a relocatable DLL from @file{api.adb}
+once @file{api.adb} has been compiled and @file{api.def} created is
+
+@smallexample
+$ gnatdll -d api.dll api.ali
+@end smallexample
+
+@noindent
+The above command creates two files: @file{libapi.a} (the import
+library) and @file{api.dll} (the actual DLL). If you want to create
+only the DLL, just type:
+
+@smallexample
+$ gnatdll -d api.dll -n api.ali
+@end smallexample
+
+@noindent
+Alternatively if you want to create just the import library, type:
+
+@smallexample
+$ gnatdll -d api.dll
+@end smallexample
+
+@node gnatdll behind the Scenes
+@subsubsection @code{gnatdll} behind the Scenes
+
+@noindent
+This section details the steps involved in creating a DLL. @code{gnatdll}
+does these steps for you. Unless you are interested in understanding what
+goes on behind the scenes, you should skip this section.
+
+We use the previous example of a DLL containing the Ada package @code{API},
+to illustrate the steps necessary to build a DLL. The starting point is a
+set of objects that will make up the DLL and the corresponding ALI
+files. In the case of this example this means that @file{api.o} and
+@file{api.ali} are available. To build a relocatable DLL, @code{gnatdll} does
+the following:
+
+@enumerate
+@item
+@code{gnatdll} builds the base file (@file{api.base}). A base file gives
+the information necessary to generate relocation information for the
+DLL.
+
+@smallexample
+@group
+$ gnatbind -n api
+$ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base
+@end group
+@end smallexample
+
+@noindent
+In addition to the base file, the @code{gnatlink} command generates an
+output file @file{api.jnk} which can be discarded. The @option{-mdll} switch
+asks @code{gnatlink} to generate the routines @code{DllMain} and
+@code{DllMainCRTStartup} that are called by the Windows loader when the DLL
+is loaded into memory.
+
+@item
+@code{gnatdll} uses @code{dlltool} (@pxref{Using dlltool}) to build the
+export table (@file{api.exp}). The export table contains the relocation
+information in a form which can be used during the final link to ensure
+that the Windows loader is able to place the DLL anywhere in memory.
+
+@smallexample
+@group
+$ dlltool --dllname api.dll --def api.def --base-file api.base \
+ --output-exp api.exp
+@end group
+@end smallexample
+
+@item
+@code{gnatdll} builds the base file using the new export table. Note that
+@code{gnatbind} must be called once again since the binder generated file
+has been deleted during the previous call to @code{gnatlink}.
+
+@smallexample
+@group
+$ gnatbind -n api
+$ gnatlink api -o api.jnk api.exp -mdll
+ -Wl,--base-file,api.base
+@end group
+@end smallexample
+
+@item
+@code{gnatdll} builds the new export table using the new base file and
+generates the DLL import library @file{libAPI.a}.
+
+@smallexample
+@group
+$ dlltool --dllname api.dll --def api.def --base-file api.base \
+ --output-exp api.exp --output-lib libAPI.a
+@end group
+@end smallexample
+
+@item
+Finally @code{gnatdll} builds the relocatable DLL using the final export
+table.
+
+@smallexample
+@group
+$ gnatbind -n api
+$ gnatlink api api.exp -o api.dll -mdll
+@end group
+@end smallexample
+@end enumerate
+
+@node Using dlltool
+@subsubsection Using @code{dlltool}
+
+@noindent
+@code{dlltool} is the low-level tool used by @code{gnatdll} to build
+DLLs and static import libraries. This section summarizes the most
+common @code{dlltool} switches. The form of the @code{dlltool} command
+is
+
+@smallexample
+$ dlltool [@var{switches}]
+@end smallexample
+
+@noindent
+@code{dlltool} switches include:
+
+@table @option
+@item --base-file @var{basefile}
+@cindex @option{--base-file} (@command{dlltool})
+Read the base file @var{basefile} generated by the linker. This switch
+is used to create a relocatable DLL.
+
+@item --def @var{deffile}
+@cindex @option{--def} (@command{dlltool})
+Read the definition file.
+
+@item --dllname @var{name}
+@cindex @option{--dllname} (@command{dlltool})
+Gives the name of the DLL. This switch is used to embed the name of the
+DLL in the static import library generated by @code{dlltool} with switch
+@option{--output-lib}.
+
+@item -k
+@cindex @option{-k} (@command{dlltool})
+Kill @code{@@}@i{nn} from exported names
+(@pxref{Windows Calling Conventions}
+for a discussion about @code{Stdcall}-style symbols.
+
+@item --help
+@cindex @option{--help} (@command{dlltool})
+Prints the @code{dlltool} switches with a concise description.
+
+@item --output-exp @var{exportfile}
+@cindex @option{--output-exp} (@command{dlltool})
+Generate an export file @var{exportfile}. The export file contains the
+export table (list of symbols in the DLL) and is used to create the DLL.
+
+@item --output-lib @i{libfile}
+@cindex @option{--output-lib} (@command{dlltool})
+Generate a static import library @var{libfile}.
+
+@item -v
+@cindex @option{-v} (@command{dlltool})
+Verbose mode.
+
+@item --as @i{assembler-name}
+@cindex @option{--as} (@command{dlltool})
+Use @i{assembler-name} as the assembler. The default is @code{as}.
+@end table
+
+@node GNAT and Windows Resources
+@section GNAT and Windows Resources
+@cindex Resources, windows
+
+@menu
+* Building Resources::
+* Compiling Resources::
+* Using Resources::
+@end menu
+
+@noindent
+Resources are an easy way to add Windows specific objects to your
+application. The objects that can be added as resources include:
+
+@itemize @bullet
+@item
+menus
+
+@item
+accelerators
+
+@item
+dialog boxes
+
+@item
+string tables
+
+@item
+bitmaps
+
+@item
+cursors
+
+@item
+icons
+
+@item
+fonts
+@end itemize
+
+@noindent
+This section explains how to build, compile and use resources.
+
+@node Building Resources
+@subsection Building Resources
+@cindex Resources, building
+
+@noindent
+A resource file is an ASCII file. By convention resource files have an
+@file{.rc} extension.
+The easiest way to build a resource file is to use Microsoft tools
+such as @code{imagedit.exe} to build bitmaps, icons and cursors and
+@code{dlgedit.exe} to build dialogs.
+It is always possible to build an @file{.rc} file yourself by writing a
+resource script.
+
+It is not our objective to explain how to write a resource file. A
+complete description of the resource script language can be found in the
+Microsoft documentation.
+
+@node Compiling Resources
+@subsection Compiling Resources
+@findex rc
+@findex windres
+@cindex Resources, compiling
+
+@noindent
+This section describes how to build a GNAT-compatible (COFF) object file
+containing the resources. This is done using the Resource Compiler
+@code{windres} as follows:
+
+@smallexample
+$ windres -i myres.rc -o myres.o
+@end smallexample
+
+@noindent
+By default @code{windres} will run @code{gcc} to preprocess the @file{.rc}
+file. You can specify an alternate preprocessor (usually named
+@file{cpp.exe}) using the @code{windres} @option{--preprocessor}
+parameter. A list of all possible options may be obtained by entering
+the command @code{windres} @option{--help}.
+
+It is also possible to use the Microsoft resource compiler @code{rc.exe}
+to produce a @file{.res} file (binary resource file). See the
+corresponding Microsoft documentation for further details. In this case
+you need to use @code{windres} to translate the @file{.res} file to a
+GNAT-compatible object file as follows:
+
+@smallexample
+$ windres -i myres.res -o myres.o
+@end smallexample
+
+@node Using Resources
+@subsection Using Resources
+@cindex Resources, using
+
+@noindent
+To include the resource file in your program just add the
+GNAT-compatible object file for the resource(s) to the linker
+arguments. With @code{gnatmake} this is done by using the @option{-largs}
+option:
+
+@smallexample
+$ gnatmake myprog -largs myres.o
+@end smallexample
+
+@node Debugging a DLL
+@section Debugging a DLL
+@cindex DLL debugging
+
+@menu
+* Program and DLL Both Built with GCC/GNAT::
+* Program Built with Foreign Tools and DLL Built with GCC/GNAT::
+@end menu
+
+@noindent
+Debugging a DLL is similar to debugging a standard program. But
+we have to deal with two different executable parts: the DLL and the
+program that uses it. We have the following four possibilities:
+
+@enumerate 1
+@item
+The program and the DLL are built with @code{GCC/GNAT}.
+@item
+The program is built with foreign tools and the DLL is built with
+@code{GCC/GNAT}.
+@item
+The program is built with @code{GCC/GNAT} and the DLL is built with
+foreign tools.
+@item
+@end enumerate
+
+@noindent
+In this section we address only cases one and two above.
+There is no point in trying to debug
+a DLL with @code{GNU/GDB}, if there is no GDB-compatible debugging
+information in it. To do so you must use a debugger compatible with the
+tools suite used to build the DLL.
+
+@node Program and DLL Both Built with GCC/GNAT
+@subsection Program and DLL Both Built with GCC/GNAT
+
+@noindent
+This is the simplest case. Both the DLL and the program have @code{GDB}
+compatible debugging information. It is then possible to break anywhere in
+the process. Let's suppose here that the main procedure is named
+@code{ada_main} and that in the DLL there is an entry point named
+@code{ada_dll}.
+
+@noindent
+The DLL (@pxref{Introduction to Dynamic Link Libraries (DLLs)}) and
+program must have been built with the debugging information (see GNAT -g
+switch). Here are the step-by-step instructions for debugging it:
+
+@enumerate 1
+@item Launch @code{GDB} on the main program.
+
+@smallexample
+$ gdb -nw ada_main
+@end smallexample
+
+@item Break on the main procedure and run the program.
+
+@smallexample
+(gdb) break ada_main
+(gdb) run
+@end smallexample
+
+@noindent
+This step is required to be able to set a breakpoint inside the DLL. As long
+as the program is not run, the DLL is not loaded. This has the
+consequence that the DLL debugging information is also not loaded, so it is not
+possible to set a breakpoint in the DLL.
+
+@item Set a breakpoint inside the DLL
+
+@smallexample
+(gdb) break ada_dll
+(gdb) run
+@end smallexample
+
+@end enumerate
+
+@noindent
+At this stage a breakpoint is set inside the DLL. From there on
+you can use the standard approach to debug the whole program
+(@pxref{Running and Debugging Ada Programs}).
+
+@node Program Built with Foreign Tools and DLL Built with GCC/GNAT
+@subsection Program Built with Foreign Tools and DLL Built with GCC/GNAT
+
+@menu
+* Debugging the DLL Directly::
+* Attaching to a Running Process::
+@end menu
+
+@noindent
+In this case things are slightly more complex because it is not possible to
+start the main program and then break at the beginning to load the DLL and the
+associated DLL debugging information. It is not possible to break at the
+beginning of the program because there is no @code{GDB} debugging information,
+and therefore there is no direct way of getting initial control. This
+section addresses this issue by describing some methods that can be used
+to break somewhere in the DLL to debug it.
+
+@noindent
+First suppose that the main procedure is named @code{main} (this is for
+example some C code built with Microsoft Visual C) and that there is a
+DLL named @code{test.dll} containing an Ada entry point named
+@code{ada_dll}.
+
+@noindent
+The DLL (@pxref{Introduction to Dynamic Link Libraries (DLLs)}) must have
+been built with debugging information (see GNAT -g option).
+
+@node Debugging the DLL Directly
+@subsubsection Debugging the DLL Directly
+
+@enumerate 1
+@item
+Launch the debugger on the DLL.
+
+@smallexample
+$ gdb -nw test.dll
+@end smallexample
+
+@item Set a breakpoint on a DLL subroutine.
+
+@smallexample
+(gdb) break ada_dll
+@end smallexample
+
+@item
+Specify the executable file to @code{GDB}.
+
+@smallexample
+(gdb) exec-file main.exe
+@end smallexample
+
+@item
+Run the program.
+
+@smallexample
+(gdb) run
+@end smallexample
+
+@noindent
+This will run the program until it reaches the breakpoint that has been
+set. From that point you can use the standard way to debug a program
+as described in (@pxref{Running and Debugging Ada Programs}).
+
+@end enumerate
+
+@noindent
+It is also possible to debug the DLL by attaching to a running process.
+
+@node Attaching to a Running Process
+@subsubsection Attaching to a Running Process
+@cindex DLL debugging, attach to process
+
+@noindent
+With @code{GDB} it is always possible to debug a running process by
+attaching to it. It is possible to debug a DLL this way. The limitation
+of this approach is that the DLL must run long enough to perform the
+attach operation. It may be useful for instance to insert a time wasting
+loop in the code of the DLL to meet this criterion.
+
+@enumerate 1
+
+@item Launch the main program @file{main.exe}.
+
+@smallexample
+$ main
+@end smallexample
+
+@item Use the Windows @i{Task Manager} to find the process ID. Let's say
+that the process PID for @file{main.exe} is 208.
+
+@item Launch gdb.
+
+@smallexample
+$ gdb -nw
+@end smallexample
+
+@item Attach to the running process to be debugged.
+
+@smallexample
+(gdb) attach 208
+@end smallexample
+
+@item Load the process debugging information.
+
+@smallexample
+(gdb) symbol-file main.exe
+@end smallexample
+
+@item Break somewhere in the DLL.
+
+@smallexample
+(gdb) break ada_dll
+@end smallexample
+
+@item Continue process execution.
+
+@smallexample
+(gdb) continue
+@end smallexample
+
+@end enumerate
+
+@noindent
+This last step will resume the process execution, and stop at
+the breakpoint we have set. From there you can use the standard
+approach to debug a program as described in
+(@pxref{Running and Debugging Ada Programs}).
+
+@node GNAT and COM/DCOM Objects
+@section GNAT and COM/DCOM Objects
+@findex COM
+@findex DCOM
+
+@noindent
+This section is temporarily left blank.
+
+@end ifset
+
+
+@c **********************************
+@c * GNU Free Documentation License *
+@c **********************************
+@include fdl.texi
+@c GNU Free Documentation License
+
+@node Index,,GNU Free Documentation License, Top
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@c Put table of contents at end, otherwise it precedes the "title page" in
+@c the .txt version
+@c Edit the pdf file to move the contents to the beginning, after the title
+@c page
+
+@bye
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-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/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/makegpr.adb b/gcc/ada/makegpr.adb
new file mode 100644
index 00000000000..61f96f251ff
--- /dev/null
+++ b/gcc/ada/makegpr.adb
@@ -0,0 +1,4074 @@
+------------------------------------------------------------------------------
+-- --
+-- 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);
+ -- Null argument list representing case of no arguments
+
+ 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);
+ -- Pattern for 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
+ Project : Project_Id;
+ Id : Other_Source_Id;
+ Found : Boolean := False;
+ end record;
+ -- Used as Source_Indexes component to check if archive needs 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 Copyright notice and of 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 => "=");
+
+ package X_Switches is new Table.Table
+ (Table_Component_Type => String_Access,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 2,
+ Table_Increment => 100,
+ Table_Name => "Makegpr.X_Switches");
+ -- Table to store the -X switches to be passed to gnatmake
+
+ 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.
+
+ Need_To_Rebuild_Global_Archive : Boolean := False;
+
+ 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
+
+ Global_Archive_Exists : Boolean := False;
+ -- True if there is a non empty global archive, to prevent creation
+ -- of such archives.
+
+ 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 (Project : Project_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_Global_Archive;
+ -- Build the archive for the main project
+
+ procedure Build_Library (Project : Project_Id; Unconditionally : Boolean);
+ -- Build the library for a library project. If Unconditionally is
+ -- False, first check if the library is up to date, and build it only
+ -- if it is not.
+
+ procedure Check (Option : String);
+ -- Check that a switch coming from a project file is not the concatenation
+ -- of several valid switch, for example "-g -v". If it is, issue a warning.
+
+ procedure Check_Archive_Builder;
+ -- Check if the archive builder (ar) is there
+
+ 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);
+ -- Compile one non-Ada source
+
+ 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);
+ -- Create the archive dependency file for a library project
+
+ procedure Create_Global_Archive_Dependency_File (Name : String);
+ -- Create the archive depenency file for the main project
+
+ procedure Display_Command
+ (Name : String;
+ Path : String_Access;
+ CPATH : String_Access := null);
+ -- 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.
+
+ function Is_Included_In_Global_Archive
+ (Object_Name : Name_Id;
+ Project : Project_Id) return Boolean;
+ -- Return True if the object Object_Name is not overridden by a source
+ -- in a project extending project Project.
+
+ 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;
+ -- Remove characters ASCII.CR and ASCII.LF from a String
+
+ 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;
+
+ procedure Add_Archive_Path;
+ -- For a library project or the main project, add the archive
+ -- path to the arguments.
+
+ ----------------------
+ -- Add_Archive_Path --
+ ----------------------
+
+ procedure Add_Archive_Path is
+ Increment : Positive;
+ Prev_Last : Positive;
+
+ begin
+ 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
+ Increment := Name_Len + 1;
+ Prev_Last := Lib_Path.Last;
+ 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;
+
+ 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;
+
+ -- For a non-library project, the only archive needed
+ -- is the one for the main project, if there is one.
+
+ elsif Project = Main_Project and then Global_Archive_Exists then
+ Add_Argument
+ (Get_Name_String (Data.Object_Directory) &
+ Directory_Separator &
+ "lib" & Get_Name_String (Data.Name) &
+ '.' & Archive_Ext,
+ Verbose_Mode);
+ end if;
+ end Add_Archive_Path;
+
+ 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 Project = Main_Project
+ or else Data.Other_Sources_Present
+ then
+ Add_Archive_Path;
+ end if;
+ end if;
+ end if;
+ end Recursive_Add_Archives;
+
+ -- Start of processing for 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 (Project : Project_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) := (Project, 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
+ Get_Name_String (Element.Value);
+
+ if not Quiet_Output then
+
+ -- When not in quiet output (no -q), check that the switch
+ -- is not the concatenation of several valid switches,
+ -- such as "-g -v". If it is, issue a warning.
+
+ Check (Option => Name_Buffer (1 .. Name_Len));
+ end if;
+
+ Add_Argument (Name_Buffer (1 .. Name_Len), True);
+ end if;
+
+ Element_Id := Element.Next;
+ end loop;
+ end if;
+ end Add_Switches;
+
+ --------------------------
+ -- Build_Global_Archive --
+ --------------------------
+
+ procedure Build_Global_Archive is
+ Data : Project_Data := Projects.Table (Main_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 := Need_To_Rebuild_Global_Archive;
+ -- When True, archive will be rebuilt
+
+ File : Prj.Util.Text_File;
+
+ Object_Path : Name_Id;
+ Time_Stamp : Time_Stamp_Type;
+
+ Saved_Last_Argument : Natural;
+ First_Object : Natural;
+
+ Discard : Boolean;
+
+ begin
+ Check_Archive_Builder;
+
+ Change_Dir (Get_Name_String (Data.Object_Directory));
+
+ 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.
+
+ for Proj in 1 .. Projects.Last loop
+ Data := Projects.Table (Proj);
+
+ if not Data.Library then
+ Last_Source := 0;
+ Source_Id := Data.First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Add_Source_Id (Proj, Source_Id);
+ Source_Id := Other_Sources.Table (Source_Id).Next;
+ end loop;
+ end if;
+ 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 path of the object file
+
+ Object_Path := 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
+ Source_Id := Source_Indexes (S).Id;
+ Source := Other_Sources.Table (Source_Id);
+
+ if (not Source_Indexes (S).Found)
+ and then Source.Object_Path = Object_Path
+ then
+ -- We have found the object file: get the source
+ -- data, and mark it as found.
+
+ 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_Path));
+ Write_Line (" is not an object of any 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 characters, 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_Path));
+ Write_Str (" is incorrect in the archive");
+ Write_Line (" dependency file");
+ end if;
+
+ exit;
+ end if;
+ end loop;
+
+ Close (File);
+ end if;
+ end if;
+ end if;
+
+ if not Need_To_Rebuild then
+ if Verbose_Mode then
+ Write_Line (" -> up to date");
+ end if;
+
+ -- Archive needs to be rebuilt
+
+ else
+ -- If archive already exists, first delete it
+
+ -- Comment needed on why we discard result???
+
+ if Is_Regular_File (Archive_Name) then
+ Delete_File (Archive_Name, Discard);
+ end if;
+
+ Last_Argument := 0;
+
+ -- 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);
+
+ First_Object := Last_Argument;
+
+ -- Followed by all the object files of the non library projects
+
+ for Proj in 1 .. Projects.Last loop
+ Data := Projects.Table (Proj);
+
+ if not Data.Library then
+ Source_Id := Data.First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+
+ -- Only include object file name that have not been
+ -- overriden in extending projects.
+
+ if Is_Included_In_Global_Archive
+ (Source.Object_Name, Proj)
+ then
+ Add_Argument
+ (Get_Name_String (Source.Object_Path), Verbose_Mode);
+ end if;
+
+ Source_Id := Source.Next;
+ end loop;
+ end if;
+ end loop;
+
+ -- No need to create a global archive, if there is no object
+ -- file to put into.
+
+ Global_Archive_Exists := Last_Argument > First_Object;
+
+ if Global_Archive_Exists then
+ -- If the archive is built, then linking will need to occur
+ -- unconditionally.
+
+ Need_To_Relink := True;
+
+ -- Spawn the archive builder (ar)
+
+ Saved_Last_Argument := Last_Argument;
+
+ Last_Argument := First_Object + 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 the archive was built, run the archive indexer (ranlib)
+ -- if there is one.
+
+ 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_Global_Archive_Dependency_File (Archive_Dep_Name);
+
+ -- Building the archive failed, delete dependency file if one
+ -- exists.
+
+ else
+ 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 if;
+ end Build_Global_Archive;
+
+ -------------------
+ -- Build_Library --
+ -------------------
+
+ procedure Build_Library (Project : Project_Id; Unconditionally : Boolean) is
+ Data : constant Project_Data := Projects.Table (Project);
+ Source_Id : Other_Source_Id;
+ Source : Other_Source;
+
+ 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;
+
+ begin
+ Check_Archive_Builder;
+
+ -- 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 (Project, 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 library if necessary
+
+ if Need_To_Rebuild then
+
+ -- If a library is built, then linking will need to occur
+ -- unconditionally.
+
+ Need_To_Relink := True;
+
+ Last_Argument := 0;
+
+ -- 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_Version => "",
+ 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);
+
+ end if;
+ end Build_Library;
+
+ -----------
+ -- Check --
+ -----------
+
+ procedure Check (Option : String) is
+ First : Positive := Option'First;
+ Last : Natural;
+
+ begin
+ for Index in Option'First + 1 .. Option'Last - 1 loop
+ if Option (Index) = ' ' and then Option (Index + 1) = '-' then
+ Write_Str ("warning: switch """);
+ Write_Str (Option);
+ Write_Str (""" is suspicious; consider using ");
+
+ Last := First;
+ while Last <= Option'Last loop
+ if Option (Last) = ' ' then
+ if First /= Option'First then
+ Write_Str (", ");
+ end if;
+
+ Write_Char ('"');
+ Write_Str (Option (First .. Last - 1));
+ Write_Char ('"');
+
+ while Last <= Option'Last and then Option (Last) = ' ' loop
+ Last := Last + 1;
+ end loop;
+
+ First := Last;
+
+ else
+ if Last = Option'Last then
+ if First /= Option'First then
+ Write_Str (", ");
+ end if;
+
+ Write_Char ('"');
+ Write_Str (Option (First .. Last));
+ Write_Char ('"');
+ end if;
+
+ Last := Last + 1;
+ end if;
+ end loop;
+
+ Write_Line (" instead");
+ exit;
+ end if;
+ end loop;
+ end Check;
+
+ ---------------------------
+ -- Check_Archive_Builder --
+ ---------------------------
+
+ procedure Check_Archive_Builder is
+ 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;
+ end Check_Archive_Builder;
+
+ ------------------------------
+ -- 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 True if source was found in 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 object file does not exist, of course 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
+ -- 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), ": ");
+
+ -- First line must start with name of object file, followed by 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;
+ CPATH : String_Access := null;
+
+ begin
+ -- If the compiler is not known 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, first calling 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 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);
+
+ -- Set CPATH, if compiler is GCC
+
+ if Compiler_Is_Gcc (Source.Language) then
+ CPATH := Current_Include_Paths (Source.Language);
+ end if;
+
+ -- And invoke the compiler
+
+ Display_Command
+ (Name => Compiler_Names (Source.Language).all,
+ Path => Compiler_Paths (Source.Language),
+ CPATH => CPATH);
+
+ Spawn
+ (Compiler_Paths (Source.Language).all,
+ Arguments (1 .. Last_Argument),
+ Success);
+
+ -- Case of successful compilation
+
+ if Success then
+
+ -- 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;
+
+ -- Compilation failed
+
+ 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;
+
+ -- Compilation will occur in the object directory
+
+ Change_Dir (Get_Name_String (Data.Object_Directory));
+
+ if not Data.Other_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 Ada sources
+
+ 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);
+
+ -- Add the -X switches, if any
+
+ for Index in 1 .. X_Switches.Last loop
+ Add_Argument (X_Switches.Table (Index), True);
+ end loop;
+
+ -- 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 some switches to gnatmake
+
+ -- -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
+
+ -- Linking options
+
+ if Linker_Options.Last /= 0 then
+ Add_Argument (Dash_largs, True);
+ else
+ Add_Argument (Dash_largs, Verbose_Mode);
+ end if;
+
+ -- Add the archives
+
+ Add_Archives (For_Gnatmake => True);
+
+ -- If there are linking options from the command line,
+ -- transmit them to gnatmake.
+
+ for Arg in 1 .. Linker_Options.Last loop
+ Add_Argument (Linker_Options.Table (Arg), True);
+ end loop;
+ 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
+ -- Loop through project files
+
+ for Project in 1 .. Projects.Last loop
+ Local_Errors := False;
+ Data := Projects.Table (Project);
+
+ -- Nothing to do when no sources of language other than Ada
+
+ if (not Data.Virtual) and then Data.Other_Sources_Present 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;
+
+ 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 Need_To_Rebuild_Archive and then (not Data.Library) then
+ Need_To_Rebuild_Global_Archive := True;
+ end if;
+
+ -- If there was no compilation error, build/rebuild the archive
+ -- if necessary.
+
+ if not Local_Errors
+ and then Data.Library
+ and then not Data.Languages (Lang_Ada)
+ then
+ Build_Library (Project, Need_To_Rebuild_Archive);
+ 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 the file in Append mode, to avoid automatic insertion of
+ -- an end of line if file is empty.
+
+ Create (Dep_File, Append_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;
+
+ -------------------------------------------
+ -- Create_Global_Archive_Dependency_File --
+ -------------------------------------------
+
+ procedure Create_Global_Archive_Dependency_File (Name : String) is
+ Source_Id : Other_Source_Id;
+ Source : Other_Source;
+ Dep_File : Ada.Text_IO.File_Type;
+
+ use Ada.Text_IO;
+
+ begin
+ -- Create the file in Append mode, to avoid automatic insertion of
+ -- an end of line if file is empty.
+
+ Create (Dep_File, Append_File, Name);
+
+ -- Get all the object files of non-Ada sources in non-library projects
+
+ for Project in 1 .. Projects.Last loop
+ if not Projects.Table (Project).Library then
+ Source_Id := Projects.Table (Project).First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+
+ -- Put only those object files that are in the global archive
+
+ if Is_Included_In_Global_Archive
+ (Source.Object_Name, Project)
+ then
+ Put_Line (Dep_File, Get_Name_String (Source.Object_Path));
+ Put_Line (Dep_File, String (Source.Object_TS));
+ end if;
+
+ Source_Id := Source.Next;
+ end loop;
+ end if;
+ end loop;
+
+ Close (Dep_File);
+
+ exception
+ when others =>
+ if Is_Open (Dep_File) then
+ Close (Dep_File);
+ end if;
+ end Create_Global_Archive_Dependency_File;
+
+ ---------------------
+ -- Display_Command --
+ ---------------------
+
+ procedure Display_Command
+ (Name : String;
+ Path : String_Access;
+ CPATH : String_Access := null)
+ 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
+ if CPATH /= null then
+ Write_Str ("CPATH = ");
+ Write_Line (CPATH.all);
+ end if;
+
+ 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;
+
+ -- Start of processing for Get_Imported_Directories
+
+ 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 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 for library project,
+ -- 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
+ Build_Global_Archive;
+ 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
+ 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;
+
+ -- Make sure the -X switch table is empty
+
+ X_Switches.Set_Last (0);
+
+ -- Get the command line arguments
+
+ Scan_Args : for Next_Arg in 1 .. Argument_Count loop
+ Scan_Arg (Argument (Next_Arg));
+ 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;
+
+ -----------------------------------
+ -- Is_Included_In_Global_Archive --
+ -----------------------------------
+
+ function Is_Included_In_Global_Archive
+ (Object_Name : Name_Id;
+ Project : Project_Id) return Boolean
+ is
+ Data : Project_Data := Projects.Table (Project);
+ Source : Other_Source_Id;
+
+ begin
+ while Data.Extended_By /= No_Project loop
+ Data := Projects.Table (Data.Extended_By);
+ Source := Data.First_Other_Source;
+
+ while Source /= No_Other_Source loop
+ if Other_Sources.Table (Source).Object_Name = Object_Name then
+ return False;
+ else
+ Source := Other_Sources.Table (Source).Next;
+ end if;
+ end loop;
+ end loop;
+
+ return True;
+ end Is_Included_In_Global_Archive;
+
+ ----------------------
+ -- 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 Check_Time_Stamps (Exec_Time_Stamp : Time_Stamp_Type);
+ -- Check if there is an archive that is more recent than the executable
+ -- to decide if we need to relink.
+
+ procedure Choose_C_Plus_Plus_Link_Process;
+ -- If the C++ compiler is not g++, create the correct script to link
+
+ procedure Link_Foreign
+ (Main : String;
+ Main_Id : Name_Id;
+ Source : Other_Source);
+ -- Link a non-Ada main, when there is no Ada code
+
+ ---------------------------------------
+ -- 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;
+
+ -----------------------
+ -- Check_Time_Stamps --
+ -----------------------
+
+ procedure Check_Time_Stamps (Exec_Time_Stamp : Time_Stamp_Type) is
+ 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.Other_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 Check_Time_Stamps;
+
+ -------------------------------------
+ -- 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;
+
+ ------------------
+ -- Link_Foreign --
+ ------------------
+
+ procedure Link_Foreign
+ (Main : String;
+ Main_Id : Name_Id;
+ Source : Other_Source)
+ is
+ 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;
+
+ -- Otherwise, get the time stamps of each archive. If one of
+ -- them is found later than the executable, we need to relink.
+
+ else
+ Check_Time_Stamps (Exec_Time_Stamp);
+ 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 all the archives, in a correct order
+
+ Add_Archives (For_Gnatmake => False);
+
+ -- Add the switches specified in package Linker of
+ -- the main project.
+
+ Add_Switches
+ (Data => Data,
+ Proc => Linker,
+ Language => Source.Language,
+ File_Name => Main_Id);
+
+ -- 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;
+
+ -- 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 Link_Foreign;
+
+ -- Start of processing of Link_Executables
+
+ 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.Other_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 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
+ Link_Foreign (Main, Main_Id, Source);
+ 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 error message preceded by 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;
+
+ -- Otherwise just fail
+
+ else
+ 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
+ -- specified, 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 directly, 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;
+ Copyright;
+
+ 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
+
+ -- Record the -X switch, so that they can be passed to gnatmake,
+ -- if gnatmake is called.
+
+ X_Switches.Increment_Last;
+ X_Switches.Table (X_Switches.Last) := new String'(Arg);
+
+ 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/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/mlib-tgt-aix.adb b/gcc/ada/mlib-tgt-aix.adb
new file mode 100644
index 00000000000..fc5a954da56
--- /dev/null
+++ b/gcc/ada/mlib-tgt-aix.adb
@@ -0,0 +1,378 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Version);
+
+ 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;
+
+ -------------
+ -- 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..4198f22317c
--- /dev/null
+++ b/gcc/ada/mlib-tgt-hpux.adb
@@ -0,0 +1,356 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+
+ 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;
+
+ -------------
+ -- 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..6c8a2e0c2a6
--- /dev/null
+++ b/gcc/ada/mlib-tgt-irix.adb
@@ -0,0 +1,351 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+
+ 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;
+
+ -------------
+ -- 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..a4a0ce8617a
--- /dev/null
+++ b/gcc/ada/mlib-tgt-linux.adb
@@ -0,0 +1,353 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+
+ 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;
+
+ -------------
+ -- 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..77295cf5b17
--- /dev/null
+++ b/gcc/ada/mlib-tgt-mingw.adb
@@ -0,0 +1,285 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (Windows 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 Windows version of the body. Works only with GCC versions
+-- supporting the "-shared" option.
+
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+
+with MLib.Fil;
+with MLib.Utl;
+
+package body MLib.Tgt is
+
+ package Files renames MLib.Fil;
+ package Tools renames MLib.Utl;
+
+ ---------------------
+ -- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Auto_Init);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Lib_Version);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator &
+ Files.Ext_To (Lib_Filename, DLL_Ext);
+
+ -- Start of processing for Build_Dynamic_Library
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ Tools.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options => Options,
+ Driver_Name => Driver_Name);
+ end Build_Dynamic_Library;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "dll";
+ 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 = ".dll";
+ 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" &
+ MLib.Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ 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
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ 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..a307e85ae88
--- /dev/null
+++ b/gcc/ada/mlib-tgt-solaris.adb
@@ -0,0 +1,350 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+
+ 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;
+
+ -------------
+ -- 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..e40fe50e8d0
--- /dev/null
+++ b/gcc/ada/mlib-tgt-tru64.adb
@@ -0,0 +1,367 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+
+ 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;
+
+ -------------
+ -- 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-alpha.adb b/gcc/ada/mlib-tgt-vms-alpha.adb
new file mode 100644
index 00000000000..6f1f069eb40
--- /dev/null
+++ b/gcc/ada/mlib-tgt-vms-alpha.adb
@@ -0,0 +1,694 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (Alpha 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 Alpha 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+
+ 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");
+
+ when Restricted =>
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-R");
+ 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;
+
+ -------------
+ -- 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-vms-ia64.adb b/gcc/ada/mlib-tgt-vms-ia64.adb
new file mode 100644
index 00000000000..639ebca3f84
--- /dev/null
+++ b/gcc/ada/mlib-tgt-vms-ia64.adb
@@ -0,0 +1,727 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (Integrity VMS Version) --
+-- --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Integrity 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_Version : String := "";
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+
+ 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;
+
+ -- Option file must end with ".opt"
+
+ 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
+ Fail ("Options File """, Opt_File_Name, """ must end with .opt");
+ 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 &
+ ".type " & Init_Proc & "#, @function" &
+ ASCII.LF;
+ Second_Line : constant String :=
+ ASCII.HT &
+ ".global " & Init_Proc & "#" &
+ ASCII.LF;
+ Third_Line : constant String :=
+ ASCII.HT &
+ ".global LIB$INITIALIZE#" &
+ ASCII.LF;
+ Fourth_Line : constant String :=
+ ASCII.HT &
+ ".section LIB$INITIALIZE#,""a"",@progbits" &
+ ASCII.LF;
+ Fifth_Line : constant String :=
+ ASCII.HT &
+ "data4 @fptr(" & Init_Proc & "#)" &
+ ASCII.LF;
+
+ 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
+ Len := Write
+ (Macro_File, Third_Line (Third_Line'First)'Address,
+ Third_Line'Length);
+ OK := Len = Third_Line'Length;
+ end if;
+
+ if OK then
+ Len := Write
+ (Macro_File, Fourth_Line (Fourth_Line'First)'Address,
+ Fourth_Line'Length);
+ OK := Len = Fourth_Line'Length;
+ end if;
+
+ if OK then
+ Len := Write
+ (Macro_File, Fifth_Line (Fifth_Line'First)'Address,
+ Fifth_Line'Length);
+ OK := Len = Fifth_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");
+
+ when Restricted =>
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-R");
+ 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;
+
+ -------------
+ -- 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..6eaa882b924
--- /dev/null
+++ b/gcc/ada/mlib-tgt-vxworks.adb
@@ -0,0 +1,304 @@
+------------------------------------------------------------------------------
+-- --
+-- 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_Version : String := "";
+ 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_Version);
+ pragma Unreferenced (Auto_Init);
+
+ begin
+ null;
+ end Build_Dynamic_Library;
+
+ -------------
+ -- 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;
+
+ 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/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..7d66ad822c1
--- /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-vms_64.ads b/gcc/ada/s-auxdec-vms_64.ads
new file mode 100644
index 00000000000..111be333b94
--- /dev/null
+++ b/gcc/ada/s-auxdec-vms_64.ads
@@ -0,0 +1,592 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . A U X _ D E C --
+-- --
+-- S p e c --
+-- --
+-- 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 package contains definitions that are designed to be compatible
+-- with the extra definitions in package System for DEC Ada implementations.
+
+-- These definitions can be used directly by withing this package, or merged
+-- with System using pragma Extend_System (Aux_DEC)
+
+-- This is the IPF VMS 64 bit version.
+
+with Unchecked_Conversion;
+
+package System.Aux_DEC is
+pragma Elaborate_Body (Aux_DEC);
+
+ subtype Short_Address is Address
+ range -2 ** (32 - 1) .. +2 ** (32 - 1) - 1;
+ for Short_Address'Object_Size use 32;
+ -- This subtype allows addresses to be converted from 64 bits to 32 bits
+ -- with an appropriate range check. Note that since this is a subtype of
+ -- type System.Address, the same limitations apply to this subtype. Namely
+ -- there are no visible arithmetic operations, and integer literals are
+ -- not available.
+
+ Short_Memory_Size : constant := 2 ** 32;
+ -- Defined for convenience of porting.
+
+ type Integer_8 is range -2 ** (8 - 1) .. +2 ** (8 - 1) - 1;
+ for Integer_8'Size use 8;
+
+ type Integer_16 is range -2 ** (16 - 1) .. +2 ** (16 - 1) - 1;
+ for Integer_16'Size use 16;
+
+ type Integer_32 is range -2 ** (32 - 1) .. +2 ** (32 - 1) - 1;
+ for Integer_32'Size use 32;
+
+ type Integer_64 is range -2 ** (64 - 1) .. +2 ** (64 - 1) - 1;
+ for Integer_64'Size use 64;
+
+ type Largest_Integer is range Min_Int .. Max_Int;
+
+ type AST_Handler is limited private;
+
+ No_AST_Handler : constant AST_Handler;
+
+ type Type_Class is
+ (Type_Class_Enumeration,
+ Type_Class_Integer,
+ Type_Class_Fixed_Point,
+ Type_Class_Floating_Point,
+ Type_Class_Array,
+ Type_Class_Record,
+ Type_Class_Access,
+ Type_Class_Task, -- also in Ada 95 protected
+ Type_Class_Address);
+
+ function "not" (Left : Largest_Integer) return Largest_Integer;
+ function "and" (Left, Right : Largest_Integer) return Largest_Integer;
+ function "or" (Left, Right : Largest_Integer) return Largest_Integer;
+ function "xor" (Left, Right : Largest_Integer) return Largest_Integer;
+
+ Address_Zero : constant Address;
+ No_Addr : constant Address;
+ Address_Size : constant := Standard'Address_Size;
+
+ function "+" (Left : Address; Right : Integer) return Address;
+ function "+" (Left : Integer; Right : Address) return Address;
+ function "-" (Left : Address; Right : Address) return Integer;
+ function "-" (Left : Address; Right : Integer) return Address;
+
+ generic
+ type Target is private;
+ function Fetch_From_Address (A : Address) return Target;
+
+ generic
+ type Target is private;
+ procedure Assign_To_Address (A : Address; T : Target);
+
+ -- Floating point type declarations for VAX floating point data types
+
+ pragma Warnings (Off);
+
+ type F_Float is digits 6;
+ pragma Float_Representation (VAX_Float, F_Float);
+
+ type D_Float is digits 9;
+ pragma Float_Representation (Vax_Float, D_Float);
+
+ type G_Float is digits 15;
+ pragma Float_Representation (Vax_Float, G_Float);
+
+ -- Floating point type declarations for IEEE floating point data types
+
+ type IEEE_Single_Float is digits 6;
+ pragma Float_Representation (IEEE_Float, IEEE_Single_Float);
+
+ type IEEE_Double_Float is digits 15;
+ pragma Float_Representation (IEEE_Float, IEEE_Double_Float);
+
+ pragma Warnings (On);
+
+ Non_Ada_Error : exception;
+
+ -- Hardware-oriented types and functions
+
+ type Bit_Array is array (Integer range <>) of Boolean;
+ pragma Pack (Bit_Array);
+
+ subtype Bit_Array_8 is Bit_Array (0 .. 7);
+ subtype Bit_Array_16 is Bit_Array (0 .. 15);
+ subtype Bit_Array_32 is Bit_Array (0 .. 31);
+ subtype Bit_Array_64 is Bit_Array (0 .. 63);
+
+ type Unsigned_Byte is range 0 .. 255;
+ for Unsigned_Byte'Size use 8;
+
+ function "not" (Left : Unsigned_Byte) return Unsigned_Byte;
+ function "and" (Left, Right : Unsigned_Byte) return Unsigned_Byte;
+ function "or" (Left, Right : Unsigned_Byte) return Unsigned_Byte;
+ function "xor" (Left, Right : Unsigned_Byte) return Unsigned_Byte;
+
+ function To_Unsigned_Byte (X : Bit_Array_8) return Unsigned_Byte;
+ function To_Bit_Array_8 (X : Unsigned_Byte) return Bit_Array_8;
+
+ type Unsigned_Byte_Array is array (Integer range <>) of Unsigned_Byte;
+
+ type Unsigned_Word is range 0 .. 65535;
+ for Unsigned_Word'Size use 16;
+
+ function "not" (Left : Unsigned_Word) return Unsigned_Word;
+ function "and" (Left, Right : Unsigned_Word) return Unsigned_Word;
+ function "or" (Left, Right : Unsigned_Word) return Unsigned_Word;
+ function "xor" (Left, Right : Unsigned_Word) return Unsigned_Word;
+
+ function To_Unsigned_Word (X : Bit_Array_16) return Unsigned_Word;
+ function To_Bit_Array_16 (X : Unsigned_Word) return Bit_Array_16;
+
+ type Unsigned_Word_Array is array (Integer range <>) of Unsigned_Word;
+
+ type Unsigned_Longword is range -2_147_483_648 .. 2_147_483_647;
+ for Unsigned_Longword'Size use 32;
+
+ function "not" (Left : Unsigned_Longword) return Unsigned_Longword;
+ function "and" (Left, Right : Unsigned_Longword) return Unsigned_Longword;
+ function "or" (Left, Right : Unsigned_Longword) return Unsigned_Longword;
+ function "xor" (Left, Right : Unsigned_Longword) return Unsigned_Longword;
+
+ function To_Unsigned_Longword (X : Bit_Array_32) return Unsigned_Longword;
+ function To_Bit_Array_32 (X : Unsigned_Longword) return Bit_Array_32;
+
+ type Unsigned_Longword_Array is
+ array (Integer range <>) of Unsigned_Longword;
+
+ type Unsigned_32 is range 0 .. 4_294_967_295;
+ for Unsigned_32'Size use 32;
+
+ function "not" (Left : Unsigned_32) return Unsigned_32;
+ function "and" (Left, Right : Unsigned_32) return Unsigned_32;
+ function "or" (Left, Right : Unsigned_32) return Unsigned_32;
+ function "xor" (Left, Right : Unsigned_32) return Unsigned_32;
+
+ function To_Unsigned_32 (X : Bit_Array_32) return Unsigned_32;
+ function To_Bit_Array_32 (X : Unsigned_32) return Bit_Array_32;
+
+ type Unsigned_Quadword is record
+ L0 : Unsigned_Longword;
+ L1 : Unsigned_Longword;
+ end record;
+
+ for Unsigned_Quadword'Size use 64;
+ for Unsigned_Quadword'Alignment use
+ Integer'Min (8, Standard'Maximum_Alignment);
+
+ function "not" (Left : Unsigned_Quadword) return Unsigned_Quadword;
+ function "and" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword;
+ function "or" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword;
+ function "xor" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword;
+
+ function To_Unsigned_Quadword (X : Bit_Array_64) return Unsigned_Quadword;
+ function To_Bit_Array_64 (X : Unsigned_Quadword) return Bit_Array_64;
+
+ type Unsigned_Quadword_Array is
+ array (Integer range <>) of Unsigned_Quadword;
+
+ function To_Address (X : Integer) return Address;
+ pragma Pure_Function (To_Address);
+
+ function To_Address_Long (X : Unsigned_Longword) return Address;
+ pragma Pure_Function (To_Address_Long);
+
+ function To_Integer (X : Address) return Integer;
+
+ function To_Unsigned_Longword (X : Address) return Unsigned_Longword;
+ function To_Unsigned_Longword (X : AST_Handler) return Unsigned_Longword;
+
+ -- Conventional names for static subtypes of type UNSIGNED_LONGWORD
+
+ subtype Unsigned_1 is Unsigned_Longword range 0 .. 2** 1-1;
+ subtype Unsigned_2 is Unsigned_Longword range 0 .. 2** 2-1;
+ subtype Unsigned_3 is Unsigned_Longword range 0 .. 2** 3-1;
+ subtype Unsigned_4 is Unsigned_Longword range 0 .. 2** 4-1;
+ subtype Unsigned_5 is Unsigned_Longword range 0 .. 2** 5-1;
+ subtype Unsigned_6 is Unsigned_Longword range 0 .. 2** 6-1;
+ subtype Unsigned_7 is Unsigned_Longword range 0 .. 2** 7-1;
+ subtype Unsigned_8 is Unsigned_Longword range 0 .. 2** 8-1;
+ subtype Unsigned_9 is Unsigned_Longword range 0 .. 2** 9-1;
+ subtype Unsigned_10 is Unsigned_Longword range 0 .. 2**10-1;
+ subtype Unsigned_11 is Unsigned_Longword range 0 .. 2**11-1;
+ subtype Unsigned_12 is Unsigned_Longword range 0 .. 2**12-1;
+ subtype Unsigned_13 is Unsigned_Longword range 0 .. 2**13-1;
+ subtype Unsigned_14 is Unsigned_Longword range 0 .. 2**14-1;
+ subtype Unsigned_15 is Unsigned_Longword range 0 .. 2**15-1;
+ subtype Unsigned_16 is Unsigned_Longword range 0 .. 2**16-1;
+ subtype Unsigned_17 is Unsigned_Longword range 0 .. 2**17-1;
+ subtype Unsigned_18 is Unsigned_Longword range 0 .. 2**18-1;
+ subtype Unsigned_19 is Unsigned_Longword range 0 .. 2**19-1;
+ subtype Unsigned_20 is Unsigned_Longword range 0 .. 2**20-1;
+ subtype Unsigned_21 is Unsigned_Longword range 0 .. 2**21-1;
+ subtype Unsigned_22 is Unsigned_Longword range 0 .. 2**22-1;
+ subtype Unsigned_23 is Unsigned_Longword range 0 .. 2**23-1;
+ subtype Unsigned_24 is Unsigned_Longword range 0 .. 2**24-1;
+ subtype Unsigned_25 is Unsigned_Longword range 0 .. 2**25-1;
+ subtype Unsigned_26 is Unsigned_Longword range 0 .. 2**26-1;
+ subtype Unsigned_27 is Unsigned_Longword range 0 .. 2**27-1;
+ subtype Unsigned_28 is Unsigned_Longword range 0 .. 2**28-1;
+ subtype Unsigned_29 is Unsigned_Longword range 0 .. 2**29-1;
+ subtype Unsigned_30 is Unsigned_Longword range 0 .. 2**30-1;
+ subtype Unsigned_31 is Unsigned_Longword range 0 .. 2**31-1;
+
+ -- Function for obtaining global symbol values
+
+ function Import_Value (Symbol : String) return Unsigned_Longword;
+ function Import_Address (Symbol : String) return Address;
+ function Import_Largest_Value (Symbol : String) return Largest_Integer;
+
+ pragma Import (Intrinsic, Import_Value);
+ pragma Import (Intrinsic, Import_Address);
+ pragma Import (Intrinsic, Import_Largest_Value);
+
+ -- For the following declarations, note that the declaration without
+ -- a Retry_Count parameter means to retry infinitely. A value of zero
+ -- for the Retry_Count parameter means do not retry.
+
+ -- Interlocked-instruction procedures
+
+ procedure Clear_Interlocked
+ (Bit : in out Boolean;
+ Old_Value : out Boolean);
+
+ procedure Set_Interlocked
+ (Bit : in out Boolean;
+ Old_Value : out Boolean);
+
+ type Aligned_Word is record
+ Value : Short_Integer;
+ end record;
+
+ for Aligned_Word'Alignment use
+ Integer'Min (2, Standard'Maximum_Alignment);
+
+ procedure Clear_Interlocked
+ (Bit : in out Boolean;
+ Old_Value : out Boolean;
+ Retry_Count : in Natural;
+ Success_Flag : out Boolean);
+
+ procedure Set_Interlocked
+ (Bit : in out Boolean;
+ Old_Value : out Boolean;
+ Retry_Count : in Natural;
+ Success_Flag : out Boolean);
+
+ procedure Add_Interlocked
+ (Addend : in Short_Integer;
+ Augend : in out Aligned_Word;
+ Sign : out Integer);
+
+ type Aligned_Integer is record
+ Value : Integer;
+ end record;
+
+ for Aligned_Integer'Alignment use
+ Integer'Min (4, Standard'Maximum_Alignment);
+
+ type Aligned_Long_Integer is record
+ Value : Long_Integer;
+ end record;
+
+ for Aligned_Long_Integer'Alignment use
+ Integer'Min (8, Standard'Maximum_Alignment);
+
+ -- For the following declarations, note that the declaration without
+ -- a Retry_Count parameter mean to retry infinitely. A value of zero
+ -- for the Retry_Count means do not retry.
+
+ procedure Add_Atomic
+ (To : in out Aligned_Integer;
+ Amount : in Integer);
+
+ procedure Add_Atomic
+ (To : in out Aligned_Integer;
+ Amount : in Integer;
+ Retry_Count : in Natural;
+ Old_Value : out Integer;
+ Success_Flag : out Boolean);
+
+ procedure Add_Atomic
+ (To : in out Aligned_Long_Integer;
+ Amount : in Long_Integer);
+
+ procedure Add_Atomic
+ (To : in out Aligned_Long_Integer;
+ Amount : in Long_Integer;
+ Retry_Count : in Natural;
+ Old_Value : out Long_Integer;
+ Success_Flag : out Boolean);
+
+ procedure And_Atomic
+ (To : in out Aligned_Integer;
+ From : in Integer);
+
+ procedure And_Atomic
+ (To : in out Aligned_Integer;
+ From : in Integer;
+ Retry_Count : in Natural;
+ Old_Value : out Integer;
+ Success_Flag : out Boolean);
+
+ procedure And_Atomic
+ (To : in out Aligned_Long_Integer;
+ From : in Long_Integer);
+
+ procedure And_Atomic
+ (To : in out Aligned_Long_Integer;
+ From : in Long_Integer;
+ Retry_Count : in Natural;
+ Old_Value : out Long_Integer;
+ Success_Flag : out Boolean);
+
+ procedure Or_Atomic
+ (To : in out Aligned_Integer;
+ From : in Integer);
+
+ procedure Or_Atomic
+ (To : in out Aligned_Integer;
+ From : in Integer;
+ Retry_Count : in Natural;
+ Old_Value : out Integer;
+ Success_Flag : out Boolean);
+
+ procedure Or_Atomic
+ (To : in out Aligned_Long_Integer;
+ From : in Long_Integer);
+
+ procedure Or_Atomic
+ (To : in out Aligned_Long_Integer;
+ From : in Long_Integer;
+ Retry_Count : in Natural;
+ Old_Value : out Long_Integer;
+ Success_Flag : out Boolean);
+
+ type Insq_Status is
+ (Fail_No_Lock, OK_Not_First, OK_First);
+
+ for Insq_Status use
+ (Fail_No_Lock => -1,
+ OK_Not_First => 0,
+ OK_First => +1);
+
+ type Remq_Status is (
+ Fail_No_Lock,
+ Fail_Was_Empty,
+ OK_Not_Empty,
+ OK_Empty);
+
+ for Remq_Status use
+ (Fail_No_Lock => -1,
+ Fail_Was_Empty => 0,
+ OK_Not_Empty => +1,
+ OK_Empty => +2);
+
+ procedure Insqhi
+ (Item : in Address;
+ Header : in Address;
+ Status : out Insq_Status);
+
+ procedure Remqhi
+ (Header : in Address;
+ Item : out Address;
+ Status : out Remq_Status);
+
+ procedure Insqti
+ (Item : in Address;
+ Header : in Address;
+ Status : out Insq_Status);
+
+ procedure Remqti
+ (Header : in Address;
+ Item : out Address;
+ Status : out Remq_Status);
+
+private
+
+ Address_Zero : constant Address := Null_Address;
+ No_Addr : constant Address := Null_Address;
+
+ -- An AST_Handler value is from a typing point of view simply a pointer
+ -- to a procedure taking a single 64bit parameter. However, this
+ -- is a bit misleading, because the data that this pointer references is
+ -- highly stylized. See body of System.AST_Handling for full details.
+
+ type AST_Handler is access procedure (Param : Long_Integer);
+ No_AST_Handler : constant AST_Handler := null;
+
+ -- Other operators have incorrect profiles. It would be nice to make
+ -- them intrinsic, since the backend can handle them, but the front
+ -- end is not prepared to deal with them, so at least inline them.
+
+ pragma Inline_Always ("+");
+ pragma Inline_Always ("-");
+ pragma Inline_Always ("not");
+ pragma Inline_Always ("and");
+ pragma Inline_Always ("or");
+ pragma Inline_Always ("xor");
+
+ -- Other inlined subprograms
+
+ pragma Inline_Always (Fetch_From_Address);
+ pragma Inline_Always (Assign_To_Address);
+
+ -- Synchronization related subprograms. These are declared to have
+ -- convention C so that the critical parameters are passed by reference.
+ -- Without this, the parameters are passed by copy, creating load/store
+ -- race conditions. We also inline them, since this seems more in the
+ -- spirit of the original (hardware intrinsic) routines.
+
+ pragma Convention (C, Clear_Interlocked);
+ pragma Inline_Always (Clear_Interlocked);
+
+ pragma Convention (C, Set_Interlocked);
+ pragma Inline_Always (Set_Interlocked);
+
+ pragma Convention (C, Add_Interlocked);
+ pragma Inline_Always (Add_Interlocked);
+
+ pragma Convention (C, Add_Atomic);
+ pragma Inline_Always (Add_Atomic);
+
+ pragma Convention (C, And_Atomic);
+ pragma Inline_Always (And_Atomic);
+
+ pragma Convention (C, Or_Atomic);
+ pragma Inline_Always (Or_Atomic);
+
+ -- Provide proper unchecked conversion definitions for transfer
+ -- functions. Note that we need this level of indirection because
+ -- the formal parameter name is X and not Source (and this is indeed
+ -- detectable by a program)
+
+ function To_Unsigned_Byte_A is new
+ Unchecked_Conversion (Bit_Array_8, Unsigned_Byte);
+
+ function To_Unsigned_Byte (X : Bit_Array_8) return Unsigned_Byte
+ renames To_Unsigned_Byte_A;
+
+ function To_Bit_Array_8_A is new
+ Unchecked_Conversion (Unsigned_Byte, Bit_Array_8);
+
+ function To_Bit_Array_8 (X : Unsigned_Byte) return Bit_Array_8
+ renames To_Bit_Array_8_A;
+
+ function To_Unsigned_Word_A is new
+ Unchecked_Conversion (Bit_Array_16, Unsigned_Word);
+
+ function To_Unsigned_Word (X : Bit_Array_16) return Unsigned_Word
+ renames To_Unsigned_Word_A;
+
+ function To_Bit_Array_16_A is new
+ Unchecked_Conversion (Unsigned_Word, Bit_Array_16);
+
+ function To_Bit_Array_16 (X : Unsigned_Word) return Bit_Array_16
+ renames To_Bit_Array_16_A;
+
+ function To_Unsigned_Longword_A is new
+ Unchecked_Conversion (Bit_Array_32, Unsigned_Longword);
+
+ function To_Unsigned_Longword (X : Bit_Array_32) return Unsigned_Longword
+ renames To_Unsigned_Longword_A;
+
+ function To_Bit_Array_32_A is new
+ Unchecked_Conversion (Unsigned_Longword, Bit_Array_32);
+
+ function To_Bit_Array_32 (X : Unsigned_Longword) return Bit_Array_32
+ renames To_Bit_Array_32_A;
+
+ function To_Unsigned_32_A is new
+ Unchecked_Conversion (Bit_Array_32, Unsigned_32);
+
+ function To_Unsigned_32 (X : Bit_Array_32) return Unsigned_32
+ renames To_Unsigned_32_A;
+
+ function To_Bit_Array_32_A is new
+ Unchecked_Conversion (Unsigned_32, Bit_Array_32);
+
+ function To_Bit_Array_32 (X : Unsigned_32) return Bit_Array_32
+ renames To_Bit_Array_32_A;
+
+ function To_Unsigned_Quadword_A is new
+ Unchecked_Conversion (Bit_Array_64, Unsigned_Quadword);
+
+ function To_Unsigned_Quadword (X : Bit_Array_64) return Unsigned_Quadword
+ renames To_Unsigned_Quadword_A;
+
+ function To_Bit_Array_64_A is new
+ Unchecked_Conversion (Unsigned_Quadword, Bit_Array_64);
+
+ function To_Bit_Array_64 (X : Unsigned_Quadword) return Bit_Array_64
+ renames To_Bit_Array_64_A;
+
+ pragma Warnings (Off);
+ -- Turn warnings off. This is needed for systems with 64-bit integers,
+ -- where some of these operations are of dubious meaning, but we do not
+ -- want warnings when we compile on such systems.
+
+ function To_Address_A is new
+ Unchecked_Conversion (Integer, Address);
+ pragma Pure_Function (To_Address_A);
+
+ function To_Address (X : Integer) return Address
+ renames To_Address_A;
+ pragma Pure_Function (To_Address);
+
+ function To_Address_Long_A is new
+ Unchecked_Conversion (Unsigned_Longword, Address);
+ pragma Pure_Function (To_Address_Long_A);
+
+ function To_Address_Long (X : Unsigned_Longword) return Address
+ renames To_Address_Long_A;
+ pragma Pure_Function (To_Address_Long);
+
+ function To_Integer_A is new
+ Unchecked_Conversion (Address, Integer);
+
+ function To_Integer (X : Address) return Integer
+ renames To_Integer_A;
+
+ function To_Unsigned_Longword_A is new
+ Unchecked_Conversion (Address, Unsigned_Longword);
+
+ function To_Unsigned_Longword (X : Address) return Unsigned_Longword
+ renames To_Unsigned_Longword_A;
+
+ function To_Unsigned_Longword_A is new
+ Unchecked_Conversion (AST_Handler, Unsigned_Longword);
+
+ function To_Unsigned_Longword (X : AST_Handler) return Unsigned_Longword
+ renames To_Unsigned_Longword_A;
+
+ pragma Warnings (On);
+
+end System.Aux_DEC;
diff --git a/gcc/ada/s-crtl.ads b/gcc/ada/s-crtl.ads
new file mode 100644
index 00000000000..9fef16b4f24
--- /dev/null
+++ b/gcc/ada/s-crtl.ads
@@ -0,0 +1,159 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . C R T L --
+-- --
+-- S p e c --
+-- --
+-- 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 package provides the low level interface to the C Run Time Library
+-- on non-VMS systems.
+
+with System.Parameters;
+package System.CRTL is
+pragma Preelaborate (CRTL);
+
+ subtype chars is System.Address;
+ -- Pointer to null-terminated array of characters
+
+ subtype FILEs is System.Address;
+ -- Corresponds to the C type FILE*
+
+ subtype int is Integer;
+
+ type long is range -(2 ** (System.Parameters.long_bits - 1))
+ .. +(2 ** (System.Parameters.long_bits - 1)) - 1;
+
+ subtype off_t is Long_Integer;
+
+ type size_t is mod 2 ** Standard'Address_Size;
+
+ function atoi (A : System.Address) return Integer;
+ pragma Import (C, atoi, "atoi");
+
+ procedure clearerr (stream : FILEs);
+ pragma Import (C, clearerr, "clearerr");
+
+ function fclose (stream : FILEs) return int;
+ pragma Import (C, fclose, "fclose");
+
+ function fdopen (handle : int; mode : chars) return FILEs;
+ pragma Import (C, fdopen, "fdopen");
+
+ function fflush (stream : FILEs) return int;
+ pragma Import (C, fflush, "fflush");
+
+ function fgetc (stream : FILEs) return int;
+ pragma Import (C, fgetc, "fgetc");
+
+ function fgets (strng : chars; n : int; stream : FILEs) return chars;
+ pragma Import (C, fgets, "fgets");
+
+ function fopen (filename : chars; Mode : chars) return FILEs;
+ pragma Import (C, fopen, "fopen");
+
+ function fputc (C : int; stream : FILEs) return int;
+ pragma Import (C, fputc, "fputc");
+
+ function fputs (Strng : chars; Stream : FILEs) return int;
+ pragma Import (C, fputs, "fputs");
+
+ procedure free (Ptr : System.Address);
+ pragma Import (C, free, "free");
+
+ function freopen
+ (filename : chars;
+ mode : chars;
+ stream : FILEs)
+ return FILEs;
+ pragma Import (C, freopen, "freopen");
+
+ function fseek
+ (stream : FILEs;
+ offset : long;
+ origin : int)
+ return int;
+ pragma Import (C, fseek, "fseek");
+
+ function ftell (stream : FILEs) return long;
+ pragma Import (C, ftell, "ftell");
+
+ function getenv (S : String) return System.Address;
+ pragma Import (C, getenv, "getenv");
+
+ function isatty (handle : int) return int;
+ pragma Import (C, isatty, "isatty");
+
+ function lseek (fd : int; offset : off_t; direction : int) return off_t;
+ pragma Import (C, lseek, "lseek");
+
+ function malloc (Size : size_t) return System.Address;
+ pragma Import (C, malloc, "malloc");
+
+ procedure memcpy (S1 : System.Address; S2 : System.Address; N : size_t);
+ pragma Import (C, memcpy, "memcpy");
+
+ procedure memmove (S1 : System.Address; S2 : System.Address; N : size_t);
+ pragma Import (C, memmove, "memmove");
+
+ procedure mktemp (template : chars);
+ pragma Import (C, mktemp, "mktemp");
+
+ function read (fd : int; buffer : chars; nbytes : int) return int;
+ pragma Import (C, read, "read");
+
+ function realloc
+ (Ptr : System.Address; Size : size_t) return System.Address;
+ pragma Import (C, realloc, "realloc");
+
+ procedure rewind (stream : FILEs);
+ pragma Import (C, rewind, "rewind");
+
+ function setvbuf
+ (stream : FILEs;
+ buffer : chars;
+ mode : int;
+ size : size_t)
+ return int;
+ pragma Import (C, setvbuf, "setvbuf");
+
+ procedure tmpnam (string : chars);
+ pragma Import (C, tmpnam, "tmpnam");
+
+ function tmpfile return FILEs;
+ pragma Import (C, tmpfile, "tmpfile");
+
+ function ungetc (c : int; stream : FILEs) return int;
+ pragma Import (C, ungetc, "ungetc");
+
+ function unlink (filename : chars) return int;
+ pragma Import (C, unlink, "unlink");
+
+ function write (fd : int; buffer : chars; nbytes : int) return int;
+ pragma Import (C, write, "write");
+end System.CRTL;
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..044eac7d037
--- /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-interr-dummy.adb b/gcc/ada/s-interr-dummy.adb
new file mode 100644
index 00000000000..0702981ade3
--- /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-2004, 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..4a7610c8018
--- /dev/null
+++ b/gcc/ada/s-interr-sigaction.adb
@@ -0,0 +1,683 @@
+------------------------------------------------------------------------------
+-- --
+-- 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;
+
+ 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);
+
+ --------------------
+ -- Signal_Handler --
+ --------------------
+
+ 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
+
+ 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;
+ 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;
+
+ 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;
+ end Bind_Interrupt_To_Entry;
+
+ ------------------------------
+ -- Detach_Interrupt_Entries --
+ ------------------------------
+
+ procedure Detach_Interrupt_Entries (T : Task_Id) is
+ begin
+ for J in Interrupt_ID loop
+ if not Is_Reserved (J) then
+ if Descriptors (J).Kind = Task_Entry
+ and then Descriptors (J).T = T
+ then
+ Descriptors (J).Kind := Unknown;
+
+ if intr_attach (int (J), 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..3d4b7fc2e9d
--- /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..d0eee62dda3
--- /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..c6e8213c7ca
--- /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..000eb1c9ae5
--- /dev/null
+++ b/gcc/ada/s-osinte-freebsd.ads
@@ -0,0 +1,647 @@
+------------------------------------------------------------------------------
+-- --
+-- 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..ab0b0775e88
--- /dev/null
+++ b/gcc/ada/s-osinte-hpux-dce.adb
@@ -0,0 +1,530 @@
+------------------------------------------------------------------------------
+-- --
+-- 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-2004, 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 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..1aea8734223
--- /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..56c852614e8
--- /dev/null
+++ b/gcc/ada/s-osinte-irix.ads
@@ -0,0 +1,528 @@
+------------------------------------------------------------------------------
+-- --
+-- 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");
+
+ -------------------
+ -- SGI Additions --
+ -------------------
+
+ -- 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.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..7b9d640efb2
--- /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..8723f2db857
--- /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..d96a5ed4a54
--- /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..09ace65013a
--- /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");
+
+ ----------------------
+ -- Utility Routines --
+ ----------------------
+
+ function To_VxWorks_Priority (Priority : in int) return int;
+ pragma Inline (To_VxWorks_Priority);
+ -- Convenience routine to convert between VxWorks priority and Ada 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..9ee6648c6c9
--- /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-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 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-mingw.adb b/gcc/ada/s-parame-mingw.adb
new file mode 100644
index 00000000000..d77ebdbcca1
--- /dev/null
+++ b/gcc/ada/s-parame-mingw.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) 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 (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 20 * 1024;
+ end Default_Stack_Size;
+
+ ------------------------
+ -- Minimum_Stack_Size --
+ ------------------------
+
+ function Minimum_Stack_Size return Size_Type is
+ begin
+ return 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-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-restri.adb b/gcc/ada/s-restri.adb
new file mode 100644
index 00000000000..be39f231831
--- /dev/null
+++ b/gcc/ada/s-restri.adb
@@ -0,0 +1,148 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . R E S T R I C T I O N S --
+-- --
+-- 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. --
+-- --
+-- 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.Restrictions is
+ use Rident;
+
+ -------------------
+ -- Abort_Allowed --
+ -------------------
+
+ function Abort_Allowed return Boolean is
+ begin
+ return Run_Time_Restrictions.Violated (No_Abort_Statements)
+ or else
+ Run_Time_Restrictions.Violated (Max_Asynchronous_Select_Nesting);
+ end Abort_Allowed;
+
+ ---------------------
+ -- Tasking_Allowed --
+ ---------------------
+
+ function Tasking_Allowed return Boolean is
+ begin
+ return Run_Time_Restrictions.Violated (Max_Tasks)
+ or else
+ Run_Time_Restrictions.Violated (No_Tasking);
+ end Tasking_Allowed;
+
+-- Package elaboration code (acquire restrictions)
+
+begin
+ Acquire_Restrictions : declare
+
+ subtype Big_String is String (Positive);
+ type Big_String_Ptr is access all Big_String;
+
+ RString : Big_String_Ptr;
+ pragma Import (C, RString, "__gl_restrictions");
+
+ P : Natural := 1;
+ -- Pointer to scan string
+
+ C : Character;
+ -- Next character from string
+
+ function Get_Char return Character;
+ -- Get next character from string
+
+ function Get_Natural return Natural;
+ -- Scan out natural value known to be in range, updating P past it
+
+ --------------
+ -- Get_Char --
+ --------------
+
+ function Get_Char return Character is
+ begin
+ P := P + 1;
+ return RString (P - 1);
+ end Get_Char;
+
+ -----------------
+ -- Get_Natural --
+ -----------------
+
+ function Get_Natural return Natural is
+ N : Natural := 0;
+
+ begin
+ while RString (P) in '0' .. '9' loop
+ N := N * 10 + (Character'Pos (Get_Char) - Character'Pos ('0'));
+ end loop;
+
+ return N;
+ end Get_Natural;
+
+ -- Start of processing for Acquire_Restrictions
+
+ begin
+ -- Acquire data corresponding to first R line
+
+ for R in All_Boolean_Restrictions loop
+ C := Get_Char;
+
+ if C = 'v' then
+ Run_Time_Restrictions.Violated (R) := True;
+
+ elsif C = 'r' then
+ Run_Time_Restrictions.Set (R) := True;
+ end if;
+ end loop;
+
+ -- Acquire data corresponding to second R line
+
+ for RP in All_Parameter_Restrictions loop
+
+ -- Acquire restrictions pragma information
+
+ if Get_Char = 'r' then
+ Run_Time_Restrictions.Set (RP) := True;
+ Run_Time_Restrictions.Value (RP) := Get_Natural;
+ end if;
+
+ -- Acquire restrictions violations information
+
+ if Get_Char = 'v' then
+ Run_Time_Restrictions.Violated (RP) := True;
+ Run_Time_Restrictions.Count (RP) := Get_Natural;
+
+ if RString (P) = '+' then
+ Run_Time_Restrictions.Unknown (RP) := True;
+ P := P + 1;
+ end if;
+ end if;
+ end loop;
+ end Acquire_Restrictions;
+end System.Restrictions;
+
diff --git a/gcc/ada/s-restri.ads b/gcc/ada/s-restri.ads
new file mode 100644
index 00000000000..fc0e3e93776
--- /dev/null
+++ b/gcc/ada/s-restri.ads
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . R E S T R I C T I O N S --
+-- --
+-- 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. --
+-- --
+-- 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 run-time interface for checking the set of
+-- restrictions that applies to the current partition. The information
+-- comes both from explicit restriction pragmas present, and also from
+-- compile time checking.
+
+-- The package simply contains an instantiation of System.Rident, but
+-- with names discarded, so that we do not have image tables for the
+-- large restriction enumeration types at run time.
+
+with System.Rident;
+
+package System.Restrictions is
+ pragma Discard_Names;
+ package Rident is new System.Rident;
+
+ Run_Time_Restrictions : Rident.Restrictions_Info;
+
+ ------------------
+ -- Subprograms --
+ -----------------
+
+ function Abort_Allowed return Boolean;
+ pragma Inline (Abort_Allowed);
+ -- Tests to see if abort is allowed by the current restrictions settings.
+ -- For abort to be allowed, either No_Abort_Statements must be False,
+ -- or Max_Asynchronous_Select_Nesting must be non-zero.
+
+ function Tasking_Allowed return Boolean;
+ pragma Inline (Tasking_Allowed);
+ -- Tests to see if tasking operations are allowed by the current
+ -- restrictions settings. For taskikng to be allowed, No_Tasking
+ -- must be False, and Max_Tasks must not be set to zero.
+
+end System.Restrictions;
+
+
diff --git a/gcc/ada/s-stchop-vxworks.adb b/gcc/ada/s-stchop-vxworks.adb
new file mode 100644
index 00000000000..a5cb67a927b
--- /dev/null
+++ b/gcc/ada/s-stchop-vxworks.adb
@@ -0,0 +1,234 @@
+------------------------------------------------------------------------------
+-- --
+-- 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;
+ pragma Convention (C, Task_Descriptor);
+
+ -- 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;
+
+ -----------------
+ -- 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-stchop.adb b/gcc/ada/s-stchop.adb
new file mode 100644
index 00000000000..0759941d638
--- /dev/null
+++ b/gcc/ada/s-stchop.adb
@@ -0,0 +1,251 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 general implementation of this package. There is a VxWorks
+-- specific version of this package (5zstchop.adb). This file should
+-- be kept synchronized with it.
+
+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 System.CRTL;
+
+package body System.Stack_Checking.Operations is
+
+ Kilobyte : constant := 1024;
+
+ 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
+ type Frame_Mark is null record;
+ Frame_Location : Frame_Mark;
+ Frame_Address : constant Address := Frame_Location'Address;
+
+ My_Stack : Stack_Access;
+ Limit_Chars : System.Address;
+ Limit : Integer;
+
+ 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, initialize based on the assumption that
+ -- there are Environment_Stack_Size bytes available beyond
+ -- the current frame address.
+
+ if My_Stack.Size = 0 then
+ My_Stack.Size := Storage_Offset (Default_Env_Stack_Size);
+
+ -- When the environment variable GNAT_STACK_LIMIT is set,
+ -- set Environment_Stack_Size to that number of kB.
+
+ Limit_Chars := System.CRTL.getenv ("GNAT_STACK_LIMIT" & ASCII.NUL);
+
+ if Limit_Chars /= Null_Address then
+ Limit := System.CRTL.atoi (Limit_Chars);
+
+ if Limit >= 0 then
+ My_Stack.Size := Storage_Offset (Limit) * Kilobyte;
+ end if;
+ end if;
+ end if;
+
+ My_Stack.Base := Frame_Address;
+
+ if Stack_Grows_Down then
+
+ -- Prevent wrap-around on too big stack sizes
+
+ My_Stack.Limit := My_Stack.Base - My_Stack.Size;
+
+ if My_Stack.Limit > My_Stack.Base then
+ My_Stack.Limit := Address'First;
+ end if;
+
+ else
+ My_Stack.Limit := My_Stack.Base + My_Stack.Size;
+
+ -- Prevent wrap-around on too big stack sizes
+
+ if My_Stack.Limit < My_Stack.Base then
+ My_Stack.Limit := Address'Last;
+ end if;
+ end if;
+ 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;
+
+ -----------------
+ -- 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
+ (not (Frame_Address <= My_Stack.Base)))
+ or else
+ (not Stack_Grows_Down and then
+ (not (Frame_Address >= My_Stack.Base)))
+ then
+ -- The returned Base is lower than the stored one,
+ -- so assume that the original one wasn't right and use the
+ -- current Frame_Address as new one. This allows initializing
+ -- Base with the Frame_Address as approximation.
+ -- During initialization the Frame_Address will be close to
+ -- the stack base anyway: the difference should be compensated
+ -- for in the stack reserve.
+
+ My_Stack.Base := Frame_Address;
+ end if;
+
+ 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-stchop.ads b/gcc/ada/s-stchop.ads
new file mode 100644
index 00000000000..11738f63c0b
--- /dev/null
+++ b/gcc/ada/s-stchop.ads
@@ -0,0 +1,68 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 --
+-- --
+-- S p e c --
+-- --
+-- 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 package provides a implementation of stack checking operations
+-- using comparison with stack base and limit.
+
+pragma Restrictions (No_Elaboration_Code);
+-- We want to guarantee the absence of elaboration code because the
+-- binder does not handle references to this package.
+
+pragma Polling (Off);
+-- Turn off polling, we do not want polling to take place during stack
+-- checking operations. It causes infinite loops and other problems.
+
+package System.Stack_Checking.Operations is
+ procedure Update_Stack_Cache (Stack : Stack_Access);
+ -- Set the stack cache for the current task. Note that this is only
+ -- for optimization purposes, nothing can be assumed about the
+ -- contents of the cache at any time, see Set_Stack_Info.
+
+ procedure Invalidate_Stack_Cache (Any_Stack : Stack_Access);
+ -- Invalidate cache entries for the task T that owns Any_Stack.
+ -- This causes the Set_Stack_Info function to be called during
+ -- the next stack check done by T. This can be used to interrupt
+ -- task T asynchronously.
+ -- Stack_Check should be called in loops for this to work reliably.
+
+ function Stack_Check (Stack_Address : System.Address) return Stack_Access;
+ -- This version of Stack_Check should not be inlined.
+
+private
+
+ Cache : aliased Stack_Access := Null_Stack;
+
+ pragma Export (C, Cache, "_gnat_stack_cache");
+ pragma Export (C, Stack_Check, "_gnat_stack_check");
+
+end System.Stack_Checking.Operations;
diff --git a/gcc/ada/s-taprop-dummy.adb b/gcc/ada/s-taprop-dummy.adb
new file mode 100644
index 00000000000..c6d4ba07c7c
--- /dev/null
+++ b/gcc/ada/s-taprop-dummy.adb
@@ -0,0 +1,439 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 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
+
+ No_Tasking : Boolean;
+ -- Comment required here ???
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_Id) is
+ begin
+ null;
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ 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;
+
+ -----------------
+ -- 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;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_Id) is
+ begin
+ null;
+ end Enter_Task;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ null;
+ end Exit_Task;
+
+ -------------------
+ -- 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;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_Id) is
+ begin
+ null;
+ end Finalize_TCB;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_Id) return System.Any_Priority is
+ begin
+ return 0;
+ end Get_Priority;
+
+ --------------------
+ -- 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;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_Id) is
+ begin
+ null;
+ end Initialize;
+
+ ---------------------
+ -- 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;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_Id; Succeeded : out Boolean) is
+ begin
+ Succeeded := False;
+ end Initialize_TCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return False;
+ end Is_Valid_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ null;
+ end Lock_RTS;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ begin
+ return 0.0;
+ end Monotonic_Clock;
+
+ --------------
+ -- 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;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Ceiling_Violation := False;
+ end Read_Lock;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_Id is
+ begin
+ return null;
+ end Register_Foreign_Thread;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_Id;
+ Thread_Self : OSI.Thread_Id) return Boolean
+ is
+ begin
+ return False;
+ end Resume_Task;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_Id is
+ begin
+ return Null_Task;
+ end Self;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_Id;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ begin
+ null;
+ end Set_Priority;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep (Self_ID : Task_Id; Reason : System.Tasking.Task_States) is
+ begin
+ null;
+ end Sleep;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ procedure Stack_Guard (T : ST.Task_Id; On : Boolean) is
+ begin
+ null;
+ end Stack_Guard;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_Id;
+ Thread_Self : OSI.Thread_Id) return Boolean
+ is
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_Id;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ begin
+ null;
+ end Timed_Delay;
+
+ -----------------
+ -- 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;
+
+ ------------
+ -- 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;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ null;
+ end Unlock_RTS;
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_Id; Reason : System.Tasking.Task_States) is
+ begin
+ null;
+ end Wakeup;
+
+ ----------------
+ -- 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;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ begin
+ null;
+ end Yield;
+
+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..c5a13d03951
--- /dev/null
+++ b/gcc/ada/s-taprop-hpux-dce.adb
@@ -0,0 +1,1050 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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
+ -- The little window between deferring abort and locking Self_ID is the
+ -- only reason 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 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;
+
+ -- 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..78580ac5558
--- /dev/null
+++ b/gcc/ada/s-taprop-irix-athread.adb
@@ -0,0 +1,952 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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..21b330182d5
--- /dev/null
+++ b/gcc/ada/s-taprop-irix.adb
@@ -0,0 +1,1133 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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
+ -- The little window between deferring abort and locking Self_ID is
+ -- the only 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;
+ 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..e2aab2e2c0e
--- /dev/null
+++ b/gcc/ada/s-taprop-linux.adb
@@ -0,0 +1,1084 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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.
+
+ 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..ec50bae835b
--- /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.Stages.
+
+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..5656661f8ca
--- /dev/null
+++ b/gcc/ada/s-taprop-mingw.adb
@@ -0,0 +1,1091 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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;
+ Result : DWORD;
+ Entry_Point : PTHREAD_START_ROUTINE;
+
+ begin
+ pTaskParameter := To_Address (T);
+
+ Entry_Point := To_PTHREAD_START_ROUTINE (Wrapper);
+
+ hTask := CreateThread
+ (null,
+ DWORD (Adjust_Storage_Size (Stack_Size)),
+ 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..c53a05e122c
--- /dev/null
+++ b/gcc/ada/s-taprop-os2.adb
@@ -0,0 +1,1152 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 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.Stages.
+
+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..4d8057dc3d2
--- /dev/null
+++ b/gcc/ada/s-taprop-posix.adb
@@ -0,0 +1,1203 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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..69db09f7e47
--- /dev/null
+++ b/gcc/ada/s-taprop-solaris.adb
@@ -0,0 +1,1813 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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..d569831f87e
--- /dev/null
+++ b/gcc/ada/s-taprop-tru64.adb
@@ -0,0 +1,1130 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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..41612d49e30
--- /dev/null
+++ b/gcc/ada/s-taprop-vms.adb
@@ -0,0 +1,1000 @@
+------------------------------------------------------------------------------
+-- --
+-- 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.Stages.
+
+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..a3340a6f615
--- /dev/null
+++ b/gcc/ada/s-taprop-vxworks.adb
@@ -0,0 +1,1137 @@
+------------------------------------------------------------------------------
+-- --
+-- 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 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.Stages.
+
+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..5fa9a92e21d
--- /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..91bf83ea973
--- /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..7cac3b504d0
--- /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..6c3e74676d5
--- /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..eb0fabebd50
--- /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-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 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..965d1c9bfcb
--- /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..89938c45caa
--- /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-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. --
+-- --
+-- 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-alpha.adb b/gcc/ada/s-vaflop-vms-alpha.adb
new file mode 100644
index 00000000000..8b1bf031fa4
--- /dev/null
+++ b/gcc/ada/s-vaflop-vms-alpha.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/symbols-vms-alpha.adb b/gcc/ada/symbols-vms-alpha.adb
new file mode 100644
index 00000000000..2151706bc43
--- /dev/null
+++ b/gcc/ada/symbols-vms-alpha.adb
@@ -0,0 +1,774 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y M B O L S --
+-- --
+-- 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 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 Compliant or Controlled, attempt to read the reference
+ -- file. If policy is Restricted, attempt to read the symbol file.
+
+ if Sym_Policy /= Autonomous then
+ case Sym_Policy is
+ when Autonomous =>
+ null;
+
+ when Compliant | Controlled =>
+ begin
+ Open (File, In_File, Reference);
+
+ exception
+ when Ada.Text_IO.Name_Error =>
+ Success := False;
+ 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;
+
+ when Restricted =>
+ begin
+ Open (File, In_File, Symbol_File);
+
+ exception
+ when Ada.Text_IO.Name_Error =>
+ Success := False;
+ return;
+
+ when X : others =>
+ if not Quiet then
+ Put_Line ("could not open """ & Symbol_File & """");
+ Put_Line (Exception_Message (X));
+ end if;
+
+ Success := False;
+ return;
+ end;
+ end case;
+
+ -- 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 or else Sym_Policy = Restricted 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;
+
+ if Sym_Policy /= Restricted then
+
+ -- 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 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);
+ end if;
+
+ 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-ia64.ads b/gcc/ada/system-linux-ia64.ads
new file mode 100644
index 00000000000..72c51b0df52
--- /dev/null
+++ b/gcc/ada/system-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/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-vms_64.ads b/gcc/ada/system-vms_64.ads
new file mode 100644
index 00000000000..9052e2b16bb
--- /dev/null
+++ b/gcc/ada/system-vms_64.ads
@@ -0,0 +1,255 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (OpenVMS 64bit GCC_ZCX DEC Threads Version) --
+-- --
+-- 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 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 new Long_Integer;
+ Null_Address : constant Address;
+ -- Although this is declared as an integer type, no arithmetic operations
+ -- are available (see abstract declarations below), and furthermore there
+ -- is special processing in the compiler that prevents the use of integer
+ -- literals with this type (use To_Address to convert integer literals).
+ --
+ -- Conversion to and from Short_Address is however freely permitted, and
+ -- is indeed the reason that Address is declared as an integer type. See
+ --
+
+ 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, "=");
+
+ -- 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);
+ 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
+
+ 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-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/xgnatugn.adb b/gcc/ada/xgnatugn.adb
new file mode 100644
index 00000000000..5a992f4e8ed
--- /dev/null
+++ b/gcc/ada/xgnatugn.adb
@@ -0,0 +1,1380 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT SYSTEM UTILITIES --
+-- --
+-- X G N A T U G N --
+-- --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- This utility is used to process the source of gnat_ugn.texi to make a
+-- version suitable for running through standard Texinfo processor. It is
+-- invoked as follows:
+
+-- xgnatugn <target> <in-file> <word-list> [ <out-file> [ <warnings> ] ]
+
+-- 1. <target> is the target type of the manual, which is one of:
+
+-- unw Unix and Windows platforms
+-- vms OpenVMS
+
+-- 2. <in-file> is the file name of the Texinfo file to be
+-- preprocessed.
+
+-- 3. <word-list> is the name of the word list file. This file is used for
+-- rewriting the VMS edition. Each line contains a word mapping: The source
+-- word in the first column, the target word in the second column. The
+-- columns are separated by a '^' character. When preprocessing for VMS, the
+-- first word is replaced with the second. (Words consist of letters,
+-- digits, and the four characters "?-_~". A sequence of multiple words can
+-- be replaced if they are listed in the first column, separated by a single
+-- space character. If multiple words are to be replaced, there must be a
+-- replacement for each prefix.)
+
+-- 4. <out-file> (optional) is the name of the output file. It defaults to
+-- gnat_ugn_unw.texi or gnat_ugn_vms.texi, depending on the target.
+
+-- 5. <warnings> (optional, and allowed only if <out-file> is explicit)
+-- can be any string. If present, it indicates that warning messages are
+-- to be output to Standard_Error. If absent, no warning messages are
+-- generated.
+
+-- The following steps are performed:
+
+-- In VMS mode
+
+-- Any occurrences of ^alpha^beta^ are replaced by beta. The sequence
+-- must fit on a single line, and there can only be one occurrence on a
+-- line.
+
+-- Any occurrences of a word in the Ug_Words list are replaced by the
+-- appropriate vms equivalents. Note that replacements do not occur
+-- within ^alpha^beta^ sequences.
+
+-- Any occurence of [filename].extension, where extension one of the
+-- following:
+
+-- "o", "ads", "adb", "ali", "ada", "atb", "ats", "adc", "c"
+
+-- replaced by the appropriate VMS names (all upper case with .o
+-- replaced .OBJ). Note that replacements do not occur within
+-- ^alpha^beta^ sequences.
+
+-- In UNW mode
+
+-- Any occurrences of ^alpha^beta^ are replaced by alpha. The sequence
+-- must fit on a single line.
+
+-- In both modes
+
+-- The sequence ^^^ is replaced by a single ^. This escape sequence
+-- must be used if the literal character ^ is to appear in the
+-- output. A line containing this escape sequence may not also contain
+-- a ^alpha^beta^ sequence.
+
+-- Recognize @ifset and @ifclear (this is because we have menu problems
+-- if we let makeinfo handle the ifset/ifclear pairs
+
+with Ada.Command_Line; use Ada.Command_Line;
+with Ada.Strings; use Ada.Strings;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
+with Ada.Strings.Maps; use Ada.Strings.Maps;
+with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants;
+with Ada.Text_IO; use Ada.Text_IO;
+
+with GNAT.Spitbol; use GNAT.Spitbol;
+with GNAT.Spitbol.Table_VString; use GNAT.Spitbol.Table_VString;
+
+procedure Xgnatugn is
+
+ procedure Usage;
+ -- Print usage information. Invoked if an invalid command line is
+ -- encountered.
+
+ Output_File : File_Type;
+ -- The preprocessed output is written to this file
+
+ type Input_File is record
+ Name : VString;
+ Data : File_Type;
+ Line : Natural := 0;
+ end record;
+ -- Records information on an input file. Name and Line are used
+ -- in error messages, Line is updated automatically by Get_Line.
+
+ function Get_Line (Input : access Input_File) return String;
+ -- Returns a line from Input and performs the necessary
+ -- line-oriented checks (length, character set, trailing spaces).
+
+ Number_Of_Warnings : Natural := 0;
+ Number_Of_Errors : Natural := 0;
+ Warnings_Enabled : Boolean;
+
+ procedure Error
+ (Input : Input_File;
+ At_Character : Natural;
+ Message : String);
+ procedure Error
+ (Input : Input_File;
+ Message : String);
+ -- Prints a message reporting an error on line Input.Line. If
+ -- At_Character is not 0, indicate the exact character at which
+ -- the error occurs.
+
+ procedure Warning
+ (Input : Input_File;
+ At_Character : Natural;
+ Message : String);
+ procedure Warning
+ (Input : Input_File;
+ Message : String);
+ -- Like Error, but just print a warning message.
+
+ Dictionary_File : aliased Input_File;
+ procedure Read_Dictionary_File;
+ -- Dictionary_File is opened using the name given on the command
+ -- line. It contains the replacements for the Ug_Words list.
+ -- Read_Dictionary_File reads Dictionary_File and fills the
+ -- Ug_Words table.
+
+ Source_File : aliased Input_File;
+ procedure Process_Source_File;
+ -- Source_File is opened using the name given on the command line.
+ -- It contains the Texinfo source code. Process_Source_File
+ -- performs the necessary replacements.
+
+ type Target_Type is (UNW, VMS);
+ Target : Target_Type;
+ -- The target for which preprocessing is performed:
+ -- UNW (Unix and Windows) or VMS
+ -- The Target variable is initialized using the command line.
+
+ Valid_Characters : constant Character_Set
+ := To_Set (Span => (' ', '~'));
+ -- This array controls which characters are permitted in the input
+ -- file (after line breaks have been removed). Valid characters
+ -- are all printable ASCII characters and the space character.
+
+ Word_Characters : constant Character_Set :=
+ (To_Set (Ranges =>
+ (('0', '9'), ('a', 'z'), ('A', 'Z')))
+ or To_Set ("?-_~"));
+ -- The characters which are permitted in words. Other (valid)
+ -- characters are assumed to be delimiters between words. Note that
+ -- this set has to include all characters of the source words of the
+ -- Ug_Words dictionary.
+
+ Reject_Trailing_Spaces : constant Boolean := True;
+ -- Controls whether Xgnatug rejects superfluous space characters
+ -- at the end of lines.
+
+ Maximum_Line_Length : constant Positive := 79;
+ Fatal_Line_Length_Limit : constant Positive := 5000;
+ Fatal_Line_Length : exception;
+ -- If Maximum_Line_Length is exceeded in an input file, an error
+ -- message is printed. If Fatal_Line_Length is exceeded,
+ -- execution terminates with a Fatal_Line_Length exception.
+
+ VMS_Escape_Character : constant Character := '^';
+ -- The character used to mark VMS alternatives (^alpha^beta^).
+
+ Extensions : GNAT.Spitbol.Table_VString.Table (20);
+ procedure Initialize_Extensions;
+ -- This table records extensions and their replacement for
+ -- rewriting filenames in the VMS version of the manual.
+
+ function Is_Extension (Extension : String) return Boolean;
+ function Get_Replacement_Extension (Extension : String) return String;
+ -- These functions query the replacement table. Is_Extension
+ -- checks if the given string is a known extension.
+ -- Get_Replacement returns the replacement extension.
+
+ Ug_Words : GNAT.Spitbol.Table_VString.Table (200);
+ function Is_Known_Word (Word : String) return Boolean;
+ function Get_Replacement_Word (Word : String) return String;
+ -- The Ug_Words table lists replacement words for the VMS version
+ -- of the manual. Is_Known_Word and Get_Replacement_Word query
+ -- this table. The table is filled using Read_Dictionary_File.
+
+ function Rewrite_Source_Line (Line : String) return String;
+ -- This subprogram takes a line and rewrites it according to Target.
+ -- It relies on information in Source_File to generate error messages.
+
+ type Conditional is (Set, Clear);
+ procedure Push_Conditional (Cond : Conditional; Flag : Target_Type);
+ procedure Pop_Conditional (Cond : Conditional);
+ -- These subprograms deal with conditional processing (@ifset/@ifclear).
+ -- They rely on information in Source_File to generate error messages.
+
+ function Currently_Excluding return Boolean;
+ -- Returns true if conditional processing directives imply that the
+ -- current line should not be included in the output.
+
+ function VMS_Context_Determined return Boolean;
+ -- Returns true if, in the current conditional preprocessing context, we
+ -- always have a VMS or a non-VMS version, regardless of the value of
+ -- Target.
+
+ function In_VMS_Section return Boolean;
+ -- Returns True if in an "@ifset vms" section.
+
+ procedure Check_No_Pending_Conditional;
+ -- Checks that all preprocessing directives have been properly matched by
+ -- their @end counterpart. If this is not the case, print an error
+ -- message.
+
+ -- The following definitions implement a stack to track the conditional
+ -- preprocessing context.
+
+ type Conditional_Context is record
+ Starting_Line : Positive;
+ Cond : Conditional;
+ Flag : Target_Type;
+ Excluding : Boolean;
+ end record;
+
+ Conditional_Stack_Depth : constant := 3;
+
+ Conditional_Stack :
+ array (1 .. Conditional_Stack_Depth) of Conditional_Context;
+
+ Conditional_TOS : Natural := 0;
+ -- Pointer to the Top Of Stack for Conditional_Stack.
+
+ -----------
+ -- Usage --
+ -----------
+
+ procedure Usage is
+ begin
+ Put_Line (Standard_Error,
+ "usage: xgnatug TARGET SOURCE DICTIONARY [OUTFILE [WARNINGS]]");
+ New_Line;
+ Put_Line (Standard_Error, "TARGET is one of:");
+
+ for T in Target_Type'Range loop
+ Put_Line (Standard_Error, " " & Target_Type'Image (T));
+ end loop;
+
+ New_Line;
+ Put_Line (Standard_Error, "SOURCE is the source file to process.");
+ New_Line;
+ Put_Line (Standard_Error, "DICTIONARY is the name of a file "
+ & "that contains word replacements");
+ Put_Line (Standard_Error, "for the VMS version.");
+ New_Line;
+ Put_Line (Standard_Error,
+ "OUT-FILE, if present, is the output file to be created;");
+ Put_Line (Standard_Error,
+ "If OUT-FILE is absent, the output file is either " &
+ "gnat_ugn_unw.texi, ");
+ Put_Line (Standard_Error,
+ "or gnat_ugn_vms.texi, depending on TARGET.");
+ New_Line;
+ Put_Line (Standard_Error,
+ "WARNINGS, if present, is any string;");
+ Put_Line (Standard_Error,
+ "it will result in warning messages (e.g., line too long))");
+ Put_Line (Standard_Error,
+ "being output to Standard_Error.");
+ end Usage;
+
+ --------------
+ -- Get_Line --
+ --------------
+
+ function Get_Line (Input : access Input_File) return String is
+ Line_Buffer : String (1 .. Fatal_Line_Length_Limit);
+ Last : Natural;
+
+ begin
+ Input.Line := Input.Line + 1;
+ Get_Line (Input.Data, Line_Buffer, Last);
+
+ if Last = Line_Buffer'Last then
+ Error (Input.all, "line exceeds fatal line length limit");
+ raise Fatal_Line_Length;
+ end if;
+
+ declare
+ Line : String renames Line_Buffer (Line_Buffer'First .. Last);
+
+ begin
+ for J in Line'Range loop
+ if not Is_In (Line (J), Valid_Characters) then
+ Error (Input.all, J, "invalid character");
+ exit;
+ end if;
+ end loop;
+
+ if Line'Length > Maximum_Line_Length then
+ Warning (Input.all, Maximum_Line_Length + 1, "line too long");
+ end if;
+
+ if Reject_Trailing_Spaces
+ and then Line'Length > 0
+ and then Line (Line'Last) = ' '
+ then
+ Error (Input.all, Line'Last, "trailing space character");
+ end if;
+
+ return Trim (Line, Right);
+ end;
+ end Get_Line;
+
+ -----------
+ -- Error --
+ -----------
+
+ procedure Error
+ (Input : Input_File;
+ Message : String)
+ is
+ begin
+ Error (Input, 0, Message);
+ end Error;
+
+ procedure Error
+ (Input : Input_File;
+ At_Character : Natural;
+ Message : String)
+ is
+ Line_Image : constant String := Integer'Image (Input.Line);
+ At_Character_Image : constant String := Integer'Image (At_Character);
+ -- These variables are required because we have to drop the leading
+ -- space character.
+
+ begin
+ Number_Of_Errors := Number_Of_Errors + 1;
+
+ if At_Character > 0 then
+ Put_Line (Standard_Error,
+ S (Input.Name) & ':'
+ & Line_Image (Line_Image'First + 1 .. Line_Image'Last) & ':'
+ & At_Character_Image (At_Character_Image'First + 1
+ .. At_Character_Image'Last)
+ & ": "
+ & Message);
+ else
+ Put_Line (Standard_Error,
+ S (Input.Name) & ':'
+ & Line_Image (Line_Image'First + 1 .. Line_Image'Last)
+ & ": "
+ & Message);
+ end if;
+ end Error;
+
+ -------------
+ -- Warning --
+ -------------
+
+ procedure Warning
+ (Input : Input_File;
+ Message : String)
+ is
+ begin
+ if Warnings_Enabled then
+ Warning (Input, 0, Message);
+ end if;
+ end Warning;
+
+ procedure Warning
+ (Input : Input_File;
+ At_Character : Natural;
+ Message : String)
+ is
+ Line_Image : constant String := Integer'Image (Input.Line);
+ At_Character_Image : constant String := Integer'Image (At_Character);
+ -- These variables are required because we have to drop the leading
+ -- space character.
+
+ begin
+ if not Warnings_Enabled then
+ return;
+ end if;
+
+ Number_Of_Warnings := Number_Of_Warnings + 1;
+
+ if At_Character > 0 then
+ Put_Line (Standard_Error,
+ S (Input.Name) & ':'
+ & Line_Image (Line_Image'First + 1 .. Line_Image'Last) & ':'
+ & At_Character_Image (At_Character_Image'First + 1
+ .. At_Character_Image'Last)
+ & ": warning: "
+ & Message);
+ else
+ Put_Line (Standard_Error,
+ S (Input.Name) & ':'
+ & Line_Image (Line_Image'First + 1 .. Line_Image'Last)
+ & ": warning: "
+ & Message);
+ end if;
+ end Warning;
+
+ --------------------------
+ -- Read_Dictionary_File --
+ --------------------------
+
+ procedure Read_Dictionary_File is
+ begin
+ while not End_Of_File (Dictionary_File.Data) loop
+ declare
+ Line : constant String :=
+ Get_Line (Dictionary_File'Access);
+ Split : constant Natural :=
+ Index (Line, (1 => VMS_Escape_Character));
+
+ begin
+ if Line'Length = 0 then
+ Error (Dictionary_File, "empty line in dictionary file");
+
+ elsif Line (Line'First) = ' ' then
+ Error (Dictionary_File, 1, "line starts with space character");
+
+ elsif Split = 0 then
+ Error (Dictionary_File, "line does not contain "
+ & VMS_Escape_Character & " character");
+ else
+ declare
+ Source : constant String :=
+ Trim (Line (1 .. Split - 1), Both);
+ Target : constant String :=
+ Trim (Line (Split + 1 .. Line'Last), Both);
+ Two_Spaces : constant Natural :=
+ Index (Source, " ");
+ Non_Word_Character : constant Natural :=
+ Index (Source,
+ Word_Characters or
+ To_Set (" "),
+ Outside);
+
+ begin
+ if Two_Spaces /= 0 then
+ Error (Dictionary_File, Two_Spaces,
+ "multiple space characters in source word");
+ end if;
+
+ if Non_Word_Character /= 0 then
+ Error (Dictionary_File, Non_Word_Character,
+ "illegal character in source word");
+ end if;
+
+ if Source'Length = 0 then
+ Error (Dictionary_File, "source is empty");
+
+ elsif Target'Length = 0 then
+ Error (Dictionary_File, "target is empty");
+
+ else
+ Set (Ug_Words, Source, V (Target));
+
+ -- Ensure that if Source is a sequence of words
+ -- "WORD1 WORD2 ...", we already have a mapping for
+ -- "WORD1".
+
+ for J in Source'Range loop
+ if Source (J) = ' ' then
+ declare
+ Prefix : String renames
+ Source (Source'First .. J - 1);
+
+ begin
+ if not Is_Known_Word (Prefix) then
+ Error (Dictionary_File,
+ "prefix '" & Prefix
+ & "' not known at this point");
+ end if;
+ end;
+ end if;
+ end loop;
+ end if;
+ end;
+ end if;
+ end;
+ end loop;
+ end Read_Dictionary_File;
+
+ -------------------------
+ -- Rewrite_Source_Line --
+ -------------------------
+
+ function Rewrite_Source_Line (Line : String) return String is
+
+ -- We use a simple lexer to split the line into tokens:
+
+ -- Word consisting entirely of Word_Characters
+ -- VMS_Alternative ^alpha^beta^ replacement (but not ^^^)
+ -- Space a space character
+ -- Other everything else (sequence of non-word characters)
+ -- VMS_Error incomplete VMS alternative
+ -- End_Of_Line no more characters on this line
+
+ -- A sequence of three VMS_Escape_Characters is automatically
+ -- collapsed to an Other token.
+
+ type Token_Span is record
+ First, Last : Positive;
+ end record;
+ -- The character range covered by a token in Line
+
+ type Token_Kind is (End_Of_Line, Word, Other,
+ VMS_Alternative, VMS_Error);
+ type Token_Record (Kind : Token_Kind := End_Of_Line) is record
+ First : Positive;
+ case Kind is
+ when Word | Other =>
+ Span : Token_Span;
+ when VMS_Alternative =>
+ Non_VMS, VMS : Token_Span;
+ when VMS_Error | End_Of_Line =>
+ null;
+ end case;
+ end record;
+
+ Input_Position : Positive := Line'First;
+ Token : Token_Record;
+ -- The position of the next character to be processed by Next_Token
+
+ procedure Next_Token;
+ -- Returns the next token in Line, starting at Input_Position
+
+ Rewritten_Line : VString;
+ -- Collects the line as it is rewritten
+
+ procedure Rewrite_Word;
+ -- The current token is assumed to be a Word. When processing the VMS
+ -- version of the manual, additional tokens are gathered to check if
+ -- we have a file name or a sequence of known words.
+
+ procedure Maybe_Rewrite_Extension;
+ -- The current token is assumed to be Other. When processing the VMS
+ -- version of the manual and the token represents a single dot ".",
+ -- the following word is rewritten according to the rules for
+ -- extensions.
+
+ VMS_Token_Seen : Boolean := False;
+ -- This is set to true if a VMS_Alternative has been encountered, or a
+ -- ^^^ token.
+
+ ----------------
+ -- Next_Token --
+ ----------------
+
+ procedure Next_Token is
+ Remaining_Line : String renames Line (Input_Position .. Line'Last);
+ Last_Character : Natural;
+
+ begin
+ if Remaining_Line'Length = 0 then
+ Token := (End_Of_Line, Remaining_Line'First);
+ return;
+ end if;
+
+ -- ^alpha^beta^, the VMS_Alternative case.
+
+ if Remaining_Line (Remaining_Line'First) = VMS_Escape_Character then
+ declare
+ VMS_Second_Character, VMS_Third_Character : Natural;
+
+ begin
+ if VMS_Token_Seen then
+ Error (Source_File, Remaining_Line'First,
+ "multiple " & VMS_Escape_Character
+ & " characters on a single line");
+ else
+ VMS_Token_Seen := True;
+ end if;
+
+ -- Find the second and third escape character. If one of
+ -- them is not present, generate an error token.
+
+ VMS_Second_Character :=
+ Index (Remaining_Line (Remaining_Line'First + 1
+ .. Remaining_Line'Last),
+ (1 => VMS_Escape_Character));
+
+ if VMS_Second_Character = 0 then
+ Input_Position := Remaining_Line'Last + 1;
+ Token := (VMS_Error, Remaining_Line'First);
+ return;
+ end if;
+
+ VMS_Third_Character :=
+ Index (Remaining_Line (VMS_Second_Character + 1
+ .. Remaining_Line'Last),
+ (1 => VMS_Escape_Character));
+
+ if VMS_Third_Character = 0 then
+ Input_Position := Remaining_Line'Last + 1;
+ Token := (VMS_Error, Remaining_Line'First);
+ return;
+ end if;
+
+ -- Consume all the characters we are about to include in
+ -- the token.
+
+ Input_Position := VMS_Third_Character + 1;
+
+ -- Check if we are in a ^^^ situation, and return an Other
+ -- token in this case.
+
+ if Remaining_Line'First + 1 = VMS_Second_Character
+ and then Remaining_Line'First + 2 = VMS_Third_Character
+ then
+ Token := (Other, Remaining_Line'First,
+ (Remaining_Line'First, Remaining_Line'First));
+ return;
+ end if;
+
+ Token := (VMS_Alternative, Remaining_Line'First,
+ (Remaining_Line'First + 1, VMS_Second_Character - 1),
+ (VMS_Second_Character + 1, VMS_Third_Character - 1));
+ return;
+ end;
+ end if; -- VMS_Alternative
+
+ -- The Word case. Search for characters not in Word_Characters.
+ -- We have found a word if the first non-word character is not
+ -- the first character in Remaining_Line, i.e. if Remaining_Line
+ -- starts with a word character.
+
+ Last_Character := Index (Remaining_Line, Word_Characters, Outside);
+ if Last_Character /= Remaining_Line'First then
+
+ -- If we haven't found a character which is not in
+ -- Word_Characters, all remaining characters are part of the
+ -- current Word token.
+
+ if Last_Character = 0 then
+ Last_Character := Remaining_Line'Last + 1;
+ end if;
+
+ Input_Position := Last_Character;
+ Token := (Word, Remaining_Line'First,
+ (Remaining_Line'First, Last_Character - 1));
+ return;
+ end if;
+
+ -- Remaining characters are in the Other category. To speed
+ -- up processing, we collect them together if there are several
+ -- of them.
+
+ Input_Position := Last_Character + 1;
+ Token := (Other,
+ Remaining_Line'First,
+ (Remaining_Line'First, Last_Character));
+ end Next_Token;
+
+ ------------------
+ -- Rewrite_Word --
+ ------------------
+
+ procedure Rewrite_Word is
+ First_Word : String
+ renames Line (Token.Span.First .. Token.Span.Last);
+
+ begin
+ -- We do not perform any error checking below, so we can just skip
+ -- all processing for the non-VMS version.
+
+ if Target /= VMS then
+ Append (Rewritten_Line, First_Word);
+ Next_Token;
+ return;
+ end if;
+
+ if Is_Known_Word (First_Word) then
+
+ -- If we have a word from the dictionary, we look for the
+ -- longest possible sequence we can rewrite.
+
+ declare
+ Seq : Token_Span := Token.Span;
+ Lost_Space : Boolean := False;
+
+ begin
+ Next_Token;
+ loop
+ if Token.Kind = Other
+ and then Line (Token.Span.First .. Token.Span.Last) = " "
+ then
+ Next_Token;
+ if Token.Kind /= Word
+ or else not Is_Known_Word (Line (Seq.First
+ .. Token.Span.Last))
+ then
+ -- When we reach this point, the following
+ -- conditions are true:
+ --
+ -- Seq is a known word.
+ -- The previous token was a space character.
+ -- Seq extended to the current token is not a
+ -- known word.
+
+ Lost_Space := True;
+ exit;
+
+ else
+
+ -- Extend Seq to cover the current (known) word.
+
+ Seq.Last := Token.Span.Last;
+ Next_Token;
+ end if;
+
+ else
+ -- When we reach this point, the following conditions
+ -- are true:
+ --
+ -- Seq is a known word.
+ -- The previous token was a word.
+ -- The current token is not a space character.
+
+ exit;
+ end if;
+ end loop;
+
+ -- Rewrite Seq, and add the lost space if necessary
+
+ Append (Rewritten_Line,
+ Get_Replacement_Word (Line (Seq.First .. Seq.Last)));
+ if Lost_Space then
+ Append (Rewritten_Line, ' ');
+ end if;
+
+ -- The unknown token will be processed during the
+ -- next iteration of the main loop.
+ return;
+ end;
+ end if;
+
+ Next_Token;
+
+ if Token.Kind = Other
+ and then Line (Token.Span.First .. Token.Span.Last) = "."
+ then
+ -- Deal with extensions
+
+ Next_Token;
+ if Token.Kind = Word
+ and then Is_Extension (Line (Token.Span.First
+ .. Token.Span.Last))
+ then
+ -- We have discovered a file extension. Convert the file
+ -- name to upper case.
+
+ Append (Rewritten_Line,
+ Translate (First_Word, Upper_Case_Map) & '.');
+ Append (Rewritten_Line,
+ Get_Replacement_Extension
+ (Line (Token.Span.First .. Token.Span.Last)));
+ Next_Token;
+ else
+ -- We already have: Word ".", followed by an unknown
+ -- token.
+
+ Append (Rewritten_Line, First_Word & '.');
+
+ -- The unknown token will be processed during the next
+ -- iteration of the main loop.
+ end if;
+
+ else
+ -- We have an unknown Word, followed by an unknown token.
+ -- The unknown token will be processed by the outer loop.
+
+ Append (Rewritten_Line, First_Word);
+ end if;
+ end Rewrite_Word;
+
+ -----------------------------
+ -- Maybe_Rewrite_Extension --
+ -----------------------------
+
+ procedure Maybe_Rewrite_Extension is
+ begin
+ -- Again, we need no special processing in the non-VMS case
+
+ if Target = VMS
+ and then Line (Token.Span.First .. Token.Span.Last) = "."
+ then
+ -- This extension is not preceded by a word, otherwise
+ -- Rewrite_Word would have handled it.
+
+ Next_Token;
+ if Token.Kind = Word
+ and then Is_Extension (Line (Token.Span.First
+ .. Token.Span.Last))
+ then
+ Append (Rewritten_Line, '.' & Get_Replacement_Extension
+ (Line (Token.Span.First .. Token.Span.Last)));
+ Next_Token;
+ else
+ Append (Rewritten_Line, '.');
+ end if;
+ else
+ Append (Rewritten_Line, Line (Token.Span.First
+ .. Token.Span.Last));
+ Next_Token;
+ end if;
+ end Maybe_Rewrite_Extension;
+
+ -- Start of processing for Process_Source_Line
+
+ begin
+ -- The following parser recognizes the following special token
+ -- sequences:
+
+ -- Word "." Word rewrite as file name if second word is extension
+ -- Word " " Word rewrite as a single word using Ug_Words table
+
+ Next_Token;
+ loop
+ case Token.Kind is
+ when End_Of_Line =>
+ exit;
+
+ when Word =>
+ Rewrite_Word;
+
+ when Other =>
+ Maybe_Rewrite_Extension;
+
+ when VMS_Alternative =>
+ if VMS_Context_Determined then
+ if (not In_VMS_Section)
+ or else
+ Line (Token.VMS.First .. Token.VMS.Last) /=
+ Line (Token.Non_VMS.First .. Token.Non_VMS.Last)
+ then
+ Warning (Source_File, Token.First,
+ "VMS alternative already determined "
+ & "by conditionals");
+ end if;
+ end if;
+ if Target = VMS then
+ Append (Rewritten_Line, Line (Token.VMS.First
+ .. Token.VMS.Last));
+ else
+ Append (Rewritten_Line, Line (Token.Non_VMS.First
+ .. Token.Non_VMS.Last));
+ end if;
+ Next_Token;
+
+ when VMS_Error =>
+ Error (Source_File, Token.First, "invalid VMS alternative");
+ Next_Token;
+ end case;
+ end loop;
+
+ return S (Rewritten_Line);
+ end Rewrite_Source_Line;
+
+ -------------------------
+ -- Process_Source_File --
+ -------------------------
+
+ procedure Process_Source_File is
+ Ifset : constant String := "@ifset ";
+ Ifclear : constant String := "@ifclear ";
+ Endsetclear : constant String := "@end ";
+ -- Strings to be recognized for conditional processing.
+
+ begin
+ while not End_Of_File (Source_File.Data) loop
+ declare
+ Line : constant String := Get_Line (Source_File'Access);
+ Rewritten : constant String := Rewrite_Source_Line (Line);
+ -- We unconditionally rewrite the line so that we can check the
+ -- syntax of all lines, and not only those which are actually
+ -- included in the output.
+
+ Have_Conditional : Boolean := False;
+ -- True if we have encountered a conditional preprocessing
+ -- directive.
+
+ Cond : Conditional;
+ -- The kind of the directive.
+
+ Flag : Target_Type;
+ -- Its flag.
+
+ begin
+ -- If the line starts with @ifset or @ifclear, we try to convert
+ -- the following flag to one of our target types. If we fail,
+ -- Have_Conditional remains False.
+
+ if Line'Length >= Ifset'Length
+ and then Line (1 .. Ifset'Length) = Ifset
+ then
+ Cond := Set;
+
+ declare
+ Arg : constant String :=
+ Trim (Line (Ifset'Length + 1 .. Line'Last), Both);
+
+ begin
+ Flag := Target_Type'Value (Arg);
+
+ if Translate (Target_Type'Image (Flag), Lower_Case_Map)
+ /= Arg
+ then
+ Error (Source_File, "flag has to be lowercase");
+ end if;
+
+ Have_Conditional := True;
+
+ exception
+ when Constraint_Error =>
+ Error (Source_File, "unknown flag for '@ifset'");
+ end;
+
+ elsif Line'Length >= Ifclear'Length
+ and then Line (1 .. Ifclear'Length) = Ifclear
+ then
+ Cond := Clear;
+
+ declare
+ Arg : constant String :=
+ Trim (Line (Ifclear'Length + 1 .. Line'Last), Both);
+
+ begin
+ Flag := Target_Type'Value (Arg);
+ if Translate (Target_Type'Image (Flag), Lower_Case_Map)
+ /= Arg
+ then
+ Error (Source_File, "flag has to be lowercase");
+ end if;
+
+ Have_Conditional := True;
+
+ exception
+ when Constraint_Error =>
+ Error (Source_File, "unknown flag for '@ifclear'");
+ end;
+ end if;
+
+ if Have_Conditional then
+
+ -- We create a new conditional context and suppress the
+ -- directive in the output.
+
+ Push_Conditional (Cond, Flag);
+
+ elsif Line'Length >= Endsetclear'Length
+ and then Line (1 .. Endsetclear'Length) = Endsetclear
+ then
+ -- The '@end ifset'/'@end ifclear' case is handled here. We
+ -- have to pop the conditional context.
+
+ declare
+ First, Last : Natural;
+
+ begin
+ Find_Token (Source => Line (Endsetclear'Length + 1
+ .. Line'Length),
+ Set => Letter_Set,
+ Test => Inside,
+ First => First,
+ Last => Last);
+
+ if Last = 0 then
+ Error (Source_File, "'@end' without argument");
+ else
+ if Line (First .. Last) = "ifset" then
+ Have_Conditional := True;
+ Cond := Set;
+ elsif Line (First .. Last) = "ifclear" then
+ Have_Conditional := True;
+ Cond := Clear;
+ end if;
+
+ if Have_Conditional then
+ Pop_Conditional (Cond);
+ end if;
+
+ -- We fall through to the ordinary case for other @end
+ -- directives.
+
+ end if; -- @end without argument
+ end;
+ end if; -- Have_Conditional
+
+ if not Have_Conditional then
+
+ -- The ordinary case.
+
+ if not Currently_Excluding then
+ Put_Line (Output_File, Rewritten);
+ end if;
+ end if;
+ end;
+ end loop;
+
+ Check_No_Pending_Conditional;
+ end Process_Source_File;
+
+ ---------------------------
+ -- Initialize_Extensions --
+ ---------------------------
+
+ procedure Initialize_Extensions is
+
+ procedure Add (Extension : String);
+ -- Adds an extension which is replaced with itself (in upper
+ -- case).
+
+ procedure Add (Extension, Replacement : String);
+ -- Adds an extension with a custom replacement.
+
+ ---------
+ -- Add --
+ ---------
+
+ procedure Add (Extension : String) is
+ begin
+ Add (Extension, Translate (Extension, Upper_Case_Map));
+ end Add;
+
+ procedure Add (Extension, Replacement : String) is
+ begin
+ Set (Extensions, Extension, V (Replacement));
+ end Add;
+
+ -- Start of processing for Initialize_Extensions
+
+ begin
+ -- To avoid performance degradation, increase the constant in the
+ -- definition of Extensions above if you add more extensions here.
+
+ Add ("o", "OBJ");
+ Add ("ads");
+ Add ("adb");
+ Add ("ali");
+ Add ("ada");
+ Add ("atb");
+ Add ("ats");
+ Add ("adc");
+ Add ("c");
+ end Initialize_Extensions;
+
+ ------------------
+ -- Is_Extension --
+ ------------------
+
+ function Is_Extension (Extension : String) return Boolean is
+ begin
+ return Present (Extensions, Extension);
+ end Is_Extension;
+
+ -------------------------------
+ -- Get_Replacement_Extension --
+ -------------------------------
+
+ function Get_Replacement_Extension (Extension : String) return String is
+ begin
+ return S (Get (Extensions, Extension));
+ end Get_Replacement_Extension;
+
+ -------------------
+ -- Is_Known_Word --
+ -------------------
+
+ function Is_Known_Word (Word : String) return Boolean is
+ begin
+ return Present (Ug_Words, Word);
+ end Is_Known_Word;
+
+ --------------------------
+ -- Get_Replacement_Word --
+ --------------------------
+
+ function Get_Replacement_Word (Word : String) return String is
+ begin
+ return S (Get (Ug_Words, Word));
+ end Get_Replacement_Word;
+
+ ----------------------
+ -- Push_Conditional --
+ ----------------------
+
+ procedure Push_Conditional (Cond : Conditional; Flag : Target_Type) is
+ Will_Exclude : Boolean;
+
+ begin
+ -- If we are already in an excluding context, inherit this property,
+ -- otherwise calculate it from scratch.
+
+ if Conditional_TOS > 0
+ and then Conditional_Stack (Conditional_TOS).Excluding
+ then
+ Will_Exclude := True;
+ else
+ case Cond is
+ when Set =>
+ Will_Exclude := Flag /= Target;
+ when Clear =>
+ Will_Exclude := Flag = Target;
+ end case;
+ end if;
+
+ -- Check if the current directive is pointless because of a previous,
+ -- enclosing directive.
+
+ for J in 1 .. Conditional_TOS loop
+ if Conditional_Stack (J).Flag = Flag then
+ Warning (Source_File, "directive without effect because of line"
+ & Integer'Image (Conditional_Stack (J).Starting_Line));
+ end if;
+ end loop;
+
+ Conditional_TOS := Conditional_TOS + 1;
+ Conditional_Stack (Conditional_TOS) :=
+ (Starting_Line => Source_File.Line,
+ Cond => Cond,
+ Flag => Flag,
+ Excluding => Will_Exclude);
+ end Push_Conditional;
+
+ ---------------------
+ -- Pop_Conditional --
+ ---------------------
+
+ procedure Pop_Conditional (Cond : Conditional) is
+ begin
+ if Conditional_TOS > 0 then
+ case Cond is
+ when Set =>
+ if Conditional_Stack (Conditional_TOS).Cond /= Set then
+ Error (Source_File,
+ "'@end ifset' does not match '@ifclear' at line"
+ & Integer'Image (Conditional_Stack
+ (Conditional_TOS).Starting_Line));
+ end if;
+
+ when Clear =>
+ if Conditional_Stack (Conditional_TOS).Cond /= Clear then
+ Error (Source_File,
+ "'@end ifclear' does not match '@ifset' at line"
+ & Integer'Image (Conditional_Stack
+ (Conditional_TOS).Starting_Line));
+ end if;
+ end case;
+
+ Conditional_TOS := Conditional_TOS - 1;
+
+ else
+ case Cond is
+ when Set =>
+ Error (Source_File,
+ "'@end ifset' without corresponding '@ifset'");
+
+ when Clear =>
+ Error (Source_File,
+ "'@end ifclear' without corresponding '@ifclear'");
+ end case;
+ end if;
+ end Pop_Conditional;
+
+ -------------------------
+ -- Currently_Excluding --
+ -------------------------
+
+ function Currently_Excluding return Boolean is
+ begin
+ return Conditional_TOS > 0
+ and then Conditional_Stack (Conditional_TOS).Excluding;
+ end Currently_Excluding;
+
+ ----------------------------
+ -- VMS_Context_Determined --
+ ----------------------------
+
+ function VMS_Context_Determined return Boolean is
+ begin
+ for J in 1 .. Conditional_TOS loop
+ if Conditional_Stack (J).Flag = VMS then
+ return True;
+ end if;
+ end loop;
+
+ return False;
+ end VMS_Context_Determined;
+
+ --------------------
+ -- In_VMS_Section --
+ --------------------
+
+ function In_VMS_Section return Boolean is
+ begin
+ for J in 1 .. Conditional_TOS loop
+ if Conditional_Stack (J).Flag = VMS then
+ return Conditional_Stack (J).Cond = Set;
+ end if;
+ end loop;
+
+ return False;
+ end In_VMS_Section;
+
+ ----------------------------------
+ -- Check_No_Pending_Conditional --
+ ----------------------------------
+
+ procedure Check_No_Pending_Conditional is
+ begin
+ for J in 1 .. Conditional_TOS loop
+ case Conditional_Stack (J).Cond is
+ when Set =>
+ Error (Source_File, "Missing '@end ifset' for '@ifset' at line"
+ & Integer'Image (Conditional_Stack (J).Starting_Line));
+
+ when Clear =>
+ Error (Source_File,
+ "Missing '@end ifclear' for '@ifclear' at line"
+ & Integer'Image (Conditional_Stack (J).Starting_Line));
+ end case;
+ end loop;
+ end Check_No_Pending_Conditional;
+
+ ------------------
+ -- Main Program --
+ ------------------
+
+ Valid_Command_Line : Boolean;
+ Output_File_Name : VString;
+
+begin
+ Initialize_Extensions;
+
+ Valid_Command_Line := Argument_Count in 3 .. 5;
+
+ -- First argument: Target.
+
+ if Valid_Command_Line then
+ begin
+ Target := Target_Type'Value (Argument (1));
+
+ exception
+ when Constraint_Error =>
+ Valid_Command_Line := False;
+ end;
+ end if;
+
+ -- Second argument: Source_File.
+
+ if Valid_Command_Line then
+ begin
+ Source_File.Name := V (Argument (2));
+ Open (Source_File.Data, In_File, Argument (2));
+
+ exception
+ when Name_Error =>
+ Valid_Command_Line := False;
+ end;
+ end if;
+
+ -- Third argument: Dictionary_File.
+
+ if Valid_Command_Line then
+ begin
+ Dictionary_File.Name := V (Argument (3));
+ Open (Dictionary_File.Data, In_File, Argument (3));
+
+ exception
+ when Name_Error =>
+ Valid_Command_Line := False;
+ end;
+ end if;
+
+ -- Fourth argument: Output_File.
+
+ if Valid_Command_Line then
+ if Argument_Count in 4 .. 5 then
+ Output_File_Name := V (Argument (4));
+ else
+ case Target is
+ when UNW =>
+ Output_File_Name := V ("gnat_ugn_unw.texi");
+ when VMS =>
+ Output_File_Name := V ("gnat_ugn_vms.texi");
+ end case;
+ end if;
+
+ Warnings_Enabled := Argument_Count = 5;
+
+ begin
+ Create (Output_File, Out_File, S (Output_File_Name));
+
+ exception
+ when Name_Error | Use_Error =>
+ Valid_Command_Line := False;
+ end;
+ end if;
+
+ if not Valid_Command_Line then
+ Usage;
+ Set_Exit_Status (Failure);
+
+ else
+ Read_Dictionary_File;
+ Close (Dictionary_File.Data);
+
+ -- Main processing starts here.
+
+ Process_Source_File;
+ Close (Output_File);
+ Close (Source_File.Data);
+
+ New_Line (Standard_Error);
+
+ if Number_Of_Warnings = 0 then
+ Put_Line (Standard_Error, " NO Warnings");
+
+ else
+ Put (Standard_Error, Integer'Image (Number_Of_Warnings));
+ Put (Standard_Error, " Warning");
+
+ if Number_Of_Warnings > 1 then
+ Put (Standard_Error, "s");
+ end if;
+
+ New_Line (Standard_Error);
+ end if;
+
+ if Number_Of_Errors = 0 then
+ Put_Line (Standard_Error, " NO Errors");
+
+ else
+ Put (Standard_Error, Integer'Image (Number_Of_Errors));
+ Put (Standard_Error, " Error");
+
+ if Number_Of_Errors > 1 then
+ Put (Standard_Error, "s");
+ end if;
+
+ New_Line (Standard_Error);
+ end if;
+
+ if Number_Of_Errors /= 0 then
+ Set_Exit_Status (Failure);
+ else
+ Set_Exit_Status (Success);
+ end if;
+ end if;
+end Xgnatugn;
diff --git a/gcc/alias.h b/gcc/alias.h
new file mode 100644
index 00000000000..371cdabf947
--- /dev/null
+++ b/gcc/alias.h
@@ -0,0 +1,31 @@
+/* Exported functions from alias.c
+ 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. */
+
+#ifndef GCC_ALIAS_H
+#define GCC_ALIAS_H
+
+extern HOST_WIDE_INT new_alias_set (void);
+extern void record_alias_subset (HOST_WIDE_INT, HOST_WIDE_INT);
+extern HOST_WIDE_INT get_varargs_alias_set (void);
+extern HOST_WIDE_INT get_frame_alias_set (void);
+extern void record_base_value (unsigned int, rtx, int);
+extern int can_address_p (tree);
+
+#endif /* GCC_ALIAS_H */
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
new file mode 100644
index 00000000000..0d92967ff7b
--- /dev/null
+++ b/gcc/c-gimplify.c
@@ -0,0 +1,542 @@
+/* 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, 2004 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. */
+
+enum bc_t { bc_break = 0, bc_continue = 1 };
+
+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);
+}
+
+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. */
+
+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 ();
+ if (decls || block)
+ {
+ bind = build (BIND_EXPR, void_type_node, decls, body, block);
+ TREE_SIDE_EFFECTS (bind) = 1;
+ }
+ else
+ bind = body;
+
+ return bind;
+}
+
+/* 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)
+ warn_if_unused_value (stmt, input_location);
+ }
+
+ if (stmt == NULL_TREE)
+ stmt = alloc_stmt_list ();
+
+ *stmt_p = stmt;
+
+ return GS_OK;
+}
+
+/* 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)
+ {
+ 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);
+ 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 *pre_p)
+{
+ tree stmt = *stmt_p;
+
+ if (FOR_INIT_STMT (stmt))
+ gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
+
+ *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 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);
+
+ body = SWITCH_BODY (stmt);
+ if (!body)
+ body = build_empty_stmt ();
+
+ *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
+ body, NULL_TREE);
+ SET_EXPR_LOCATION (*stmt_p, stmt_locus);
+ gimplify_stmt (stmt_p);
+
+ *stmt_p = finish_bc_block (break_block, *stmt_p);
+ return GS_ALL_DONE;
+}
+
+/* Gimplification of expression trees. */
+
+/* Gimplify a C99 compound literal expression. This just means adding the
+ DECL_EXPR before the current EXPR_STMT and using its anonymous decl
+ instead. */
+
+static enum gimplify_status
+gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
+{
+ tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
+ tree decl = DECL_EXPR_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_and_add (decl_s, pre_p);
+ *expr_p = decl;
+ return GS_OK;
+}
+
+/* Do C-specific gimplification. Args are as for gimplify_expr. */
+
+int
+c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
+{
+ enum tree_code code = TREE_CODE (*expr_p);
+
+ switch (code)
+ {
+ case DECL_EXPR:
+ /* This is handled mostly by gimplify.c, but we have to deal with
+ not warning about int x = x; as it is a GCC extension to turn off
+ this warning but only if warn_init_self is zero. */
+ if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
+ && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
+ && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
+ && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
+ == DECL_EXPR_DECL (*expr_p))
+ && !warn_init_self)
+ TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
+ return GS_UNHANDLED;
+
+ case COMPOUND_LITERAL_EXPR:
+ return gimplify_compound_literal_expr (expr_p, pre_p);
+
+ case FOR_STMT:
+ return gimplify_for_stmt (expr_p, pre_p);
+
+ case WHILE_STMT:
+ return gimplify_while_stmt (expr_p);
+
+ case DO_STMT:
+ return gimplify_do_stmt (expr_p);
+
+ case SWITCH_STMT:
+ return gimplify_switch_stmt (expr_p);
+
+ case EXPR_STMT:
+ return gimplify_expr_stmt (expr_p);
+
+ case CONTINUE_STMT:
+ *expr_p = build_bc_goto (bc_continue);
+ return GS_ALL_DONE;
+
+ case BREAK_STMT:
+ *expr_p = build_bc_goto (bc_break);
+ return GS_ALL_DONE;
+
+ default:
+ return GS_UNHANDLED;
+ }
+}
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
new file mode 100644
index 00000000000..01b58a1d7b1
--- /dev/null
+++ b/gcc/cfgexpand.c
@@ -0,0 +1,451 @@
+/* A pass for lowering trees to RTL.
+ 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 "basic-block.h"
+#include "function.h"
+#include "expr.h"
+#include "langhooks.h"
+#include "tree-flow.h"
+#include "timevar.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "except.h"
+#include "flags.h"
+/* Expand basic block BB from GIMPLE trees to RTL. */
+
+static basic_block
+expand_block (basic_block bb, FILE * dump_file)
+{
+ block_stmt_iterator bsi = bsi_start (bb);
+ tree stmt = NULL;
+ rtx note, last;
+ edge e;
+
+ if (dump_file)
+ {
+ tree_register_cfg_hooks ();
+ dump_bb (bb, dump_file, 0);
+ rtl_register_cfg_hooks ();
+ }
+
+ if (!bsi_end_p (bsi))
+ stmt = bsi_stmt (bsi);
+
+ if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
+ {
+ last = get_last_insn ();
+
+ expand_expr_stmt (stmt);
+
+ /* Java emits line number notes in the top of labels.
+ ??? Make this go away once line number notes are obsoleted. */
+ BB_HEAD (bb) = NEXT_INSN (last);
+ if (GET_CODE (BB_HEAD (bb)) == NOTE)
+ BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
+ bsi_next (&bsi);
+ note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
+ }
+ else
+ note = BB_HEAD (bb) = emit_note (NOTE_INSN_BASIC_BLOCK);
+
+ NOTE_BASIC_BLOCK (note) = bb;
+
+ e = bb->succ;
+ while (e)
+ {
+ edge next = e->succ_next;
+
+ /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
+ e->flags &= ~EDGE_EXECUTABLE;
+
+ /* At the moment not all abnormal edges match the RTL representation.
+ It is safe to remove them here as find_sub_basic_blocks will
+ rediscover them. In the future we should get this fixed properly. */
+ if (e->flags & EDGE_ABNORMAL)
+ remove_edge (e);
+
+ e = next;
+ }
+
+ for (; !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ last = get_last_insn ();
+
+ if (!stmt)
+ continue;
+
+ /* Expand this statement, then evaluate the resulting RTL and
+ fixup the CFG accordingly. */
+ switch (TREE_CODE (stmt))
+ {
+ case COND_EXPR:
+ {
+ basic_block new_bb, dest;
+ edge new_edge;
+ edge true_edge;
+ edge false_edge;
+ tree pred = COND_EXPR_COND (stmt);
+ tree then_exp = COND_EXPR_THEN (stmt);
+ tree else_exp = COND_EXPR_ELSE (stmt);
+ rtx last = get_last_insn ();
+
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+ if (EXPR_LOCUS (stmt))
+ {
+ emit_line_note (*(EXPR_LOCUS (stmt)));
+ record_block_change (TREE_BLOCK (stmt));
+ }
+
+ /* These flags have no purpose in RTL land. */
+ true_edge->flags &= ~EDGE_TRUE_VALUE;
+ false_edge->flags &= ~EDGE_FALSE_VALUE;
+
+ /* We can either have a pure conditional jump with one fallthru
+ edge or two-way jump that needs to be decomposed into two
+ basic blocks. */
+ if (TREE_CODE (then_exp) == GOTO_EXPR
+ && TREE_CODE (else_exp) == NOP_EXPR)
+ {
+ jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
+ break;
+ }
+ if (TREE_CODE (else_exp) == GOTO_EXPR
+ && TREE_CODE (then_exp) == NOP_EXPR)
+ {
+ jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_exp)));
+ break;
+ }
+ if (TREE_CODE (then_exp) != GOTO_EXPR
+ || TREE_CODE (else_exp) != GOTO_EXPR)
+ abort ();
+
+ jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
+ last = get_last_insn ();
+ expand_expr (else_exp, const0_rtx, VOIDmode, 0);
+
+ BB_END (bb) = last;
+ if (GET_CODE (BB_END (bb)) == BARRIER)
+ BB_END (bb) = PREV_INSN (BB_END (bb));
+ update_bb_for_insn (bb);
+
+ new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
+ dest = false_edge->dest;
+ redirect_edge_succ (false_edge, new_bb);
+ false_edge->flags |= EDGE_FALLTHRU;
+ new_bb->count = false_edge->count;
+ new_bb->frequency = EDGE_FREQUENCY (false_edge);
+ new_edge = make_edge (new_bb, dest, 0);
+ new_edge->probability = REG_BR_PROB_BASE;
+ new_edge->count = new_bb->count;
+ if (GET_CODE (BB_END (new_bb)) == BARRIER)
+ BB_END (new_bb) = PREV_INSN (BB_END (new_bb));
+ update_bb_for_insn (new_bb);
+
+ if (dump_file)
+ {
+ dump_bb (bb, dump_file, 0);
+ dump_bb (new_bb, dump_file, 0);
+ }
+ return new_bb;
+ }
+
+ /* Update after expansion of sibling call. */
+ case CALL_EXPR:
+ case MODIFY_EXPR:
+ case RETURN_EXPR:
+ expand_expr_stmt (stmt);
+ for (last = NEXT_INSN (last); last; last = NEXT_INSN (last))
+ {
+ if (GET_CODE (last) == CALL_INSN && SIBLING_CALL_P (last))
+ {
+ edge e;
+ int probability = 0;
+ gcov_type count = 0;
+
+ do_pending_stack_adjust ();
+ e = bb->succ;
+ while (e)
+ {
+ edge next = e->succ_next;
+
+ if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
+ {
+ if (e->dest != EXIT_BLOCK_PTR)
+ {
+ e->dest->count -= e->count;
+ e->dest->frequency -= EDGE_FREQUENCY (e);
+ if (e->dest->count < 0)
+ e->dest->count = 0;
+ if (e->dest->frequency < 0)
+ e->dest->frequency = 0;
+ }
+ count += e->count;
+ probability += e->probability;
+ remove_edge (e);
+ }
+
+ e = next;
+ }
+
+ /* This is somewhat ugly: the call_expr expander often emits instructions
+ after the sibcall (to perform the function return). These confuse the
+ find_sub_basic_blocks code, so we need to get rid of these. */
+ last = NEXT_INSN (last);
+ if (GET_CODE (last) != BARRIER)
+ abort ();
+ while (NEXT_INSN (last))
+ {
+ /* For instance an sqrt builtin expander expands if with
+ sibcall in the then and label for `else`. */
+ if (GET_CODE (NEXT_INSN (last)) == CODE_LABEL)
+ break;
+ delete_insn (NEXT_INSN (last));
+ }
+ e = make_edge (bb, EXIT_BLOCK_PTR,
+ EDGE_ABNORMAL | EDGE_SIBCALL);
+ e->probability += probability;
+ e->count += count;
+ BB_END (bb) = last;
+ update_bb_for_insn (bb);
+ if (NEXT_INSN (last))
+ bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
+ else
+ return bb;
+ }
+ }
+ break;
+
+ default:
+ expand_expr_stmt (stmt);
+ break;
+ }
+ }
+
+ do_pending_stack_adjust ();
+
+ /* Find the the block tail. The last insn is the block is the insn
+ before a barrier and/or table jump insn. */
+ last = get_last_insn ();
+ if (GET_CODE (last) == BARRIER)
+ last = PREV_INSN (last);
+ if (JUMP_TABLE_DATA_P (last))
+ last = PREV_INSN (PREV_INSN (last));
+ BB_END (bb) = last;
+
+ if (dump_file)
+ dump_bb (bb, dump_file, 0);
+ update_bb_for_insn (bb);
+ return bb;
+}
+
+
+/* Create a basic block for initialization code. */
+
+static basic_block
+construct_init_block (void)
+{
+ basic_block init_block, first_block;
+ edge e;
+
+ expand_start_bindings_and_block (0, NULL_TREE);
+
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ if (e->dest == ENTRY_BLOCK_PTR->next_bb)
+ break;
+
+ init_block = create_basic_block (NEXT_INSN (get_insns ()),
+ get_last_insn (),
+ ENTRY_BLOCK_PTR);
+ init_block->frequency = ENTRY_BLOCK_PTR->frequency;
+ init_block->count = ENTRY_BLOCK_PTR->count;
+ if (e)
+ {
+ first_block = e->dest;
+ redirect_edge_succ (e, init_block);
+ e = make_edge (init_block, first_block, EDGE_FALLTHRU);
+ }
+ else
+ e = make_edge (init_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
+ e->probability = REG_BR_PROB_BASE;
+ e->count = ENTRY_BLOCK_PTR->count;
+
+ update_bb_for_insn (init_block);
+ return init_block;
+}
+
+
+/* Create a block containing landing pads and similar stuff. */
+
+static void
+construct_exit_block (void)
+{
+ rtx head = get_last_insn ();
+ rtx end;
+ basic_block exit_block;
+ edge e, e2, next;
+
+ /* Make sure the locus is set to the end of the function, so that
+ epilogue line numbers and warnings are set properly. */
+#ifdef USE_MAPPED_LOCATION
+ if (cfun->function_end_locus != UNKNOWN_LOCATION)
+#else
+ if (cfun->function_end_locus.file)
+#endif
+ input_location = cfun->function_end_locus;
+
+ /* The following insns belong to the top scope. */
+ record_block_change (DECL_INITIAL (current_function_decl));
+
+ expand_end_bindings (NULL_TREE, 1, 0);
+
+ /* Generate rtl for function exit. */
+ expand_function_end ();
+
+ end = get_last_insn ();
+ if (head == end)
+ return;
+ while (NEXT_INSN (head) && GET_CODE (NEXT_INSN (head)) == NOTE)
+ head = NEXT_INSN (head);
+ exit_block = create_basic_block (NEXT_INSN (head), end, EXIT_BLOCK_PTR->prev_bb);
+ exit_block->frequency = EXIT_BLOCK_PTR->frequency;
+ exit_block->count = EXIT_BLOCK_PTR->count;
+ for (e = EXIT_BLOCK_PTR->pred; e; e = next)
+ {
+ next = e->pred_next;
+ if (!(e->flags & EDGE_ABNORMAL))
+ redirect_edge_succ (e, exit_block);
+ }
+ e = make_edge (exit_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
+ e->probability = REG_BR_PROB_BASE;
+ e->count = EXIT_BLOCK_PTR->count;
+ for (e2 = EXIT_BLOCK_PTR->pred; e2; e2 = e2->pred_next)
+ if (e2 != e)
+ {
+ e->count -= e2->count;
+ exit_block->count -= e2->count;
+ exit_block->frequency -= EDGE_FREQUENCY (e2);
+ }
+ if (e->count < 0)
+ e->count = 0;
+ if (exit_block->count < 0)
+ exit_block->count = 0;
+ if (exit_block->frequency < 0)
+ exit_block->frequency = 0;
+ update_bb_for_insn (exit_block);
+}
+
+/* Translate the intermediate representation contained in the CFG
+ from GIMPLE trees to RTL.
+
+ We do conversion per basic block and preserve/update the tree CFG.
+ This implies we have to do some magic as the CFG can simultaneously
+ consist of basic blocks containing RTL and GIMPLE trees. This can
+ confuse the CFG hooks, so be careful to not manipulate CFG during
+ the expansion. */
+
+static void
+tree_expand_cfg (void)
+{
+ basic_block bb, init_block;
+ sbitmap blocks;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "\n;; Function %s",
+ (*lang_hooks.decl_printable_name) (current_function_decl, 2));
+ fprintf (dump_file, " (%s)\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
+ }
+
+ /* Prepare the rtl middle end to start recording block changes. */
+ reset_block_changes ();
+
+ /* 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 (current_function_decl);
+
+ /* If this function is `main', emit a call to `__main'
+ to run global initializers, etc. */
+ if (DECL_NAME (current_function_decl)
+ && MAIN_NAME_P (DECL_NAME (current_function_decl))
+ && DECL_FILE_SCOPE_P (current_function_decl))
+ expand_main_function ();
+
+ /* Write the flowgraph to a dot file. */
+ rtl_register_cfg_hooks ();
+
+ init_block = construct_init_block ();
+
+ FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
+ bb = expand_block (bb, dump_file);
+
+ construct_exit_block ();
+
+ /* 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 ();
+
+ rebuild_jump_labels (get_insns ());
+ find_exception_handler_labels ();
+
+ blocks = sbitmap_alloc (last_basic_block);
+ sbitmap_ones (blocks);
+ find_many_sub_basic_blocks (blocks);
+ purge_all_dead_edges (0);
+ sbitmap_free (blocks);
+
+ compact_blocks ();
+#ifdef ENABLE_CHECKING
+ verify_flow_info();
+#endif
+}
+
+struct tree_opt_pass pass_expand =
+{
+ "expand", /* name */
+ NULL, /* gate */
+ tree_expand_cfg, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_EXPAND, /* tv_id */
+ /* ??? If TER is enabled, we actually receive GENERIC. */
+ PROP_gimple_leh | PROP_cfg, /* properties_required */
+ PROP_rtl, /* properties_provided */
+ PROP_gimple_leh, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d90103e703e..b2ff003a959 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -2012,22 +2012,38 @@ split_small_symbolic_operand (rtx x)
Technically we could copy them if we could set up a mapping from one
sequence number to another, across the set of insns to be duplicated.
This seems overly complicated and error-prone since interblock motion
- from sched-ebb could move one of the pair of insns to a different block.
-
- Also cannot allow jsr insns to be duplicated. If they throw exceptions,
- then they'll be in a different block from their ldgp. Which could lead
- the bb reorder code to think that it would be ok to copy just the block
- containing the call and branch to the block containing the ldgp. */
+ from sched-ebb could move one of the pair of insns to a different block. */
static bool
alpha_cannot_copy_insn_p (rtx insn)
{
+ rtx pat;
+
if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
return false;
- if (recog_memoized (insn) >= 0)
- return get_attr_cannot_copy (insn);
- else
+
+ if (GET_CODE (insn) != INSN)
return false;
+ if (asm_noperands (insn) >= 0)
+ return false;
+
+ pat = PATTERN (insn);
+ if (GET_CODE (pat) != SET)
+ return false;
+ pat = SET_SRC (pat);
+ if (GET_CODE (pat) == UNSPEC_VOLATILE)
+ {
+ if (XINT (pat, 1) == UNSPECV_LDGP1
+ || XINT (pat, 1) == UNSPECV_PLDGP2)
+ return true;
+ }
+ else if (GET_CODE (pat) == UNSPEC)
+ {
+ if (XINT (pat, 1) == UNSPEC_LDGP2)
+ return true;
+ }
+
+ return false;
}
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 6c25d67dff9..01f96ca47c2 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -97,8 +97,8 @@
;; separately.
(define_attr "type"
- "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
- icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
+ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
+fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_string "iadd"))
;; Describe a user's asm statement.
@@ -154,14 +154,6 @@
]
(const_string "no")))
-;; The CANNOT_COPY attribute marks instructions with relocations that
-;; cannot easily be duplicated. This includes insns with gpdisp relocs
-;; since they have to stay in 1-1 correspondence with one another. This
-;; also includes jsr insns, since they must stay in correspondence with
-;; the immediately following gpdisp instructions.
-
-(define_attr "cannot_copy" "false,true"
- (const_string "false"))
;; Include scheduling descriptions.
@@ -4748,8 +4740,7 @@
(use (match_operand 3 "const_int_operand" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
- [(set_attr "type" "jsr")
- (set_attr "cannot_copy" "true")])
+ [(set_attr "type" "jsr")])
;; We output a nop after noreturn calls at the very end of the function to
;; ensure that the return address always remains in the caller's code range,
@@ -6823,8 +6814,7 @@
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "ldah %0,0(%1)\t\t!gpdisp!%2"
- [(set_attr "cannot_copy" "true")])
+ "ldah %0,0(%1)\t\t!gpdisp!%2")
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6832,8 +6822,7 @@
(match_operand 2 "const_int_operand" "")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2"
- [(set_attr "cannot_copy" "true")])
+ "lda %0,0(%1)\t\t!gpdisp!%2")
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6841,8 +6830,7 @@
(match_operand 2 "const_int_operand" "")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
- [(set_attr "cannot_copy" "true")])
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6850,8 +6838,7 @@
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
""
- "ldgp %0,0(%1)\n$%~..ng:"
- [(set_attr "cannot_copy" "true")])
+ "ldgp %0,0(%1)\n$%~..ng:")
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -7987,8 +7974,7 @@
(use (match_operand 4 "" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
- [(set_attr "type" "jsr")
- (set_attr "cannot_copy" "true")])
+ [(set_attr "type" "jsr")])
(define_insn "*call_value_osf_1_noreturn"
[(set (match_operand 0 "" "")
diff --git a/gcc/config/arm/arm-cores.def b/gcc/config/arm/arm-cores.def
new file mode 100644
index 00000000000..cf08aa865f3
--- /dev/null
+++ b/gcc/config/arm/arm-cores.def
@@ -0,0 +1,92 @@
+/* ARM CPU Cores
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by CodeSourcery, LLC
+
+ 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. */
+
+/* Before using #include to read this file, define a macro:
+
+ 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.
+ 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.
+
+ Some tools assume no whitespace up to the first "," in each entry. */
+
+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, 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, 3, FL_CO_PROC | FL_MODE26, slowmul)
+/* V4 Architecture Processors */
+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, 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, 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, 6J, 0, 9e)
+ARM_CORE(arm1136jfs, 6J, FL_VFPV2, 9e)
diff --git a/gcc/config/arm/arm-generic.md b/gcc/config/arm/arm-generic.md
new file mode 100644
index 00000000000..ec2df47b465
--- /dev/null
+++ b/gcc/config/arm/arm-generic.md
@@ -0,0 +1,152 @@
+;; Generic ARM Pipeline Description
+;; 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. */
+
+(define_automaton "arm")
+
+;; Write buffer
+;
+; Strictly, we should model a 4-deep write buffer for ARM7xx based chips
+;
+; The write buffer on some of the arm6 processors is hard to model exactly.
+; There is room in the buffer for up to two addresses and up to eight words
+; of memory, but the two needn't be split evenly. When writing the two
+; addresses are fully pipelined. However, a read from memory that is not
+; currently in the cache will block until the writes have completed.
+; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
+; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
+; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
+; cycle to add as well.
+(define_cpu_unit "write_buf" "arm")
+
+;; Write blockage unit
+;
+; The write_blockage unit models (partially), the fact that reads will stall
+; until the write buffer empties.
+; The f_mem_r and r_mem_f could also block, but they are to the stack,
+; so we don't model them here
+(define_cpu_unit "write_blockage" "arm")
+
+;; Core
+;
+(define_cpu_unit "core" "arm")
+
+(define_insn_reservation "r_mem_f_wbuf" 5
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "r_mem_f")))
+ "core+write_buf*3")
+
+(define_insn_reservation "store_wbuf" 5
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1")))
+ "core+write_buf*3+write_blockage*5")
+
+(define_insn_reservation "store2_wbuf" 7
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2")))
+ "core+write_buf*4+write_blockage*7")
+
+(define_insn_reservation "store3_wbuf" 9
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3")))
+ "core+write_buf*5+write_blockage*9")
+
+(define_insn_reservation "store4_wbuf" 11
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store4")))
+ "core+write_buf*6+write_blockage*11")
+
+(define_insn_reservation "store2" 3
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store2")))
+ "core*3")
+
+(define_insn_reservation "store3" 4
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store3")))
+ "core*4")
+
+(define_insn_reservation "store4" 5
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store4")))
+ "core*5")
+
+(define_insn_reservation "store_ldsched" 1
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "yes")
+ (eq_attr "type" "store1")))
+ "core")
+
+(define_insn_reservation "load_ldsched_xscale" 3
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "yes")
+ (and (eq_attr "type" "load_byte,load1")
+ (eq_attr "is_xscale" "yes"))))
+ "core")
+
+(define_insn_reservation "load_ldsched" 2
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "yes")
+ (and (eq_attr "type" "load_byte,load1")
+ (eq_attr "is_xscale" "no"))))
+ "core")
+
+(define_insn_reservation "load_or_store" 2
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "!yes")
+ (eq_attr "type" "load_byte,load1,load2,load3,load4,store1")))
+ "core*2")
+
+(define_insn_reservation "mult" 16
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")))
+ "core*16")
+
+(define_insn_reservation "mult_ldsched_strongarm" 3
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "yes")
+ (and (eq_attr "is_strongarm" "yes")
+ (eq_attr "type" "mult"))))
+ "core*2")
+
+(define_insn_reservation "mult_ldsched" 4
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "ldsched" "yes")
+ (and (eq_attr "is_strongarm" "no")
+ (eq_attr "type" "mult"))))
+ "core*4")
+
+(define_insn_reservation "multi_cycle" 32
+ (and (eq_attr "generic_sched" "yes")
+ (and (eq_attr "core_cycles" "multi")
+ (eq_attr "type" "!mult,load_byte,load1,load2,load3,load4,store1,store2,store3,store4")))
+ "core*32")
+
+(define_insn_reservation "single_cycle" 1
+ (and (eq_attr "generic_sched" "yes")
+ (eq_attr "core_cycles" "single"))
+ "core")
diff --git a/gcc/config/arm/arm1026ejs.md b/gcc/config/arm/arm1026ejs.md
new file mode 100644
index 00000000000..77f8fde2ccf
--- /dev/null
+++ b/gcc/config/arm/arm1026ejs.md
@@ -0,0 +1,241 @@
+;; ARM 1026EJ-S Pipeline Description
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Written by CodeSourcery, LLC.
+;;
+;; 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 descriptions are based on the information contained in the
+;; ARM1026EJ-S Technical Reference Manual, Copyright (c) 2003 ARM
+;; Limited.
+;;
+
+;; This automaton provides a pipeline description for the ARM
+;; 1026EJ-S core.
+;;
+;; The model given here assumes that the condition for all conditional
+;; instructions is "true", i.e., that all of the instructions are
+;; actually executed.
+
+(define_automaton "arm1026ejs")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Pipelines
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; There are two pipelines:
+;;
+;; - An Arithmetic Logic Unit (ALU) pipeline.
+;;
+;; The ALU pipeline has fetch, issue, decode, execute, memory, and
+;; write stages. We only need to model the execute, memory and write
+;; stages.
+;;
+;; - A Load-Store Unit (LSU) pipeline.
+;;
+;; The LSU pipeline has decode, execute, memory, and write stages.
+;; We only model the execute, memory and write stages.
+
+(define_cpu_unit "a_e,a_m,a_w" "arm1026ejs")
+(define_cpu_unit "l_e,l_m,l_w" "arm1026ejs")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ALU Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; ALU instructions require three cycles to execute, and use the ALU
+;; pipeline in each of the three stages. The results are available
+;; after the execute stage stage has finished.
+;;
+;; If the destination register is the PC, the pipelines are stalled
+;; for several cycles. That case is not modeled here.
+
+;; ALU operations with no shifted operand
+(define_insn_reservation "alu_op" 1
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "alu"))
+ "a_e,a_m,a_w")
+
+;; ALU operations with a shift-by-constant operand
+(define_insn_reservation "alu_shift_op" 1
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "alu_shift"))
+ "a_e,a_m,a_w")
+
+;; ALU operations with a shift-by-register operand
+;; These really stall in the decoder, in order to read
+;; the shift value in a second cycle. Pretend we take two cycles in
+;; the execute stage.
+(define_insn_reservation "alu_shift_reg_op" 2
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "alu_shift_reg"))
+ "a_e*2,a_m,a_w")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Multiplication Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Multiplication instructions loop in the execute stage until the
+;; instruction has been passed through the multiplier array enough
+;; times.
+
+;; The result of the "smul" and "smulw" instructions is not available
+;; until after the memory stage.
+(define_insn_reservation "mult1" 2
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "insn" "smulxy,smulwy"))
+ "a_e,a_m,a_w")
+
+;; The "smlaxy" and "smlawx" instructions require two iterations through
+;; the execute stage; the result is available immediately following
+;; the execute stage.
+(define_insn_reservation "mult2" 2
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "insn" "smlaxy,smlalxy,smlawx"))
+ "a_e*2,a_m,a_w")
+
+;; The "smlalxy", "mul", and "mla" instructions require two iterations
+;; through the execute stage; the result is not available until after
+;; the memory stage.
+(define_insn_reservation "mult3" 3
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "insn" "smlalxy,mul,mla"))
+ "a_e*2,a_m,a_w")
+
+;; The "muls" and "mlas" instructions loop in the execute stage for
+;; four iterations in order to set the flags. The value result is
+;; available after three iterations.
+(define_insn_reservation "mult4" 3
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "insn" "muls,mlas"))
+ "a_e*4,a_m,a_w")
+
+;; Long multiply instructions that produce two registers of
+;; output (such as umull) make their results available in two cycles;
+;; the least significant word is available before the most significant
+;; word. That fact is not modeled; instead, the instructions are
+;; described.as if the entire result was available at the end of the
+;; cycle in which both words are available.
+
+;; The "umull", "umlal", "smull", and "smlal" instructions all take
+;; three iterations through the execute cycle, and make their results
+;; available after the memory cycle.
+(define_insn_reservation "mult5" 4
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "insn" "umull,umlal,smull,smlal"))
+ "a_e*3,a_m,a_w")
+
+;; The "umulls", "umlals", "smulls", and "smlals" instructions loop in
+;; the execute stage for five iterations in order to set the flags.
+;; The value result is available after four iterations.
+(define_insn_reservation "mult6" 4
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "insn" "umulls,umlals,smulls,smlals"))
+ "a_e*5,a_m,a_w")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Load/Store Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; The models for load/store instructions do not accurately describe
+;; the difference between operations with a base register writeback
+;; (such as "ldm!"). These models assume that all memory references
+;; hit in dcache.
+
+;; LSU instructions require six cycles to execute. They use the ALU
+;; pipeline in all but the 5th cycle, and the LSU pipeline in cycles
+;; three through six.
+;; Loads and stores which use a scaled register offset or scaled
+;; register pre-indexed addressing mode take three cycles EXCEPT for
+;; those that are base + offset with LSL of 0 or 2, or base - offset
+;; with LSL of zero. The remainder take 1 cycle to execute.
+;; For 4byte loads there is a bypass from the load stage
+
+(define_insn_reservation "load1_op" 2
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "load_byte,load1"))
+ "a_e+l_e,l_m,a_w+l_w")
+
+(define_insn_reservation "store1_op" 0
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "store1"))
+ "a_e+l_e,l_m,a_w+l_w")
+
+;; A load's result can be stored by an immediately following store
+(define_bypass 1 "load1_op" "store1_op" "arm_no_early_store_addr_dep")
+
+;; On a LDM/STM operation, the LSU pipeline iterates until all of the
+;; registers have been processed.
+;;
+;; The time it takes to load the data depends on whether or not the
+;; base address is 64-bit aligned; if it is not, an additional cycle
+;; is required. This model assumes that the address is always 64-bit
+;; aligned. Because the processor can load two registers per cycle,
+;; that assumption means that we use the same instruction reservations
+;; for loading 2k and 2k - 1 registers.
+;;
+;; The ALU pipeline is stalled until the completion of the last memory
+;; stage in the LSU pipeline. That is modeled by keeping the ALU
+;; execute stage busy until that point.
+;;
+;; As with ALU operations, if one of the destination registers is the
+;; PC, there are additional stalls; that is not modeled.
+
+(define_insn_reservation "load2_op" 2
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "load2"))
+ "a_e+l_e,l_m,a_w+l_w")
+
+(define_insn_reservation "store2_op" 0
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "store2"))
+ "a_e+l_e,l_m,a_w+l_w")
+
+(define_insn_reservation "load34_op" 3
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "load3,load4"))
+ "a_e+l_e,a_e+l_e+l_m,a_e+l_m,a_w+l_w")
+
+(define_insn_reservation "store34_op" 0
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "store3,store4"))
+ "a_e+l_e,a_e+l_e+l_m,a_e+l_m,a_w+l_w")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Branch and Call Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Branch instructions are difficult to model accurately. The ARM
+;; core can predict most branches. If the branch is predicted
+;; correctly, and predicted early enough, the branch can be completely
+;; eliminated from the instruction stream. Some branches can
+;; therefore appear to require zero cycles to execute. We assume that
+;; all branches are predicted correctly, and that the latency is
+;; therefore the minimum value.
+
+(define_insn_reservation "branch_op" 0
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "branch"))
+ "nothing")
+
+;; The latency for a call is not predictable. Therefore, we use 32 as
+;; roughly equivalent to positive infinity.
+
+(define_insn_reservation "call_op" 32
+ (and (eq_attr "tune" "arm1026ejs")
+ (eq_attr "type" "call"))
+ "nothing")
diff --git a/gcc/config/arm/arm1136jfs.md b/gcc/config/arm/arm1136jfs.md
new file mode 100644
index 00000000000..2c0638c0524
--- /dev/null
+++ b/gcc/config/arm/arm1136jfs.md
@@ -0,0 +1,377 @@
+;; ARM 1136J[F]-S Pipeline Description
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Written by CodeSourcery, LLC.
+;;
+;; 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 descriptions are based on the information contained in the
+;; ARM1136JF-S Technical Reference Manual, Copyright (c) 2003 ARM
+;; Limited.
+;;
+
+;; This automaton provides a pipeline description for the ARM
+;; 1136J-S and 1136JF-S cores.
+;;
+;; The model given here assumes that the condition for all conditional
+;; instructions is "true", i.e., that all of the instructions are
+;; actually executed.
+
+(define_automaton "arm1136jfs")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Pipelines
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; There are three distinct pipelines (page 1-26 and following):
+;;
+;; - A 4-stage decode pipeline, shared by all three. It has fetch (1),
+;; fetch (2), decode, and issue stages. Since this is always involved,
+;; we do not model it in the scheduler.
+;;
+;; - A 4-stage ALU pipeline. It has shifter, ALU (main integer operations),
+;; and saturation stages. The fourth stage is writeback; see below.
+;;
+;; - A 4-stage multiply-accumulate pipeline. It has three stages, called
+;; MAC1 through MAC3, and a fourth writeback stage.
+;;
+;; The 4th-stage writeback is shared between the ALU and MAC pipelines,
+;; which operate in lockstep. Results from either pipeline will be
+;; moved into the writeback stage. Because the two pipelines operate
+;; in lockstep, we schedule them as a single "execute" pipeline.
+;;
+;; - A 4-stage LSU pipeline. It has address generation, data cache (1),
+;; data cache (2), and writeback stages. (Note that this pipeline,
+;; including the writeback stage, is independent from the ALU & LSU pipes.)
+
+(define_cpu_unit "e_1,e_2,e_3,e_wb" "arm1136jfs") ; ALU and MAC
+; e_1 = Sh/Mac1, e_2 = ALU/Mac2, e_3 = SAT/Mac3
+(define_cpu_unit "l_a,l_dc1,l_dc2,l_wb" "arm1136jfs") ; Load/Store
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ALU Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; ALU instructions require eight cycles to execute, and use the ALU
+;; pipeline in each of the eight stages. The results are available
+;; after the alu stage has finished.
+;;
+;; If the destination register is the PC, the pipelines are stalled
+;; for several cycles. That case is not modelled here.
+
+;; ALU operations with no shifted operand
+(define_insn_reservation "11_alu_op" 2
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "alu"))
+ "e_1,e_2,e_3,e_wb")
+
+;; ALU operations with a shift-by-constant operand
+(define_insn_reservation "11_alu_shift_op" 2
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "alu_shift"))
+ "e_1,e_2,e_3,e_wb")
+
+;; ALU operations with a shift-by-register operand
+;; These really stall in the decoder, in order to read
+;; the shift value in a second cycle. Pretend we take two cycles in
+;; the shift stage.
+(define_insn_reservation "11_alu_shift_reg_op" 3
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "alu_shift_reg"))
+ "e_1*2,e_2,e_3,e_wb")
+
+;; alu_ops can start sooner, if there is no shifter dependency
+(define_bypass 1 "11_alu_op,11_alu_shift_op"
+ "11_alu_op")
+(define_bypass 1 "11_alu_op,11_alu_shift_op"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 1 "11_alu_op,11_alu_shift_op"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+(define_bypass 2 "11_alu_shift_reg_op"
+ "11_alu_op")
+(define_bypass 2 "11_alu_shift_reg_op"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 2 "11_alu_shift_reg_op"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+
+(define_bypass 1 "11_alu_op,11_alu_shift_op"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 2 "11_alu_shift_reg_op"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Multiplication Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Multiplication instructions loop in the first two execute stages until
+;; the instruction has been passed through the multiplier array enough
+;; times.
+
+;; Multiply and multiply-accumulate results are available after four stages.
+(define_insn_reservation "11_mult1" 4
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "mul,mla"))
+ "e_1*2,e_2,e_3,e_wb")
+
+;; The *S variants set the condition flags, which requires three more cycles.
+(define_insn_reservation "11_mult2" 4
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "muls,mlas"))
+ "e_1*2,e_2,e_3,e_wb")
+
+(define_bypass 3 "11_mult1,11_mult2"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 3 "11_mult1,11_mult2"
+ "11_alu_op")
+(define_bypass 3 "11_mult1,11_mult2"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 3 "11_mult1,11_mult2"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+(define_bypass 3 "11_mult1,11_mult2"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+
+;; Signed and unsigned multiply long results are available across two cycles;
+;; the less significant word is available one cycle before the more significant
+;; word. Here we conservatively wait until both are available, which is
+;; after three iterations and the memory cycle. The same is also true of
+;; the two multiply-accumulate instructions.
+(define_insn_reservation "11_mult3" 5
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "smull,umull,smlal,umlal"))
+ "e_1*3,e_2,e_3,e_wb*2")
+
+;; The *S variants set the condition flags, which requires three more cycles.
+(define_insn_reservation "11_mult4" 5
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "smulls,umulls,smlals,umlals"))
+ "e_1*3,e_2,e_3,e_wb*2")
+
+(define_bypass 4 "11_mult3,11_mult4"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 4 "11_mult3,11_mult4"
+ "11_alu_op")
+(define_bypass 4 "11_mult3,11_mult4"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 4 "11_mult3,11_mult4"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+(define_bypass 4 "11_mult3,11_mult4"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+
+;; Various 16x16->32 multiplies and multiply-accumulates, using combinations
+;; of high and low halves of the argument registers. They take a single
+;; pass through the pipeline and make the result available after three
+;; cycles.
+(define_insn_reservation "11_mult5" 3
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "smulxy,smlaxy,smulwy,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx"))
+ "e_1,e_2,e_3,e_wb")
+
+(define_bypass 2 "11_mult5"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 2 "11_mult5"
+ "11_alu_op")
+(define_bypass 2 "11_mult5"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 2 "11_mult5"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+(define_bypass 2 "11_mult5"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+
+;; The same idea, then the 32-bit result is added to a 64-bit quantity.
+(define_insn_reservation "11_mult6" 4
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "smlalxy"))
+ "e_1*2,e_2,e_3,e_wb*2")
+
+;; Signed 32x32 multiply, then the most significant 32 bits are extracted
+;; and are available after the memory stage.
+(define_insn_reservation "11_mult7" 4
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "insn" "smmul,smmulr"))
+ "e_1*2,e_2,e_3,e_wb")
+
+(define_bypass 3 "11_mult6,11_mult7"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 3 "11_mult6,11_mult7"
+ "11_alu_op")
+(define_bypass 3 "11_mult6,11_mult7"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 3 "11_mult6,11_mult7"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+(define_bypass 3 "11_mult6,11_mult7"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Branch Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; These vary greatly depending on their arguments and the results of
+;; stat prediction. Cycle count ranges from zero (unconditional branch,
+;; folded dynamic prediction) to seven (incorrect predictions, etc). We
+;; assume an optimal case for now, because the cost of a cache miss
+;; overwhelms the cost of everything else anyhow.
+
+(define_insn_reservation "11_branches" 0
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "branch"))
+ "nothing")
+
+;; Call latencies are not predictable. A semi-arbitrary very large
+;; number is used as "positive infinity" so that everything should be
+;; finished by the time of return.
+(define_insn_reservation "11_call" 32
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "call"))
+ "nothing")
+
+;; Branches are predicted. A correctly predicted branch will be no
+;; cost, but we're conservative here, and use the timings a
+;; late-register would give us.
+(define_bypass 1 "11_alu_op,11_alu_shift_op"
+ "11_branches")
+(define_bypass 2 "11_alu_shift_reg_op"
+ "11_branches")
+(define_bypass 2 "11_load1,11_load2"
+ "11_branches")
+(define_bypass 3 "11_load34"
+ "11_branches")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Load/Store Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; The models for load/store instructions do not accurately describe
+;; the difference between operations with a base register writeback.
+;; These models assume that all memory references hit in dcache. Also,
+;; if the PC is one of the registers involved, there are additional stalls
+;; not modelled here. Addressing modes are also not modelled.
+
+(define_insn_reservation "11_load1" 3
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "load1"))
+ "l_a+e_1,l_dc1,l_dc2,l_wb")
+
+;; Load byte results are not available until the writeback stage, where
+;; the correct byte is extracted.
+
+(define_insn_reservation "11_loadb" 4
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "load_byte"))
+ "l_a+e_1,l_dc1,l_dc2,l_wb")
+
+(define_insn_reservation "11_store1" 0
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "store1"))
+ "l_a+e_1,l_dc1,l_dc2,l_wb")
+
+;; Load/store double words into adjacent registers. The timing and
+;; latencies are different depending on whether the address is 64-bit
+;; aligned. This model assumes that it is.
+(define_insn_reservation "11_load2" 3
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "load2"))
+ "l_a+e_1,l_dc1,l_dc2,l_wb")
+
+(define_insn_reservation "11_store2" 0
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "store2"))
+ "l_a+e_1,l_dc1,l_dc2,l_wb")
+
+;; Load/store multiple registers. Two registers are stored per cycle.
+;; Actual timing depends on how many registers are affected, so we
+;; optimistically schedule a low latency.
+(define_insn_reservation "11_load34" 4
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "load3,load4"))
+ "l_a+e_1,l_dc1*2,l_dc2,l_wb")
+
+(define_insn_reservation "11_store34" 0
+ (and (eq_attr "tune" "arm1136js,arm1136jfs")
+ (eq_attr "type" "store3,store4"))
+ "l_a+e_1,l_dc1*2,l_dc2,l_wb")
+
+;; A store can start immediately after an alu op, if that alu op does
+;; not provide part of the address to access.
+(define_bypass 1 "11_alu_op,11_alu_shift_op"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+(define_bypass 2 "11_alu_shift_reg_op"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+
+;; An alu op can start sooner after a load, if that alu op does not
+;; have an early register dependency on the load
+(define_bypass 2 "11_load1"
+ "11_alu_op")
+(define_bypass 2 "11_load1"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 2 "11_load1"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+
+(define_bypass 3 "11_loadb"
+ "11_alu_op")
+(define_bypass 3 "11_loadb"
+ "11_alu_shift_op"
+ "arm_no_early_alu_shift_value_dep")
+(define_bypass 3 "11_loadb"
+ "11_alu_shift_reg_op"
+ "arm_no_early_alu_shift_dep")
+
+;; A mul op can start sooner after a load, if that mul op does not
+;; have an early multiply dependency
+(define_bypass 2 "11_load1"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 3 "11_load34"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+(define_bypass 3 "11_loadb"
+ "11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
+ "arm_no_early_mul_dep")
+
+;; A store can start sooner after a load, if that load does not
+;; produce part of the address to access
+(define_bypass 2 "11_load1"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
+(define_bypass 3 "11_loadb"
+ "11_store1"
+ "arm_no_early_store_addr_dep")
diff --git a/gcc/config/arm/arm926ejs.md b/gcc/config/arm/arm926ejs.md
new file mode 100644
index 00000000000..258495b7f06
--- /dev/null
+++ b/gcc/config/arm/arm926ejs.md
@@ -0,0 +1,188 @@
+;; ARM 926EJ-S Pipeline Description
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Written by CodeSourcery, LLC.
+;;
+;; 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 descriptions are based on the information contained in the
+;; ARM926EJ-S Technical Reference Manual, Copyright (c) 2002 ARM
+;; Limited.
+;;
+
+;; This automaton provides a pipeline description for the ARM
+;; 926EJ-S core.
+;;
+;; The model given here assumes that the condition for all conditional
+;; instructions is "true", i.e., that all of the instructions are
+;; actually executed.
+
+(define_automaton "arm926ejs")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Pipelines
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; There is a single pipeline
+;;
+;; The ALU pipeline has fetch, decode, execute, memory, and
+;; write stages. We only need to model the execute, memory and write
+;; stages.
+
+(define_cpu_unit "e,m,w" "arm926ejs")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ALU Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; ALU instructions require three cycles to execute, and use the ALU
+;; pipeline in each of the three stages. The results are available
+;; after the execute stage stage has finished.
+;;
+;; If the destination register is the PC, the pipelines are stalled
+;; for several cycles. That case is not modeled here.
+
+;; ALU operations with no shifted operand
+(define_insn_reservation "9_alu_op" 1
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "alu,alu_shift"))
+ "e,m,w")
+
+;; ALU operations with a shift-by-register operand
+;; These really stall in the decoder, in order to read
+;; the shift value in a second cycle. Pretend we take two cycles in
+;; the execute stage.
+(define_insn_reservation "9_alu_shift_reg_op" 2
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "alu_shift_reg"))
+ "e*2,m,w")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Multiplication Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Multiplication instructions loop in the execute stage until the
+;; instruction has been passed through the multiplier array enough
+;; times. Multiply operations occur in both the execute and memory
+;; stages of the pipeline
+
+(define_insn_reservation "9_mult1" 3
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "insn" "smlalxy,mul,mla"))
+ "e*2,m,w")
+
+(define_insn_reservation "9_mult2" 4
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "insn" "muls,mlas"))
+ "e*3,m,w")
+
+(define_insn_reservation "9_mult3" 4
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "insn" "umull,umlal,smull,smlal"))
+ "e*3,m,w")
+
+(define_insn_reservation "9_mult4" 5
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "insn" "umulls,umlals,smulls,smlals"))
+ "e*4,m,w")
+
+(define_insn_reservation "9_mult5" 2
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "insn" "smulxy,smlaxy,smlawx"))
+ "e,m,w")
+
+(define_insn_reservation "9_mult6" 3
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "insn" "smlalxy"))
+ "e*2,m,w")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Load/Store Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; The models for load/store instructions do not accurately describe
+;; the difference between operations with a base register writeback
+;; (such as "ldm!"). These models assume that all memory references
+;; hit in dcache.
+
+;; Loads with a shifted offset take 3 cycles, and are (a) probably the
+;; most common and (b) the pessimistic assumption will lead to fewer stalls.
+(define_insn_reservation "9_load1_op" 3
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "load1,load_byte"))
+ "e*2,m,w")
+
+(define_insn_reservation "9_store1_op" 0
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "store1"))
+ "e,m,w")
+
+;; multiple word loads and stores
+(define_insn_reservation "9_load2_op" 3
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "load2"))
+ "e,m*2,w")
+
+(define_insn_reservation "9_load3_op" 4
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "load3"))
+ "e,m*3,w")
+
+(define_insn_reservation "9_load4_op" 5
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "load4"))
+ "e,m*4,w")
+
+(define_insn_reservation "9_store2_op" 0
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "store2"))
+ "e,m*2,w")
+
+(define_insn_reservation "9_store3_op" 0
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "store3"))
+ "e,m*3,w")
+
+(define_insn_reservation "9_store4_op" 0
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "store4"))
+ "e,m*4,w")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Branch and Call Instructions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Branch instructions are difficult to model accurately. The ARM
+;; core can predict most branches. If the branch is predicted
+;; correctly, and predicted early enough, the branch can be completely
+;; eliminated from the instruction stream. Some branches can
+;; therefore appear to require zero cycles to execute. We assume that
+;; all branches are predicted correctly, and that the latency is
+;; therefore the minimum value.
+
+(define_insn_reservation "9_branch_op" 0
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "branch"))
+ "nothing")
+
+;; The latency for a call is not predictable. Therefore, we use 32 as
+;; roughly equivalent to positive infinity.
+
+(define_insn_reservation "9_call_op" 32
+ (and (eq_attr "tune" "arm926ejs")
+ (eq_attr "type" "call"))
+ "nothing")
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
new file mode 100644
index 00000000000..7008ab40c76
--- /dev/null
+++ b/gcc/config/arm/vfp.md
@@ -0,0 +1,781 @@
+;; ARM VFP coprocessor Machine Description
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Written by CodeSourcery, LLC.
+;;
+;; 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. */
+
+;; Additional register numbers
+(define_constants
+ [(VFPCC_REGNUM 95)]
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Pipeline description
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define_automaton "vfp11")
+
+;; There are 3 pipelines in the VFP11 unit.
+;;
+;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
+;; fourth stage for simple operations.
+;;
+;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
+;; These insns also uses first execute stage of FMAC pipeline.
+;;
+;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
+;; second memory stage for loads.
+
+;; We do not model Write-After-Read hazards.
+;; We do not do write scheduling with the arm core, so it is only necessary
+;; to model the first stage of each pipeline
+;; ??? Need to model LS pipeline properly for load/store multiple?
+;; We do not model fmstat properly. This could be done by modeling pipelines
+;; properly and defining an absence set between a dummy fmstat unit and all
+;; other vfp units.
+
+(define_cpu_unit "fmac" "vfp11")
+
+(define_cpu_unit "ds" "vfp11")
+
+(define_cpu_unit "vfp_ls" "vfp11")
+
+;; The VFP "type" attributes differ from those used in the FPA model.
+;; ffarith Fast floating point insns, eg. abs, neg, cpy, cmp.
+;; farith Most arithmetic insns.
+;; fmul Double precision multiply.
+;; fdivs Single precision sqrt or division.
+;; fdivd Double precision sqrt or division.
+;; f_load Floating point load from memory.
+;; f_store Floating point store to memory.
+;; f_2_r Transfer vfp to arm reg.
+;; r_2_f Transfer arm to vfp reg.
+
+(define_insn_reservation "vfp_ffarith" 4
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "ffarith"))
+ "fmac")
+
+(define_insn_reservation "vfp_farith" 8
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "farith"))
+ "fmac")
+
+(define_insn_reservation "vfp_fmul" 9
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "fmul"))
+ "fmac*2")
+
+(define_insn_reservation "vfp_fdivs" 19
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "fdivs"))
+ "ds*15")
+
+(define_insn_reservation "vfp_fdivd" 33
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "fdivd"))
+ "fmac+ds*29")
+
+;; Moves to/from arm regs also use the load/store pipeline.
+(define_insn_reservation "vfp_fload" 4
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "f_load,r_2_f"))
+ "vfp_ls")
+
+(define_insn_reservation "vfp_fstore" 4
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "type" "f_load,f_2_r"))
+ "vfp_ls")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Insn pattern
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; SImode moves
+;; ??? For now do not allow loading constants into vfp regs. This causes
+;; problems because small constants get converted into adds.
+(define_insn "*arm_movsi_vfp"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w, Uv")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,!w,!w,Uvi,!w"))]
+ "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
+ && ( s_register_operand (operands[0], SImode)
+ || s_register_operand (operands[1], SImode))"
+ "@
+ mov%?\\t%0, %1
+ mvn%?\\t%0, #%B1
+ ldr%?\\t%0, %1
+ str%?\\t%1, %0
+ fmsr%?\\t%0, %1\\t%@ int
+ fmrs%?\\t%0, %1\\t%@ int
+ fcpys%?\\t%0, %1\\t%@ int
+ flds%?\\t%0, %1\\t%@ int
+ fsts%?\\t%1, %0\\t%@ int"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
+ (set_attr "pool_range" "*,*,4096,*,*,*,*,1020,*")
+ (set_attr "neg_pool_range" "*,*,4084,*,*,*,*,1008,*")]
+)
+
+
+;; DImode moves
+
+(define_insn "*arm_movdi_vfp"
+ [(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)
+ {
+ case 0: case 1: case 2:
+ return (output_move_double (operands));
+ case 3:
+ return \"fmdrr%?\\t%P0, %1\\t%@ int\";
+ case 4:
+ return \"fmrrd%?\\t%0, %1\\t%@ int\";
+ case 5:
+ return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
+ case 6:
+ return \"fldd%?\\t%P0, %1\\t%@ int\";
+ case 7:
+ return \"fstd%?\\t%P1, %0\\t%@ int\";
+ default:
+ abort ();
+ }
+ "
+ [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
+ (set_attr "length" "8,8,8,4,4,4,4,4")
+ (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
+ (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
+)
+
+
+;; SFmode moves
+
+(define_insn "*movsf_vfp"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
+ (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
+ && ( s_register_operand (operands[0], SFmode)
+ || s_register_operand (operands[1], SFmode))"
+ "@
+ fmsr%?\\t%0, %1
+ fmrs%?\\t%0, %1
+ flds%?\\t%0, %1
+ fsts%?\\t%1, %0
+ ldr%?\\t%0, %1\\t%@ float
+ str%?\\t%1, %0\\t%@ float
+ fcpys%?\\t%0, %1
+ mov%?\\t%0, %1\\t%@ float"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_load,f_store,load1,store1")
+ (set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
+ (set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
+)
+
+
+;; DFmode moves
+
+(define_insn "*movdf_vfp"
+ [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
+ (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ return \"fmdrr%?\\t%P0, %Q1, %R1\";
+ case 1:
+ return \"fmrrd%?\\t%Q0, %R0, %P1\";
+ case 2: case 3: case 7:
+ return output_move_double (operands);
+ case 4:
+ return \"fldd%?\\t%P0, %1\";
+ case 5:
+ return \"fstd%?\\t%P1, %0\";
+ case 6:
+ return \"fcpyd%?\\t%P0, %P1\";
+ default:
+ abort ();
+ }
+ }
+ "
+ [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_load,f_store")
+ (set_attr "length" "4,4,8,8,4,4,4,8")
+ (set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
+ (set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
+)
+
+
+;; Conditional move patterns
+
+(define_insn "*movsfcc_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
+ (if_then_else:SF
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand 4 "cc_register" "") (const_int 0)])
+ (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
+ (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "@
+ fcpys%D3\\t%0, %2
+ fcpys%d3\\t%0, %1
+ fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
+ fmsr%D3\\t%0, %2
+ fmsr%d3\\t%0, %1
+ fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
+ fmrs%D3\\t%0, %2
+ fmrs%d3\\t%0, %1
+ fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
+ [(set_attr "conds" "use")
+ (set_attr "length" "4,4,8,4,4,8,4,4,8")
+ (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
+)
+
+(define_insn "*movdfcc_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
+ (if_then_else:DF
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand 4 "cc_register" "") (const_int 0)])
+ (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
+ (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "@
+ fcpyd%D3\\t%P0, %P2
+ fcpyd%d3\\t%P0, %P1
+ fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
+ fmdrr%D3\\t%P0, %Q2, %R2
+ fmdrr%d3\\t%P0, %Q1, %R1
+ fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
+ fmrrd%D3\\t%Q0, %R0, %P2
+ fmrrd%d3\\t%Q0, %R0, %P1
+ fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
+ [(set_attr "conds" "use")
+ (set_attr "length" "4,4,8,4,4,8,4,4,8")
+ (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
+)
+
+
+;; Sign manipulation functions
+
+(define_insn "*abssf2_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fabss%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn "*absdf2_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fabsd%?\\t%P0, %P1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn "*negsf2_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "+w")
+ (neg:SF (match_operand:SF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnegs%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn "*negdf2_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "+w")
+ (neg:DF (match_operand:DF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnegd%?\\t%P0, %P1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+
+;; Arithmetic insns
+
+(define_insn "*addsf3_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (plus:SF (match_operand:SF 1 "s_register_operand" "w")
+ (match_operand:SF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fadds%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*adddf3_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "w")
+ (match_operand:DF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "faddd%?\\t%P0, %P1, %P2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+
+(define_insn "*subsf3_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (minus:SF (match_operand:SF 1 "s_register_operand" "w")
+ (match_operand:SF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fsubs%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*subdf3_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (minus:DF (match_operand:DF 1 "s_register_operand" "w")
+ (match_operand:DF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fsubd%?\\t%P0, %P1, %P2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+
+;; Division insns
+
+(define_insn "*divsf3_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "+w")
+ (div:SF (match_operand:SF 1 "s_register_operand" "w")
+ (match_operand:SF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fdivs%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fdivs")]
+)
+
+(define_insn "*divdf3_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "+w")
+ (div:DF (match_operand:DF 1 "s_register_operand" "w")
+ (match_operand:DF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fdivd%?\\t%P0, %P1, %P2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fdivd")]
+)
+
+
+;; Multiplication insns
+
+(define_insn "*mulsf3_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "+w")
+ (mult:SF (match_operand:SF 1 "s_register_operand" "w")
+ (match_operand:SF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmuls%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*muldf3_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "+w")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "w")
+ (match_operand:DF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmuld%?\\t%P0, %P1, %P2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fmul")]
+)
+
+
+(define_insn "*mulsf3negsf_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "+w")
+ (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
+ (match_operand:SF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnmuls%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*muldf3negdf_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "+w")
+ (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
+ (match_operand:DF 2 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnmuld%?\\t%P0, %P1, %P2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fmul")]
+)
+
+
+;; Multiply-accumulate insns
+
+;; 0 = 1 * 2 + 0
+(define_insn "*mulsf3addsf_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
+ (match_operand:SF 3 "s_register_operand" "w"))
+ (match_operand:SF 1 "s_register_operand" "0")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmacs%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*muldf3adddf_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
+ (match_operand:DF 3 "s_register_operand" "w"))
+ (match_operand:DF 1 "s_register_operand" "0")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmacd%?\\t%P0, %P2, %P3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fmul")]
+)
+
+;; 0 = 1 * 2 - 0
+(define_insn "*mulsf3subsf_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
+ (match_operand:SF 3 "s_register_operand" "w"))
+ (match_operand:SF 1 "s_register_operand" "0")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmscs%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*muldf3subdf_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
+ (match_operand:DF 3 "s_register_operand" "w"))
+ (match_operand:DF 1 "s_register_operand" "0")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmscd%?\\t%P0, %P2, %P3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fmul")]
+)
+
+;; 0 = -(1 * 2) + 0
+(define_insn "*mulsf3negsfaddsf_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (minus:SF (match_operand:SF 1 "s_register_operand" "0")
+ (mult:SF (match_operand:SF 2 "s_register_operand" "w")
+ (match_operand:SF 3 "s_register_operand" "w"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnmacs%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*fmuldf3negdfadddf_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (minus:DF (match_operand:DF 1 "s_register_operand" "0")
+ (mult:DF (match_operand:DF 2 "s_register_operand" "w")
+ (match_operand:DF 3 "s_register_operand" "w"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnmacd%?\\t%P0, %P2, %P3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fmul")]
+)
+
+
+;; 0 = -(1 * 2) - 0
+(define_insn "*mulsf3negsfsubsf_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (minus:SF (mult:SF
+ (neg:SF (match_operand:SF 2 "s_register_operand" "w"))
+ (match_operand:SF 3 "s_register_operand" "w"))
+ (match_operand:SF 1 "s_register_operand" "0")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnmscs%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*muldf3negdfsubdf_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (minus:DF (mult:DF
+ (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
+ (match_operand:DF 3 "s_register_operand" "w"))
+ (match_operand:DF 1 "s_register_operand" "0")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fnmscd%?\\t%P0, %P2, %P3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fmul")]
+)
+
+
+;; Conversion routines
+
+(define_insn "*extendsfdf2_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fcvtds%?\\t%P0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*truncdfsf2_vfp"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fcvtsd%?\\t%0, %P1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*truncsisf2_vfp"
+ [(set (match_operand:SI 0 "s_register_operand" "=w")
+ (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "ftosizs%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*truncsidf2_vfp"
+ [(set (match_operand:SI 0 "s_register_operand" "=w")
+ (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "ftosizd%?\\t%0, %P1"
+ [(set_attr "predicable" "yes")
+ (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")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fsitos%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "*floatsidf2_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (float:DF (match_operand:SI 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fsitod%?\\t%P0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+
+(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"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fsqrts%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fdivs")]
+)
+
+(define_insn "*sqrtdf2_vfp"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fsqrtd%?\\t%P0, %P1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "fdivd")]
+)
+
+
+;; Patterns to split/copy vfp condition flags.
+
+(define_insn "*movcc_vfp"
+ [(set (reg CC_REGNUM)
+ (reg VFPCC_REGNUM))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fmstat%?"
+ [(set_attr "conds" "set")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn_and_split "*cmpsf_split_vfp"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
+ (match_operand:SF 1 "vfp_compare_operand" "wG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "#"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ [(set (reg:CCFP VFPCC_REGNUM)
+ (compare:CCFP (match_dup 0)
+ (match_dup 1)))
+ (set (reg:CCFP CC_REGNUM)
+ (reg:CCFP VFPCC_REGNUM))]
+ ""
+)
+
+(define_insn_and_split "*cmpsf_trap_split_vfp"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
+ (match_operand:SF 1 "vfp_compare_operand" "wG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "#"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ [(set (reg:CCFPE VFPCC_REGNUM)
+ (compare:CCFPE (match_dup 0)
+ (match_dup 1)))
+ (set (reg:CCFPE CC_REGNUM)
+ (reg:CCFPE VFPCC_REGNUM))]
+ ""
+)
+
+(define_insn_and_split "*cmpdf_split_vfp"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
+ (match_operand:DF 1 "vfp_compare_operand" "wG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "#"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ [(set (reg:CCFP VFPCC_REGNUM)
+ (compare:CCFP (match_dup 0)
+ (match_dup 1)))
+ (set (reg:CCFP CC_REGNUM)
+ (reg:CCFPE VFPCC_REGNUM))]
+ ""
+)
+
+(define_insn_and_split "*cmpdf_trap_split_vfp"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
+ (match_operand:DF 1 "vfp_compare_operand" "wG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "#"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ [(set (reg:CCFPE VFPCC_REGNUM)
+ (compare:CCFPE (match_dup 0)
+ (match_dup 1)))
+ (set (reg:CCFPE CC_REGNUM)
+ (reg:CCFPE VFPCC_REGNUM))]
+ ""
+)
+
+
+;; Comparison patterns
+
+(define_insn "*cmpsf_vfp"
+ [(set (reg:CCFP VFPCC_REGNUM)
+ (compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
+ (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "@
+ fcmps%?\\t%0, %1
+ fcmpzs%?\\t%0"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn "*cmpsf_trap_vfp"
+ [(set (reg:CCFPE VFPCC_REGNUM)
+ (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
+ (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "@
+ fcmpes%?\\t%0, %1
+ fcmpezs%?\\t%0"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn "*cmpdf_vfp"
+ [(set (reg:CCFP VFPCC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
+ (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "@
+ fcmpd%?\\t%P0, %P1
+ fcmpzd%?\\t%P0"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+(define_insn "*cmpdf_trap_vfp"
+ [(set (reg:CCFPE VFPCC_REGNUM)
+ (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
+ (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "@
+ fcmped%?\\t%P0, %P1
+ fcmpezd%?\\t%P0"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "ffarith")]
+)
+
+
+;; Store multiple insn used in function prologue.
+
+(define_insn "*push_multi_vfp"
+ [(match_parallel 2 "multi_register_push"
+ [(set (match_operand:BLK 0 "memory_operand" "=m")
+ (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
+ UNSPEC_PUSH_MULT))])]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "* return vfp_output_fstmx (operands);"
+ [(set_attr "type" "f_store")]
+)
+
+
+;; Unimplemented insns:
+;; fldm*
+;; fstm*
+;; fmdhr et al (VFPv1)
+;; Support for xD (single precision only) variants.
+;; fmrrs, fmsrr
diff --git a/gcc/config/darwin7.h b/gcc/config/darwin7.h
new file mode 100644
index 00000000000..47a8fa19222
--- /dev/null
+++ b/gcc/config/darwin7.h
@@ -0,0 +1,29 @@
+/* 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
+
+/* Machine dependent libraries, include libmx when compiling on Darwin 7.0
+ and above. */
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!static:-lSystem -lmx}"
diff --git a/gcc/config/frv/libgcc-frv.ver b/gcc/config/frv/libgcc-frv.ver
new file mode 100644
index 00000000000..2aae3db9c79
--- /dev/null
+++ b/gcc/config/frv/libgcc-frv.ver
@@ -0,0 +1,55 @@
+GCC_3.4 {
+ # frv abi symbol names
+ __ftod
+ __ftoi
+ __ftoui
+ __dtoi
+ __ftoui
+ __dtoui
+ __ftoll
+ __dtoll
+ __ftoull
+ __dtoull
+ __itof
+ __lltof
+ __dtof
+ __itod
+ __lltof
+ __lltod
+ __addd
+ __subd
+ __muld
+ __divd
+ __addf
+ __subf
+ __mulf
+ __divf
+ __sllll
+ __srlll
+ __srall
+ __addll
+ __subll
+ __mulll
+ __umulll
+ __divll
+ __udivll
+ __modll
+ __umodll
+ __cmpll
+ __cmpf
+ __cmpd
+ __andll
+ __orll
+ __xorll
+ __notll
+ __cmov
+ __cmovd
+ __cmovh
+ __cmovw
+ __modi
+ __uitod
+ __uitof
+ __ulltod
+ __ulltof
+ __umodi
+}
diff --git a/gcc/config/frv/linux.h b/gcc/config/frv/linux.h
new file mode 100644
index 00000000000..6f0f1b27f67
--- /dev/null
+++ b/gcc/config/frv/linux.h
@@ -0,0 +1,74 @@
+/* Target macros for the FRV Linux port of GCC.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ Contributed by Red Hat 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 __FRV_LINUX_H__
+#define __FRV_LINUX_H__
+
+#undef SUBTARGET_DRIVER_SELF_SPECS
+#define SUBTARGET_DRIVER_SELF_SPECS \
+ "%{!mno-fdpic:-mfdpic}",
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
+
+#undef LINK_SPEC
+#define LINK_SPEC "\
+ %{mfdpic: -m elf32frvfd -z text} %{shared} %{pie} \
+ %{!shared: %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
+ %{static}}"
+
+/* Support for compile-time default CPU. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }
+
+/* Define OS-specific predefined preprocessor macros. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__gnu_linux__"); \
+ builtin_define_std ("linux"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=linux"); \
+ } while (0)
+
+#define HAS_INIT_SECTION 1
+#define INIT_SECTION_ASM_OP "\t.section .init,\"ax\""
+#define FINI_SECTION_ASM_OP "\t.section .fini,\"ax\""
+
+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
+asm (SECTION_OP); \
+asm ("ldi.p @(fp,4), gr15 ! call " #FUNC); \
+asm (TEXT_SECTION_ASM_OP);
+
+#undef INVOKE__main
+
+#undef Twrite
+#define Twrite __write
+
+#endif /* __FRV_LINUX_H__ */
diff --git a/gcc/config/frv/t-linux b/gcc/config/frv/t-linux
new file mode 100644
index 00000000000..298f59b0b4d
--- /dev/null
+++ b/gcc/config/frv/t-linux
@@ -0,0 +1,12 @@
+# We don't want multilibs.
+MULTILIB_OPTIONS=
+MULTILIB_DIRNAMES=
+MULTILIB_MATCHES=
+MULTILIB_EXCEPTIONS=
+MULTILIB_EXTRA_OPTS=
+
+CRTSTUFF_T_CFLAGS = -fPIC
+TARGET_LIBGCC2_CFLAGS = -fPIC
+
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+ $(srcdir)/config/frv/libgcc-frv.ver
diff --git a/gcc/config/h8300/genmova.sh b/gcc/config/h8300/genmova.sh
new file mode 100644
index 00000000000..1988afa512a
--- /dev/null
+++ b/gcc/config/h8300/genmova.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+# Generate mova.md, a file containing patterns that can be implemented
+# using the h8sx mova instruction.
+
+echo ";; -*- buffer-read-only: t -*-"
+echo ";; Generated automatically from genmova.sh"
+
+# Loop over modes for the source operand (the index). Only 8-bit and
+# 16-bit indices are allowed.
+for s in QI HI; do
+
+ # Set $src to the operand syntax for this size of index.
+ case $s in
+ QI) src=%X1.b;;
+ HI) src=%T1.w;;
+ esac
+
+ # A match_operand for the source.
+ operand="(match_operand:$s 1 \"h8300_dst_operand\" \"0,rQ\")"
+
+ # Loop over the destination register's mode. The QI and HI versions use
+ # the same instructions as the SI ones, they just ignore the upper bits
+ # of the result.
+ for d in QI HI SI; do
+
+ # If the destination is larger than the source, include a
+ # zero_extend/plus pattern. We could also match zero extensions
+ # of memory without the plus, but it's not any smaller or faster
+ # than separate insns.
+ case $d:$s in
+ SI:QI | SI:HI | HI:QI)
+ cat <<EOF
+(define_insn ""
+ [(set (match_operand:$d 0 "register_operand" "=r,r")
+ (plus:$d (zero_extend:$d $operand)
+ (match_operand:$d 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/b.l @(%o2,$src),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+EOF
+ ;;
+ esac
+
+ # Loop over the shift amount.
+ for shift in 1 2; do
+ case $shift in
+ 1) opsize=w mult=2;;
+ 2) opsize=l mult=4;;
+ esac
+
+ # Calculate the mask of bits that will be nonzero after the source
+ # has been extended and shifted.
+ case $s:$shift in
+ QI:1) mask=510;;
+ QI:2) mask=1020;;
+ HI:1) mask=131070;;
+ HI:2) mask=262140;;
+ esac
+
+ # There doesn't seem to be a well-established canonical form for
+ # some of the patterns we need. Emit both shift and multiplication
+ # patterns.
+ for form in mult ashift; do
+ case $form in
+ mult) amount=$mult;;
+ ashift) amount=$shift;;
+ esac
+
+ case $d:$s in
+ # If the source and destination are the same size, we can treat
+ # mova as a sort of multiply-add instruction.
+ QI:QI | HI:HI)
+ cat <<EOF
+(define_insn ""
+ [(set (match_operand:$d 0 "register_operand" "=r,r")
+ (plus:$d ($form:$d $operand
+ (const_int $amount))
+ (match_operand:$d 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/$opsize.l @(%o2,$src),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+EOF
+ ;;
+
+ # Handle the cases where the source is smaller than the
+ # destination. Sometimes combine will keep the extension,
+ # sometimes it will use an AND.
+ SI:QI | SI:HI | HI:QI)
+
+ # Emit the forms that use zero_extend.
+ cat <<EOF
+(define_insn ""
+ [(set (match_operand:$d 0 "register_operand" "=r,r")
+ ($form:$d (zero_extend:$d $operand)
+ (const_int $amount)))]
+ "TARGET_H8300SX"
+ "mova/$opsize.l @(0,$src),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:$d 0 "register_operand" "=r,r")
+ (plus:$d ($form:$d (zero_extend:$d $operand)
+ (const_int $amount))
+ (match_operand:$d 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/$opsize.l @(%o2,$src),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+EOF
+
+ # Now emit the forms that use AND. When the index is a register,
+ # these forms are effectively $d-mode operations: the index will
+ # be a $d-mode REG or SUBREG. When the index is a memory
+ # location, we will have a paradoxical subreg such as:
+ #
+ # (and:SI (mult:SI (subreg:SI (mem:QI ...) 0)
+ # (const_int 4))
+ # (const_int 1020))
+ #
+ # Match the two case separately: a $d-mode register_operand
+ # or a $d-mode subreg of an $s-mode memory_operand. Match the
+ # memory form first since register_operand accepts mem subregs
+ # before reload.
+ memory="(match_operand:$s 1 \"memory_operand\" \"m\")"
+ memory="(subreg:$d $memory 0)"
+ register="(match_operand:$d 1 \"register_operand\" \"0\")"
+ for paradoxical in "$memory" "$register"; do
+ cat <<EOF
+(define_insn ""
+ [(set (match_operand:$d 0 "register_operand" "=r")
+ (and:$d ($form:$d $paradoxical
+ (const_int $amount))
+ (const_int $mask)))]
+ "TARGET_H8300SX"
+ "mova/$opsize.l @(0,$src),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:$d 0 "register_operand" "=r")
+ (plus:$d (and:$d ($form:$d $paradoxical
+ (const_int $amount))
+ (const_int $mask))
+ (match_operand:$d 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/$opsize.l @(%o2,$src),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+EOF
+ done
+ ;;
+ esac
+ done
+ done
+ done
+done
diff --git a/gcc/config/h8300/mova.md b/gcc/config/h8300/mova.md
new file mode 100644
index 00000000000..5c4d5d9d911
--- /dev/null
+++ b/gcc/config/h8300/mova.md
@@ -0,0 +1,841 @@
+;; -*- buffer-read-only: t -*-
+;; Generated automatically from genmova.sh
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (plus:QI (mult:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 2))
+ (match_operand:QI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (plus:QI (ashift:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 1))
+ (match_operand:QI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (plus:QI (mult:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 4))
+ (match_operand:QI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (plus:QI (ashift:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 2))
+ (match_operand:QI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/b.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 510))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 510))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 1)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 1))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 1))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 1))
+ (const_int 510))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 1))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 1))
+ (const_int 510))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 4)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 4))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 4))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 4))
+ (const_int 1020))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 4))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 4))
+ (const_int 1020))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 1020))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 1020))
+ (match_operand:HI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/b.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 510))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 510))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 1)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 1))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 1))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 1))
+ (const_int 510))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 1))
+ (const_int 510)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 1))
+ (const_int 510))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 4)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 4))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 4))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 4))
+ (const_int 1020))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 4))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 4))
+ (const_int 1020))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 1020))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 1020)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%X1.b),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 1020))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%X1.b),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (mult:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 2))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (ashift:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 1))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (mult:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 4))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (ashift:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
+ (const_int 2))
+ (match_operand:HI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/b.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 131070)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 131070))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 131070)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 131070))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 1)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 1))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 1))
+ (const_int 131070)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 1))
+ (const_int 131070))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 1))
+ (const_int 131070)))]
+ "TARGET_H8300SX"
+ "mova/w.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 1))
+ (const_int 131070))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/w.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 4)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 4))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 4))
+ (const_int 262140)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 4))
+ (const_int 262140))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 4))
+ (const_int 262140)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 4))
+ (const_int 262140))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
+ (const_int 2))
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 262140)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
+ (const_int 2))
+ (const_int 262140))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 262140)))]
+ "TARGET_H8300SX"
+ "mova/l.l @(0,%T1.w),%S0"
+ [(set_attr "length_table" "mova_zero")
+ (set_attr "cc" "none")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 2))
+ (const_int 262140))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ "TARGET_H8300SX"
+ "mova/l.l @(%o2,%T1.w),%S0"
+ [(set_attr "length_table" "mova")
+ (set_attr "cc" "none")])
+
diff --git a/gcc/config/h8300/t-rtems b/gcc/config/h8300/t-rtems
new file mode 100644
index 00000000000..104ee2366f1
--- /dev/null
+++ b/gcc/config/h8300/t-rtems
@@ -0,0 +1,7 @@
+# Custom multilibs for RTEMS
+
+# -mn is not applicable to RTEMS (-mn implies 16bit void*)
+
+MULTILIB_OPTIONS = mh/ms mint32
+MULTILIB_DIRNAMES = h8300h h8300s int32
+MULTILIB_EXCEPTIONS = mint32
diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c
new file mode 100644
index 00000000000..777cfa9f894
--- /dev/null
+++ b/gcc/config/host-linux.c
@@ -0,0 +1,141 @@
+/* Linux host-specific hook definitions.
+ 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 <sys/mman.h>
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+
+
+/* Linux has a feature called exec-shield-randomize that perturbs the
+ address of non-fixed mapped segments by a (relatively) small amount.
+ The feature is intended to make it harder to attack the system with
+ buffer overflow attacks, since every invocation of a program will
+ have its libraries and data segments at slightly different addresses.
+
+ This feature causes us problems with PCH because it makes it that
+ much harder to acquire a stable location at which to map our PCH
+ data file.
+
+ [ The feature causes other points of non-determinism within the
+ compiler as well, so we'd *really* like to be able to have the
+ driver disable exec-shield-randomize for the process group, but
+ that isn't possible at present. ]
+
+ We're going to try several things:
+
+ * Select an architecture specific address as "likely" and see
+ if that's free. For our 64-bit hosts, we can easily choose
+ an address in Never Never Land.
+
+ * If exec-shield-randomize is disabled, then just use the
+ address chosen by mmap in step one.
+
+ * If exec-shield-randomize is enabled, then temporarily allocate
+ 32M of memory as a buffer, then allocate PCH memory, then
+ free the buffer. The theory here is that the perturbation is
+ no more than 16M, and so by allocating our buffer larger than
+ that we make it considerably more likely that the address will
+ be free when we want to load the data back.
+*/
+
+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
+#define HOST_HOOKS_GT_PCH_GET_ADDRESS linux_gt_pch_get_address
+
+/* For various ports, try to guess a fixed spot in the vm space
+ that's probably free. */
+#if defined(__alpha)
+# define TRY_EMPTY_VM_SPACE 0x10000000000
+#elif defined(__ia64)
+# define TRY_EMPTY_VM_SPACE 0x2000000100000000
+#elif defined(__x86_64)
+# 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
+
+/* Determine a location where we might be able to reliably allocate SIZE
+ bytes. FD is the PCH file, though we should return with the file
+ unmapped. */
+
+static void *
+linux_gt_pch_get_address (size_t size, int fd)
+{
+ size_t buffer_size = 32 * 1024 * 1024;
+ void *addr, *buffer;
+ FILE *f;
+ bool randomize_on;
+
+ addr = mmap ((void *)TRY_EMPTY_VM_SPACE, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fd, 0);
+
+ /* If we failed the map, that means there's *no* free space. */
+ if (addr == (void *) MAP_FAILED)
+ return NULL;
+ /* Unmap the area before returning. */
+ munmap (addr, size);
+
+ /* If we got the exact area we requested, then that's great. */
+ if (TRY_EMPTY_VM_SPACE && addr == (void *) TRY_EMPTY_VM_SPACE)
+ return addr;
+
+ /* If we didn't, then we need to look to see if randomization is on. */
+ f = fopen ("/proc/sys/kernel/exec-shield-randomize", "r");
+ randomize_on = false;
+ if (f != NULL)
+ {
+ char buf[100];
+ size_t c;
+
+ c = fread (buf, 1, sizeof buf - 1, f);
+ if (c > 0)
+ {
+ buf[c] = '\0';
+ randomize_on = (atoi (buf) > 0);
+ }
+ fclose (f);
+ }
+
+ /* If it isn't, then accept the address that mmap selected as fine. */
+ if (!randomize_on)
+ return addr;
+
+ /* Otherwise, we need to try again with buffer space. */
+ buffer = mmap (0, buffer_size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (buffer != (void *) MAP_FAILED)
+ munmap (buffer, buffer_size);
+ if (addr == (void *) MAP_FAILED)
+ return NULL;
+ munmap (addr, size);
+
+ return addr;
+}
+
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/gcc/config/host-solaris.c b/gcc/config/host-solaris.c
new file mode 100644
index 00000000000..4fa7a5b1ad0
--- /dev/null
+++ b/gcc/config/host-solaris.c
@@ -0,0 +1,79 @@
+/* Solaris host-specific hook definitions.
+ 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 <sys/mman.h>
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+
+
+#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS sol_gt_pch_use_address
+
+/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at
+ mapping the data at BASE, -1 if we couldn't. */
+
+static int
+sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
+{
+ void *addr;
+
+ /* We're called with size == 0 if we're not planning to load a PCH
+ file at all. This allows the hook to free any static space that
+ we might have allocated at link time. */
+ if (size == 0)
+ return -1;
+
+ addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ fd, offset);
+
+ /* Solaris isn't good about honoring the mmap START parameter
+ without MAP_FIXED set. Before we give up, search the desired
+ address space with mincore to see if the space is really free. */
+ if (addr != base)
+ {
+ size_t page_size = getpagesize();
+ char one_byte;
+ size_t i;
+
+ if (addr != (void *) MAP_FAILED)
+ munmap (addr, size);
+
+ errno = 0;
+ for (i = 0; i < size; i += page_size)
+ if (mincore ((char *)base + i, page_size, (void *)&one_byte) == -1
+ && errno == ENOMEM)
+ continue; /* The page is not mapped. */
+ else
+ break;
+
+ if (i >= size)
+ addr = mmap (base, size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
+ fd, offset);
+ }
+
+ return addr == base ? 1 : -1;
+}
+
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/gcc/config/i386/host-mingw32.c b/gcc/config/i386/host-mingw32.c
new file mode 100644
index 00000000000..0e3fdd7caf1
--- /dev/null
+++ b/gcc/config/i386/host-mingw32.c
@@ -0,0 +1,148 @@
+/* mingw32 host-specific hook definitions.
+ 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 "hosthooks.h"
+#include "hosthooks-def.h"
+#include "toplev.h"
+#include "diagnostic.h"
+
+
+#define WIN32_LEAN_AND_MEAN /* Not so important if we have windows.h.gch. */
+#include <windows.h>
+
+static void * mingw32_gt_pch_get_address (size_t, int);
+static int mingw32_gt_pch_use_address (void *, size_t, int, size_t);
+static size_t mingw32_gt_pch_alloc_granularity (void);
+
+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
+#define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address
+#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address
+#undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY
+#define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity
+
+static inline void w32_error(const char*, const char*, int, const char*);
+
+/* FIXME: Is this big enough? */
+static const size_t pch_VA_max_size = 128 * 1024 * 1024;
+
+/* Granularity for reserving address space. */
+static const size_t va_granularity = 0x10000;
+
+/* Print out the GetLastError() translation. */
+static inline void
+w32_error (const char* function, const char* file, int line,
+ const char* my_msg)
+{
+ LPSTR w32_msgbuf;
+ FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR) &w32_msgbuf, 0, NULL);
+ fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n",
+ function, trim_filename (file), line, my_msg, w32_msgbuf);
+ LocalFree ((HLOCAL)w32_msgbuf);
+}
+
+/* Granularity for reserving address space. */
+static size_t mingw32_gt_pch_alloc_granularity (void)
+{
+ return va_granularity;
+}
+
+/* Identify an address that's likely to be free in a subsequent invocation
+ of the compiler. The area should be able to hold SIZE bytes. FD is an
+ open file descriptor if the host would like to probe with mmap. */
+
+static void *
+mingw32_gt_pch_get_address (size_t size, int fd ATTRIBUTE_UNUSED)
+{
+ void* res;
+ size = (size + va_granularity - 1) & ~(va_granularity - 1);
+ if (size > pch_VA_max_size)
+ return NULL;
+
+ /* FIXME: We let system determine base by setting first arg to NULL.
+ Allocating at top of available address space avoids unnecessary
+ fragmentation of "ordinary" (malloc's) address space but may not be safe
+ with delayed load of system dll's. Preferred addresses for NT system
+ dlls is in 0x70000000 to 0x78000000 range.
+ If we allocate at bottom we need to reserve the address as early as possible
+ and at the same point in each invocation. */
+
+ res = VirtualAlloc (NULL, pch_VA_max_size,
+ MEM_RESERVE | MEM_TOP_DOWN,
+ PAGE_NOACCESS);
+ if (!res)
+ w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc");
+ else
+ /* We do not need the address space for now, so free it. */
+ VirtualFree (res, 0, MEM_RELEASE);
+
+ return res;
+}
+
+/* ADDR is an address returned by gt_pch_get_address. Attempt to allocate
+ SIZE bytes at the same address and load it with the data from FD at
+ OFFSET. Return -1 if we couldn't allocate memory at ADDR, return 0
+ if the memory is allocated but the data not loaded, return 1 if done. */
+
+static int
+mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
+ size_t offset)
+{
+ void * mmap_addr;
+ static HANDLE mmap_handle;
+
+ if (size == 0)
+ return 0;
+
+ /* Offset must be also be a multiple of allocation granularity for
+ this to work. We can't change the offset. */
+ if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
+ return -1;
+
+ mmap_handle = CreateFileMapping ((HANDLE) _get_osfhandle (fd),
+ NULL, PAGE_WRITECOPY | SEC_COMMIT,
+ 0, 0, NULL);
+ if (mmap_handle == NULL)
+ {
+ w32_error (__FUNCTION__, __FILE__, __LINE__, "CreateFileMapping");
+ return -1;
+ }
+ mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
+ size, addr);
+ if (mmap_addr != addr)
+ {
+ w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx");
+ CloseHandle(mmap_handle);
+ return -1;
+ }
+
+ return 1;
+}
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 25240acc9d7..8fdf24dad46 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4882,7 +4882,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
{
HOST_WIDE_INT total_size;
int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
- HOST_WIDE_INT offset;
+ int offset;
int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
HOST_WIDE_INT size = get_frame_size ();
@@ -4998,8 +4998,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
(size + frame->padding1 + frame->padding2
+ frame->outgoing_arguments_size + frame->va_arg_size);
- if ((!frame->to_allocate && frame->nregs <= 1)
- || (TARGET_64BIT && frame->to_allocate >= (HOST_WIDE_INT) 0x80000000))
+ if (!frame->to_allocate && frame->nregs <= 1)
frame->save_regs_using_mov = false;
if (TARGET_RED_ZONE && current_function_sp_is_unchanging
@@ -5066,41 +5065,6 @@ ix86_emit_save_regs_using_mov (rtx pointer, HOST_WIDE_INT offset)
}
}
-/* Expand prologue or epilogue stack adjustement.
- The pattern exist to put a dependency on all ebp-based memory accesses.
- STYLE should be negative if instructions should be marked as frame related,
- zero if %r11 register is live and cannot be freely used and positive
- otherwise. */
-
-static void
-pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
-{
- rtx insn;
-
- if (! TARGET_64BIT)
- insn = emit_insn (gen_pro_epilogue_adjust_stack_1 (dest, src, offset));
- else if (x86_64_immediate_operand (offset, DImode))
- insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64 (dest, src, offset));
- else
- {
- rtx r11;
- /* r11 is used by indirect sibcall return as well, set before the
- epilogue and used after the epilogue. ATM indirect sibcall
- shouldn't be used together with huge frame sizes in one
- function because of the frame_size check in sibcall.c. */
- if (style == 0)
- abort ();
- r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
- insn = emit_insn (gen_rtx_SET (DImode, r11, offset));
- if (style < 0)
- RTX_FRAME_RELATED_P (insn) = 1;
- insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64_2 (dest, src, r11,
- offset));
- }
- if (style < 0)
- RTX_FRAME_RELATED_P (insn) = 1;
-}
-
/* Expand the prologue into a bunch of separate insns. */
void
@@ -5142,8 +5106,12 @@ ix86_expand_prologue (void)
if (allocate == 0)
;
else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-allocate), -1);
+ {
+ insn = emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-allocate)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
else
{
/* Only valid for Win32. */
@@ -5298,8 +5266,8 @@ ix86_expand_epilogue (int style)
tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, tmp);
- pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
- const0_rtx, style);
+ emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, sa, const0_rtx));
}
else
{
@@ -5310,19 +5278,19 @@ ix86_expand_epilogue (int style)
}
}
else if (!frame_pointer_needed)
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame.to_allocate
- + frame.nregs * UNITS_PER_WORD),
- style);
+ emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate
+ + frame.nregs * UNITS_PER_WORD)));
/* If not an i386, mov & pop is faster than "leave". */
else if (TARGET_USE_LEAVE || optimize_size
|| !cfun->machine->use_fast_prologue_epilogue)
emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
else
{
- pro_epilogue_adjust_stack (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- const0_rtx, style);
+ emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+ const0_rtx));
if (TARGET_64BIT)
emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
else
@@ -5337,13 +5305,14 @@ ix86_expand_epilogue (int style)
{
if (!frame_pointer_needed)
abort ();
- pro_epilogue_adjust_stack (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (offset), style);
+ emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+ GEN_INT (offset)));
}
else if (frame.to_allocate)
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame.to_allocate), style);
+ emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate)));
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (ix86_save_reg (regno, false))
@@ -5382,7 +5351,7 @@ ix86_expand_epilogue (int style)
{
rtx ecx = gen_rtx_REG (SImode, 2);
- /* There is no "pascal" calling convention in 64bit ABI. */
+ /* There are is no "pascal" calling convention in 64bit ABI. */
if (TARGET_64BIT)
abort ();
@@ -11625,7 +11594,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx callarg2,
{
rtx addr;
addr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
- fnaddr = gen_rtx_REG (Pmode, FIRST_REX_INT_REG + 3 /* R11 */);
+ fnaddr = gen_rtx_REG (Pmode, 40);
emit_move_insn (fnaddr, addr);
fnaddr = gen_rtx_MEM (QImode, fnaddr);
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f9acc04ec7b..835480d3a47 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -17772,7 +17772,23 @@
;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
;;
;; in proper program order.
-(define_insn "pro_epilogue_adjust_stack_1"
+(define_expand "pro_epilogue_adjust_stack"
+ [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_operand:SI 1 "register_operand" "0,r")
+ (match_operand:SI 2 "immediate_operand" "i,i")))
+ (clobber (reg:CC 17))
+ (clobber (mem:BLK (scratch)))])]
+ ""
+{
+ if (TARGET_64BIT)
+ {
+ emit_insn (gen_pro_epilogue_adjust_stack_rex64
+ (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+})
+
+(define_insn "*pro_epilogue_adjust_stack_1"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" "0,r")
(match_operand:SI 2 "immediate_operand" "i,i")))
@@ -17828,8 +17844,6 @@
case TYPE_ALU:
if (GET_CODE (operands[2]) == CONST_INT
- /* Avoid overflows. */
- && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
@@ -17856,30 +17870,6 @@
(const_string "lea")))
(set_attr "mode" "DI")])
-(define_insn "pro_epilogue_adjust_stack_rex64_2"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (match_operand:DI 1 "register_operand" "0,r")
- (match_operand:DI 3 "immediate_operand" "i,i")))
- (use (match_operand:DI 2 "register_operand" "r,r"))
- (clobber (reg:CC 17))
- (clobber (mem:BLK (scratch)))]
- "TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ALU:
- return "add{q}\t{%2, %0|%0, %2}";
-
- case TYPE_LEA:
- operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
- return "lea{q}\t{%a2, %0|%0, %a2}";
-
- default:
- abort ();
- }
-}
- [(set_attr "type" "alu,lea")
- (set_attr "mode" "DI")])
;; Placeholder for the conditional moves. This one is split either to SSE
;; based moves emulation or to usual cmove sequence. Little bit unfortunate
diff --git a/gcc/config/i386/kfreebsd-gnu.h b/gcc/config/i386/kfreebsd-gnu.h
new file mode 100644
index 00000000000..884777d50c9
--- /dev/null
+++ b/gcc/config/i386/kfreebsd-gnu.h
@@ -0,0 +1,26 @@
+/* Definitions for Intel 386 running kFreeBSD-based GNU systems with ELF format
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Robert Millan.
+
+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. */
+
+#undef LINK_EMULATION
+#define LINK_EMULATION "elf_i386_fbsd"
+#undef REG_NAME
+#define REG_NAME(reg) sc_ ## reg
diff --git a/gcc/config/i386/xm-sun.h b/gcc/config/i386/knetbsd-gnu.h
index 6c0f0a25630..a1cda7bcbb5 100644
--- a/gcc/config/i386/xm-sun.h
+++ b/gcc/config/i386/knetbsd-gnu.h
@@ -1,21 +1,24 @@
-/* Configuration for GNU C-compiler for Intel 80386 running SunOS 4.0.
- Copyright (C) 1988, 1997 Free Software Foundation, Inc.
+/* Definitions for Intel 386 running kNetBSD-based GNU systems with ELF format
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Robert Millan.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+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. */
-#define USG
+#undef REG_NAME
+#define REG_NAME(reg) sc_ ## reg
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/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-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/kfreebsd-gnu.h b/gcc/config/kfreebsd-gnu.h
new file mode 100644
index 00000000000..953c69cc083
--- /dev/null
+++ b/gcc/config/kfreebsd-gnu.h
@@ -0,0 +1,36 @@
+/* Definitions for kFreeBSD-based GNU systems with ELF format
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Robert Millan.
+
+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. */
+
+#undef LINUX_TARGET_OS_CPP_BUILTINS
+#define LINUX_TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__FreeBSD_kernel__"); \
+ builtin_define ("__GLIBC__"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } \
+ while (0)
+
+#undef DYNAMIC_LINKER
+#define DYNAMIC_LINKER "/lib/ld.so.1"
diff --git a/gcc/config/knetbsd-gnu.h b/gcc/config/knetbsd-gnu.h
new file mode 100644
index 00000000000..744cfc23de7
--- /dev/null
+++ b/gcc/config/knetbsd-gnu.h
@@ -0,0 +1,36 @@
+/* Definitions for kNetBSD-based GNU systems with ELF format
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Robert Millan.
+
+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. */
+
+#undef LINUX_TARGET_OS_CPP_BUILTINS
+#define LINUX_TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__NetBSD_kernel__"); \
+ builtin_define ("__GLIBC__"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } \
+ while (0)
+
+#undef DYNAMIC_LINKER
+#define DYNAMIC_LINKER "/lib/ld.so.1"
diff --git a/gcc/config/m32r/linux.h b/gcc/config/m32r/linux.h
new file mode 100644
index 00000000000..bc9e61bc99d
--- /dev/null
+++ b/gcc/config/m32r/linux.h
@@ -0,0 +1,104 @@
+/* Definitions for Renesas M32R running Linux-based GNU systems using ELF.
+ 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. */
+
+#define LINUX_DEFAULT_ELF
+
+/* A lie, I guess, but the general idea behind linux/ELF is that we are
+ supposed to be outputting something that will assemble under SVr4.
+ This gets us pretty close. */
+
+#define HANDLE_SYSV_PRAGMA
+
+#undef HANDLE_PRAGMA_PACK
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (M32R GNU/Linux with ELF)");
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+/* Provide a LINK_SPEC appropriate for Linux. Here we provide support
+ for the special GCC options -static and -shared, which allow us to
+ link things in one of these three modes by applying the appropriate
+ combinations of options at link-time. We like to support here for
+ as many of the other GNU linker options as possible. But I don't
+ have the time to search for those flags. I am sure how to add
+ support for -soname shared_object_name. H.J.
+
+ I took out %{v:%{!V:-V}}. It is too much :-(. They can use
+ -Wl,-V.
+
+ When the -shared link option is used a final link is not being
+ done. */
+
+/* If ELF is the default format, we should not use /lib/elf. */
+
+#undef LINK_SPEC
+#if TARGET_LITTLE_ENDIAN
+#define LINK_SPEC "%(link_cpu) -m m32rlelf_linux %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
+ %{static:-static}}}"
+#else
+#define LINK_SPEC "%(link_cpu) -m m32relf_linux %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
+ %{static:-static}}}"
+#endif
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+ "%{shared: -lc} \
+ %{!shared: %{mieee-fp:-lieee} %{pthread:-lpthread} \
+ %{profile:-lc_p} %{!profile: -lc}}"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: \
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+
+#undef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC "\
+ %{posix:-D_POSIX_SOURCE} \
+ %{pthread:-D_REENTRANT -D_PTHREADS} \
+"
+
+#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
+
diff --git a/gcc/config/m32r/little.h b/gcc/config/m32r/little.h
new file mode 100644
index 00000000000..9c1b0b5a72c
--- /dev/null
+++ b/gcc/config/m32r/little.h
@@ -0,0 +1,34 @@
+/* Definitions for Renesas little endian M32R cpu.
+ 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. */
+
+#define TARGET_ENDIAN_DEFAULT LITTLE_ENDIAN_BIT
+
+#define CPP_ENDIAN_SPEC \
+ " %{mbe:-D__BIG_ENDIAN__} %{mbig-endian:-D__BIG_ENDIAN__}" \
+ " %{!mbe: %{!mbig-endian:-D__LITTLE_ENDIAN__}}"
+
+#define CC1_ENDIAN_SPEC " %{!mbe: %{!mbig-endian:-mle}}"
+
+#define ASM_ENDIAN_SPEC \
+ " %{!mbe: %{!mbig-endian:-EL}} %{mbe:-EB} %{mbig-endian:-EB}"
+
+#define LINK_ENDIAN_SPEC " %{!mbe: %{!mbig-endian:-EL}}"
+
diff --git a/gcc/config/m32r/t-linux b/gcc/config/m32r/t-linux
new file mode 100644
index 00000000000..03046579094
--- /dev/null
+++ b/gcc/config/m32r/t-linux
@@ -0,0 +1,42 @@
+# lib1funcs.asm is currently empty.
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so...
+
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+# Turn off the SDA while compiling libgcc2. There are no headers for it
+# and we want maximal upward compatibility here.
+
+TARGET_LIBGCC2_CFLAGS = -G 0 -fPIC
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+# We need to use -fpic when we are using gcc to compile the routines in
+# initfini.c. This is only really needed when we are going to use gcc/g++
+# to produce a shared library, but since we don't know ahead of time when
+# we will be doing that, we just always use -fpic when compiling the
+# routines in initfini.c.
+# -fpic currently isn't supported for the m32r.
+
+CRTSTUFF_T_CFLAGS_S = -fPIC
+
+
+# Don't run fixproto
+STMP_FIXPROTO =
+
+# Don't install "assert.h" in gcc. We use the one in glibc.
+INSTALL_ASSERT_H =
+
+# Do not build libgcc1. Let gcc generate those functions. The GNU/Linux
+# C library can handle them.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+LIBGCC1_TEST =
+
diff --git a/gcc/config/m32r/xm-linux.h b/gcc/config/m32r/xm-linux.h
new file mode 100644
index 00000000000..1c6f4629798
--- /dev/null
+++ b/gcc/config/m32r/xm-linux.h
@@ -0,0 +1,26 @@
+/* Configuration for GCC for Renesas M32R running Linux-based GNU systems.
+ 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 <m32r/xm-m32r.h>
+#include <xm-linux.h>
+
+/* Doubles are stored in memory with the high order word first.
+ This matters when cross-compiling. */
+#undef HOST_WORDS_BIG_ENDIAN
diff --git a/gcc/config/m32r/xm-m32r.h b/gcc/config/m32r/xm-m32r.h
new file mode 100644
index 00000000000..c7b006ae3b5
--- /dev/null
+++ b/gcc/config/m32r/xm-m32r.h
@@ -0,0 +1,43 @@
+/* Configuration for GNU C-compiler for the M32R processor.
+ 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. */
+
+/* This describes the machine the compiler is hosted on. */
+#define HOST_BITS_PER_CHAR 8
+#define HOST_BITS_PER_SHORT 16
+#define HOST_BITS_PER_INT 32
+#define HOST_BITS_PER_LONG 32
+#define HOST_BITS_PER_LONGLONG 64
+
+/* Doubles are stored in memory with the high order word first.
+ This matters when cross-compiling. */
+#define HOST_WORDS_BIG_ENDIAN 1
+
+/* target machine dependencies.
+ tm.h is a symbolic link to the actual target specific file. */
+#include "tm.h"
+
+/* Arguments to use with `exit'. */
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 33
+
+/* If compiled with Sun CC, the use of alloca requires this #include. */
+#ifndef __GNUC__
+#include "alloca.h"
+#endif
diff --git a/gcc/config/m68k/t-slibgcc-elf-ver b/gcc/config/m68k/t-slibgcc-elf-ver
new file mode 100644
index 00000000000..6aac37cc08f
--- /dev/null
+++ b/gcc/config/m68k/t-slibgcc-elf-ver
@@ -0,0 +1,3 @@
+# Bump the version number of the shared libgcc library
+
+SHLIB_SOVERSION = 2
diff --git a/gcc/config/memcmp.c b/gcc/config/memcmp.c
new file mode 100644
index 00000000000..2348afe1d27
--- /dev/null
+++ b/gcc/config/memcmp.c
@@ -0,0 +1,16 @@
+/* Public domain. */
+#include <stddef.h>
+
+int
+memcmp (const void *str1, const void *str2, size_t count)
+{
+ const unsigned char *s1 = str1;
+ const unsigned char *s2 = str2;
+
+ while (count-- > 0)
+ {
+ if (*s1++ != *s2++)
+ return s1[-1] < s2[-1] ? -1 : 1;
+ }
+ return 0;
+}
diff --git a/gcc/config/memcpy.c b/gcc/config/memcpy.c
new file mode 100644
index 00000000000..58b1e405627
--- /dev/null
+++ b/gcc/config/memcpy.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+#include <stddef.h>
+
+void *
+memcpy (void *dest, const void *src, size_t len)
+{
+ char *d = dest;
+ const char *s = src;
+ while (len--)
+ *d++ = *s++;
+ return dest;
+}
diff --git a/gcc/config/memmove.c b/gcc/config/memmove.c
new file mode 100644
index 00000000000..13b340af6a0
--- /dev/null
+++ b/gcc/config/memmove.c
@@ -0,0 +1,20 @@
+/* Public domain. */
+#include <stddef.h>
+
+void *
+memmove (void *dest, const void *src, size_t len)
+{
+ char *d = dest;
+ const char *s = src;
+ if (d < s)
+ while (len--)
+ *d++ = *s++;
+ else
+ {
+ char *lasts = s + (len-1);
+ char *lastd = d + (len-1);
+ while (len--)
+ *lastd-- = *lasts--;
+ }
+ return dest;
+}
diff --git a/gcc/config/memset.c b/gcc/config/memset.c
new file mode 100644
index 00000000000..3e7025ee394
--- /dev/null
+++ b/gcc/config/memset.c
@@ -0,0 +1,11 @@
+/* Public domain. */
+#include <stddef.h>
+
+void *
+memset (void *dest, int val, size_t len)
+{
+ unsigned char *ptr = dest;
+ while (len-- > 0)
+ *ptr++ = val;
+ return dest;
+}
diff --git a/gcc/config/mips/3000.md b/gcc/config/mips/3000.md
new file mode 100644
index 00000000000..8c9a0d6429f
--- /dev/null
+++ b/gcc/config/mips/3000.md
@@ -0,0 +1,78 @@
+;; DFA based pipeline description for the r3000
+;; This is a special pipeline - this is also the default schedule and
+;; so we need to schedule instructions that may not exist on the r2k/r3k.
+
+(define_automaton "r3k_alu,r3k_imuldiv")
+
+(define_cpu_unit "r3k_alu" "r3k_alu")
+(define_cpu_unit "r3k_imuldiv" "r3k_imuldiv")
+
+(define_insn_reservation "r3k_generic" 1
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "unknown,prefetch,prefetchx,condmove,const,arith,
+ shift,slt,clz,trap,multi,nop"))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_load" 2
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "load,fpload,fpidxload,xfer"))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_store" 1
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "store,fpstore,fpidxstore"))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_branch" 1
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "branch,jump,call"))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_hilo" 1
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "mfhilo,mthilo"))
+ "r3k_imuldiv*3")
+
+(define_insn_reservation "r3k_imul" 12
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "imul,imadd"))
+ "r3k_imuldiv*12")
+
+(define_insn_reservation "r3k_idiv" 35
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "idiv"))
+ "r3k_imuldiv*35")
+
+(define_insn_reservation "r3k_fmove" 1
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "fabs,fneg,fmove,fcvt"))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_fadd" 2
+ (and (eq_attr "cpu" "r3000")
+ (eq_attr "type" "fcmp,fadd"))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_fmul_single" 4
+ (and (eq_attr "cpu" "r3000")
+ (and (eq_attr "type" "fmul,fmadd")
+ (eq_attr "mode" "SF")))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_fmul_double" 5
+ (and (eq_attr "cpu" "r3000")
+ (and (eq_attr "type" "fmul,fmadd")
+ (eq_attr "mode" "DF")))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_fdiv_single" 12
+ (and (eq_attr "cpu" "r3000")
+ (and (eq_attr "type" "fdiv,fsqrt,frsqrt")
+ (eq_attr "mode" "SF")))
+ "r3k_alu")
+
+(define_insn_reservation "r3k_fdiv_double" 19
+ (and (eq_attr "cpu" "r3000")
+ (and (eq_attr "type" "fdiv,fsqrt,frsqrt")
+ (eq_attr "mode" "DF")))
+ "r3k_alu")
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/iris5gld.h b/gcc/config/mips/iris5gld.h
new file mode 100644
index 00000000000..cd4eb86a889
--- /dev/null
+++ b/gcc/config/mips/iris5gld.h
@@ -0,0 +1,75 @@
+/* Definitions of target machine for GNU compiler. IRIX 5 with GNU ld.
+ Copyright (C) 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. */
+
+#undef LINK_SPEC
+#define LINK_SPEC "\
+%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} \
+%{bestGnum} %{shared} %{non_shared} \
+%{call_shared} %{no_archive} %{exact_version} \
+%{static: -non_shared} \
+%{!static: \
+ %{!shared: %{!non_shared: %{!call_shared: -call_shared}}}} \
+%{rpath} -init __gcc_init -fini __gcc_fini \
+-melf32bsmip"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%(irix_startfile_spec) irix-crti.o%s crtbegin.o%s"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s irix-crtn.o%s %(irix_endfile_spec)"
+
+/* The GNU linker supports one-only sections. */
+#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
+
+#define INIT_SECTION_ASM_OP "\t.section\t.init,0x1,0x6,4,4"
+#define FINI_SECTION_ASM_OP "\t.section\t.fini,0x1,0x6,4,4"
+/* Definitions of target machine for GNU compiler. IRIX 5 with GNU ld.
+ Copyright (C) 2003 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. */
+
+#undef LINK_SPEC
+#define LINK_SPEC "\
+%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} \
+%{bestGnum} %{shared} %{non_shared} \
+%{call_shared} %{no_archive} %{exact_version} \
+%{static: -non_shared} \
+%{!static: \
+ %{!shared: %{!non_shared: %{!call_shared: -call_shared}}}} \
+%{rpath} -init __do_global_ctors -fini __do_global_dtors \
+-melf32bsmip"
+
+/* The GNU linker supports one-only sections. */
+#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
diff --git a/gcc/config/mips/irix-crti.asm b/gcc/config/mips/irix-crti.asm
new file mode 100644
index 00000000000..5d8ede70390
--- /dev/null
+++ b/gcc/config/mips/irix-crti.asm
@@ -0,0 +1,33 @@
+ .abicalls
+ .set noreorder
+ .set nomacro
+
+ .section .init,0x1,0x6,4,4
+ jr $31
+ nop
+
+ .globl __gcc_init
+__gcc_init:
+#if _MIPS_SIM == _ABIO32
+ addiu $sp,$sp,-16
+ sw $31,0($sp)
+#else
+ daddiu $sp,$sp,-16
+ sd $31,0($sp)
+ sd $28,8($sp)
+#endif
+
+ .section .fini,0x1,0x6,4,4
+ jr $31
+ nop
+
+ .globl __gcc_fini
+__gcc_fini:
+#if _MIPS_SIM == _ABIO32
+ addiu $sp,$sp,-16
+ sw $31,0($sp)
+#else
+ daddiu $sp,$sp,-16
+ sd $31,0($sp)
+ sd $28,8($sp)
+#endif
diff --git a/gcc/config/mips/irix-crtn.asm b/gcc/config/mips/irix-crtn.asm
new file mode 100644
index 00000000000..647e8e13e31
--- /dev/null
+++ b/gcc/config/mips/irix-crtn.asm
@@ -0,0 +1,27 @@
+ .abicalls
+ .set noreorder
+ .set nomacro
+
+ .section .init,0x1,0x6,4,4
+#if _MIPS_SIM == _ABIO32
+ lw $31,0($sp)
+ jr $31
+ addiu $sp,$sp,16
+#else
+ ld $31,0($sp)
+ ld $28,8($sp)
+ jr $31
+ daddiu $sp,$sp,16
+#endif
+
+ .section .fini,0x1,0x6,4,4
+#if _MIPS_SIM == _ABIO32
+ lw $31,0($sp)
+ jr $31
+ addiu $sp,$sp,16
+#else
+ ld $31,0($sp)
+ ld $28,8($sp)
+ jr $31
+ daddiu $sp,$sp,16
+#endif
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/t-irix-gld b/gcc/config/mips/t-irix-gld
new file mode 100644
index 00000000000..1e7ceafaff9
--- /dev/null
+++ b/gcc/config/mips/t-irix-gld
@@ -0,0 +1,9 @@
+$(T)irix-crti.o: $(srcdir)/config/mips/irix-crti.asm $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+ -c -o $@ -x assembler-with-cpp $<
+
+$(T)irix-crtn.o: $(srcdir)/config/mips/irix-crtn.asm $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+ -c -o $@ -x assembler-with-cpp $<
+
+EXTRA_MULTILIB_PARTS += irix-crti.o irix-crtn.o
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/pa/t-slibgcc-elf-ver b/gcc/config/pa/t-slibgcc-elf-ver
new file mode 100644
index 00000000000..6aac37cc08f
--- /dev/null
+++ b/gcc/config/pa/t-slibgcc-elf-ver
@@ -0,0 +1,3 @@
+# Bump the version number of the shared libgcc library
+
+SHLIB_SOVERSION = 2
diff --git a/gcc/config/rs6000/darwin-fallback.c b/gcc/config/rs6000/darwin-fallback.c
new file mode 100644
index 00000000000..f7756fbac84
--- /dev/null
+++ b/gcc/config/rs6000/darwin-fallback.c
@@ -0,0 +1,432 @@
+/* Fallback frame-state unwinder for Darwin.
+ 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.
+
+ 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 combined
+ 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 "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "dwarf2.h"
+#include "unwind.h"
+#include "unwind-dw2.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <ucontext.h>
+
+typedef unsigned long reg_unit;
+
+/* Place in GPRS the parameters to the first 'sc' instruction that would
+ have been executed if we were returning from this CONTEXT, or
+ return false if an unexpected instruction is encountered. */
+
+static bool
+interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
+{
+ uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
+ uint32_t cr;
+ reg_unit lr = (reg_unit) pc;
+ reg_unit ctr = 0;
+ uint32_t *invalid_address = NULL;
+
+ int i;
+
+ for (i = 0; i < 13; i++)
+ gprs[i] = 1;
+ gprs[1] = _Unwind_GetCFA (context);
+ for (; i < 32; i++)
+ gprs[i] = _Unwind_GetGR (context, i);
+ cr = _Unwind_GetGR (context, CR2_REGNO);
+
+ /* For each supported Libc, we have to track the code flow
+ all the way back into the kernel.
+
+ This code is believed to support all released Libc/Libsystem builds since
+ Jaguar 6C115, including all the security updates. To be precise,
+
+ Libc Libsystem Build(s)
+ 262~1 60~37 6C115
+ 262~1 60.2~4 6D52
+ 262~1 61~3 6F21-6F22
+ 262~1 63~24 6G30-6G37
+ 262~1 63~32 6I34-6I35
+ 262~1 63~64 6L29-6L60
+ 262.4.1~1 63~84 6L123-6R172
+
+ 320~1 71~101 7B85-7D28
+ 320~1 71~266 7F54-7F56
+ 320~1 71~288 7F112
+ 320~1 71~289 7F113
+ 320.1.3~1 71.1.1~29 7H60-7H105
+ 320.1.3~1 71.1.1~30 7H110-7H113
+ 320.1.3~1 71.1.1~31 7H114
+
+ That's a big table! It would be insane to try to keep track of
+ every little detail, so we just read the code itself and do what
+ it would do.
+ */
+
+ for (;;)
+ {
+ uint32_t ins = *pc++;
+
+ if ((ins & 0xFC000003) == 0x48000000) /* b instruction */
+ {
+ pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
+ continue;
+ }
+ if ((ins & 0xFC600000) == 0x2C000000) /* cmpwi */
+ {
+ int32_t val1 = (int16_t) ins;
+ int32_t val2 = gprs[ins >> 16 & 0x1F];
+ /* Only beq and bne instructions are supported, so we only
+ need to set the EQ bit. */
+ uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
+ if (val1 == val2)
+ cr |= mask;
+ else
+ cr &= ~mask;
+ continue;
+ }
+ if ((ins & 0xFEC38003) == 0x40820000) /* forwards beq/bne */
+ {
+ if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
+ pc += (ins & 0x7FFC) / 4 - 1;
+ continue;
+ }
+ if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
+ {
+ gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
+ | gprs [ins >> 21 & 0x1F]);
+ continue;
+ }
+ if (ins >> 26 == 0x0E) /* addi, including li */
+ {
+ reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
+ gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
+ continue;
+ }
+ if (ins >> 26 == 0x0F) /* addis, including lis */
+ {
+ reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
+ gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
+ continue;
+ }
+ if (ins >> 26 == 0x20) /* lwz */
+ {
+ reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
+ uint32_t *p = (uint32_t *)(src + (int16_t) ins);
+ if (p == invalid_address)
+ return false;
+ gprs [ins >> 21 & 0x1F] = *p;
+ continue;
+ }
+ if (ins >> 26 == 0x21) /* lwzu */
+ {
+ uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
+ if (p == invalid_address)
+ return false;
+ gprs [ins >> 21 & 0x1F] = *p;
+ continue;
+ }
+ if (ins >> 26 == 0x24) /* stw */
+ /* What we hope this is doing is '--in_sigtramp'. We don't want
+ to actually store to memory, so just make a note of the
+ address and refuse to load from it. */
+ {
+ reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
+ uint32_t *p = (uint32_t *)(src + (int16_t) ins);
+ if (p == NULL || invalid_address != NULL)
+ return false;
+ invalid_address = p;
+ continue;
+ }
+ if (ins >> 26 == 0x2E) /* lmw */
+ {
+ reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
+ uint32_t *p = (uint32_t *)(src + (int16_t) ins);
+ int i;
+
+ for (i = (ins >> 21 & 0x1F); i < 32; i++)
+ {
+ if (p == invalid_address)
+ return false;
+ gprs[i] = *p++;
+ }
+ continue;
+ }
+ if ((ins & 0xFC1FFFFF) == 0x7c0803a6) /* mtlr */
+ {
+ lr = gprs [ins >> 21 & 0x1F];
+ continue;
+ }
+ if ((ins & 0xFC1FFFFF) == 0x7c0802a6) /* mflr */
+ {
+ gprs [ins >> 21 & 0x1F] = lr;
+ continue;
+ }
+ if ((ins & 0xFC1FFFFF) == 0x7c0903a6) /* mtctr */
+ {
+ ctr = gprs [ins >> 21 & 0x1F];
+ continue;
+ }
+ /* The PowerPC User's Manual says that bit 11 of the mtcrf
+ instruction is reserved and should be set to zero, but it
+ looks like the Darwin assembler doesn't do that... */
+ if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
+ {
+ int i;
+ uint32_t mask = 0;
+ for (i = 0; i < 8; i++)
+ mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
+ cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
+ continue;
+ }
+ if (ins == 0x429f0005) /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
+ {
+ lr = (reg_unit) pc;
+ continue;
+ }
+ if (ins == 0x4e800420) /* bctr */
+ {
+ pc = (uint32_t *) ctr;
+ continue;
+ }
+ if (ins == 0x44000002) /* sc */
+ return true;
+
+ return false;
+ }
+}
+
+/* These defines are from the kernel's bsd/dev/ppc/unix_signal.c. */
+#define UC_TRAD 1
+#define UC_TRAD_VEC 6
+#define UC_TRAD64 20
+#define UC_TRAD64_VEC 25
+#define UC_FLAVOR 30
+#define UC_FLAVOR_VEC 35
+#define UC_FLAVOR64 40
+#define UC_FLAVOR64_VEC 45
+#define UC_DUAL 50
+#define UC_DUAL_VEC 55
+
+/* These are based on /usr/include/ppc/ucontext.h and
+ /usr/include/mach/ppc/thread_status.h, but rewritten to be more
+ convenient, to compile on Jaguar, and to work around Radar 3712064
+ on Panther, which is that the 'es' field of 'struct mcontext64' has
+ the wrong type (doh!). */
+
+struct gcc_mcontext64 {
+ uint64_t dar;
+ uint32_t dsisr;
+ uint32_t exception;
+ uint32_t padding1[4];
+ uint64_t srr0;
+ uint64_t srr1;
+ uint32_t gpr[32][2];
+ uint32_t cr;
+ uint32_t xer[2]; /* These are arrays because the original structure has them misaligned. */
+ uint32_t lr[2];
+ uint32_t ctr[2];
+ uint32_t vrsave;
+ ppc_float_state_t fs;
+ ppc_vector_state_t vs;
+};
+
+#define UC_FLAVOR_SIZE \
+ (sizeof (struct mcontext) - sizeof (ppc_vector_state_t))
+
+#define UC_FLAVOR_VEC_SIZE (sizeof (struct mcontext))
+
+#define UC_FLAVOR64_SIZE \
+ (sizeof (struct gcc_mcontext64) - sizeof (ppc_vector_state_t))
+
+#define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
+
+/* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
+ to represent the execution of a signal return; or, if not a signal
+ return, return false. */
+
+static bool
+handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
+ _Unwind_Ptr old_cfa)
+{
+ struct ucontext *uctx;
+ bool is_64, is_vector;
+ ppc_float_state_t *float_state;
+ ppc_vector_state_t *vector_state;
+ _Unwind_Ptr new_cfa;
+ int i;
+ static _Unwind_Ptr return_addr;
+
+ /* Yay! We're in a Libc that we understand, and it's made a
+ system call. It'll be one of two kinds: either a Jaguar-style
+ SYS_sigreturn, or a Panther-style 'syscall' call with 184, which
+ is also SYS_sigreturn. */
+
+ if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
+ {
+ uctx = (struct ucontext *) gprs[3];
+ is_vector = (uctx->uc_mcsize == UC_FLAVOR64_VEC_SIZE
+ || uctx->uc_mcsize == UC_FLAVOR_VEC_SIZE);
+ is_64 = (uctx->uc_mcsize == UC_FLAVOR64_VEC_SIZE
+ || uctx->uc_mcsize == UC_FLAVOR64_SIZE);
+ }
+ else if (gprs[0] == 0 && gprs[3] == 184)
+ {
+ int ctxstyle = gprs[5];
+ uctx = (struct ucontext *) gprs[4];
+ is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
+ || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
+ is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
+ || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
+ }
+ else
+ return false;
+
+#define set_offset(r, addr) \
+ (fs->regs.reg[r].how = REG_SAVED_OFFSET, \
+ fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
+
+ /* Restore even the registers that are not call-saved, since they
+ might be being used in the prologue to save other registers,
+ for instance GPR0 is sometimes used to save LR. */
+
+ /* Handle the GPRs, and produce the information needed to do the rest. */
+ if (is_64)
+ {
+ /* The context is 64-bit, but it doesn't carry any extra information
+ for us because only the low 32 bits of the registers are
+ call-saved. */
+ struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->uc_mcontext;
+ int i;
+
+ float_state = &m64->fs;
+ vector_state = &m64->vs;
+
+ new_cfa = m64->gpr[1][1];
+
+ set_offset (CR2_REGNO, &m64->cr);
+ for (i = 0; i < 32; i++)
+ set_offset (i, m64->gpr[i] + 1);
+ set_offset (XER_REGNO, m64->xer + 1);
+ set_offset (LINK_REGISTER_REGNUM, m64->lr + 1);
+ set_offset (COUNT_REGISTER_REGNUM, m64->ctr + 1);
+ if (is_vector)
+ set_offset (VRSAVE_REGNO, &m64->vrsave);
+
+ /* Sometimes, srr0 points to the instruction that caused the exception,
+ and sometimes to the next instruction to be executed; we want
+ the latter. */
+ if (m64->exception == 3 || m64->exception == 4
+ || m64->exception == 6
+ || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
+ return_addr = m64->srr0 + 4;
+ else
+ return_addr = m64->srr0;
+ }
+ else
+ {
+ struct mcontext *m = uctx->uc_mcontext;
+ int i;
+
+ float_state = &m->fs;
+ vector_state = &m->vs;
+
+ new_cfa = m->ss.r1;
+
+ set_offset (CR2_REGNO, &m->ss.cr);
+ for (i = 0; i < 32; i++)
+ set_offset (i, &m->ss.r0 + i);
+ set_offset (XER_REGNO, &m->ss.xer);
+ set_offset (LINK_REGISTER_REGNUM, &m->ss.lr);
+ set_offset (COUNT_REGISTER_REGNUM, &m->ss.ctr);
+
+ if (is_vector)
+ set_offset (VRSAVE_REGNO, &m->ss.vrsave);
+
+ /* Sometimes, srr0 points to the instruction that caused the exception,
+ and sometimes to the next instruction to be executed; we want
+ the latter. */
+ if (m->es.exception == 3 || m->es.exception == 4
+ || m->es.exception == 6
+ || (m->es.exception == 7 && !(m->ss.srr1 & 0x10000)))
+ return_addr = m->ss.srr0 + 4;
+ else
+ return_addr = m->ss.srr0;
+ }
+
+ fs->cfa_how = CFA_REG_OFFSET;
+ fs->cfa_reg = STACK_POINTER_REGNUM;
+ fs->cfa_offset = new_cfa - old_cfa;;
+
+ /* The choice of column for the return address is somewhat tricky.
+ Fortunately, the actual choice is private to this file, and
+ the space it's reserved from is the GCC register space, not the
+ DWARF2 numbering. So any free element of the right size is an OK
+ choice. Thus: */
+ fs->retaddr_column = ARG_POINTER_REGNUM;
+ /* FIXME: this should really be done using a DWARF2 location expression,
+ not using a static variable. In fact, this entire file should
+ be implemented in DWARF2 expressions. */
+ set_offset (ARG_POINTER_REGNUM, &return_addr);
+
+ for (i = 0; i < 32; i++)
+ set_offset (32 + i, float_state->fpregs + i);
+ set_offset (SPEFSCR_REGNO, &float_state->fpscr);
+
+ if (is_vector)
+ {
+ for (i = 0; i < 32; i++)
+ set_offset (FIRST_ALTIVEC_REGNO + i, vector_state->save_vr + i);
+ set_offset (VSCR_REGNO, vector_state->save_vscr);
+ }
+
+ return true;
+}
+
+/* This is also prototyped in rs6000/darwin.h, inside the
+ MD_FALLBACK_FRAME_STATE_FOR macro. */
+extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs);
+
+/* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
+ returning true iff the frame was a sigreturn() frame that we
+ can understand. */
+
+bool
+_Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ reg_unit gprs[32];
+
+ if (!interpret_libc (gprs, context))
+ return false;
+ return handle_syscall (fs, gprs, _Unwind_GetCFA (context));
+}
diff --git a/gcc/config/rs6000/darwin-fpsave.asm b/gcc/config/rs6000/darwin-fpsave.asm
new file mode 100644
index 00000000000..c8c646b09db
--- /dev/null
+++ b/gcc/config/rs6000/darwin-fpsave.asm
@@ -0,0 +1,100 @@
+/* This file contains the floating-point save and restore routines.
+ *
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * 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, 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 with other programs, and to distribute
+ * those programs 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 another program.)
+ *
+ * This file is distributed in the hope that 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; 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, if you link this library with files
+ * compiled with GCC to produce an executable, this does not 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.
+ */
+
+/* THE SAVE AND RESTORE ROUTINES CAN HAVE ONLY ONE GLOBALLY VISIBLE
+ ENTRY POINT - callers have to jump to "saveFP+60" to save f29..f31,
+ for example. For FP reg saves/restores, it takes one instruction
+ (4 bytes) to do the operation; for Vector regs, 2 instructions are
+ required (8 bytes.)
+
+ MORAL: DO NOT MESS AROUND WITH THESE FUNCTIONS! */
+
+.text
+ .align 2
+
+/* saveFP saves R0 -- assumed to be the callers LR -- to 8(R1). */
+
+.private_extern saveFP
+saveFP:
+ stfd f14,-144(r1)
+ stfd f15,-136(r1)
+ stfd f16,-128(r1)
+ stfd f17,-120(r1)
+ stfd f18,-112(r1)
+ stfd f19,-104(r1)
+ stfd f20,-96(r1)
+ stfd f21,-88(r1)
+ stfd f22,-80(r1)
+ stfd f23,-72(r1)
+ stfd f24,-64(r1)
+ stfd f25,-56(r1)
+ stfd f26,-48(r1)
+ stfd f27,-40(r1)
+ stfd f28,-32(r1)
+ stfd f29,-24(r1)
+ stfd f30,-16(r1)
+ stfd f31,-8(r1)
+ stw r0,8(r1)
+ blr
+
+/* restFP restores the caller`s LR from 8(R1). Note that the code for
+ this starts at the offset of F30 restoration, so calling this
+ routine in an attempt to restore only F31 WILL NOT WORK (it would
+ be a stupid thing to do, anyway.) */
+
+.private_extern restFP
+restFP:
+ lfd f14,-144(r1)
+ lfd f15,-136(r1)
+ lfd f16,-128(r1)
+ lfd f17,-120(r1)
+ lfd f18,-112(r1)
+ lfd f19,-104(r1)
+ lfd f20,-96(r1)
+ lfd f21,-88(r1)
+ lfd f22,-80(r1)
+ lfd f23,-72(r1)
+ lfd f24,-64(r1)
+ lfd f25,-56(r1)
+ lfd f26,-48(r1)
+ lfd f27,-40(r1)
+ lfd f28,-32(r1)
+ lfd f29,-24(r1)
+ /* <OFFSET OF F30 RESTORE> restore callers LR */
+ lwz r0,8(r1)
+ lfd f30,-16(r1)
+ /* and prepare for return to caller */
+ mtlr r0
+ lfd f31,-8(r1)
+ blr
diff --git a/gcc/config/rs6000/darwin-ldouble.c b/gcc/config/rs6000/darwin-ldouble.c
new file mode 100644
index 00000000000..e3dc5627445
--- /dev/null
+++ b/gcc/config/rs6000/darwin-ldouble.c
@@ -0,0 +1,205 @@
+/* 128-bit long double support routines for Darwin.
+ Copyright (C) 1993, 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.
+
+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. */
+
+/* Implementations of floating-point long double basic arithmetic
+ functions called by the IBM C compiler when generating code for
+ PowerPC platforms. In particular, the following functions are
+ implemented: _xlqadd, _xlqsub, _xlqmul, and _xlqdiv. Double-double
+ algorithms are based on the paper "Doubled-Precision IEEE Standard
+ 754 Floating-Point Arithmetic" by W. Kahan, February 26, 1987. An
+ alternative published reference is "Software for Doubled-Precision
+ Floating-Point Computations", by Seppo Linnainmaa, ACM TOMS vol 7
+ no 3, September 1961, pages 272-283. */
+
+/* Each long double is made up of two IEEE doubles. The value of the
+ long double is the sum of the values of the two parts. The most
+ significant part is required to be the value of the long double
+ rounded to the nearest double, as specified by IEEE. For Inf
+ values, the least significant part is required to be one of +0.0 or
+ -0.0. No other requirements are made; so, for example, 1.0 may be
+ represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
+ NaN is don't-care.
+
+ This code currently assumes big-endian. */
+
+#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__))
+
+#define fabs(x) __builtin_fabs(x)
+
+#define unlikely(x) __builtin_expect ((x), 0)
+
+/* All these routines actually take two long doubles as parameters,
+ but GCC currently generates poor code when a union is used to turn
+ a long double into a pair of doubles. */
+
+extern long double _xlqadd (double, double, double, double);
+extern long double _xlqsub (double, double, double, double);
+extern long double _xlqmul (double, double, double, double);
+extern long double _xlqdiv (double, double, double, double);
+
+typedef union
+{
+ long double ldval;
+ double dval[2];
+} longDblUnion;
+
+static const double FPKINF = 1.0/0.0;
+
+/* Add two 'long double' values and return the result. */
+long double
+_xlqadd (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double t, tau, u, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ if (unlikely (a != a) || unlikely (c != c))
+ return a + c; /* NaN result. */
+
+ /* Ordered operands are arranged in order of their magnitudes. */
+
+ /* Switch inputs if |(c,d)| > |(a,b)|. */
+ if (fabs (c) > fabs (a))
+ {
+ t = a;
+ tau = b;
+ a = c;
+ b = d;
+ c = t;
+ d = tau;
+ }
+
+ /* b <- second largest magnitude double. */
+ if (fabs (c) > fabs (b))
+ {
+ t = b;
+ b = c;
+ c = t;
+ }
+
+ /* Thanks to commutativity, sum is invariant w.r.t. the next
+ conditional exchange. */
+ tau = d + c;
+
+ /* Order the smallest magnitude doubles. */
+ if (fabs (d) > fabs (c))
+ {
+ t = c;
+ c = d;
+ d = t;
+ }
+
+ t = (tau + b) + a; /* Sum values in ascending magnitude order. */
+
+ /* Infinite or zero result. */
+ if (unlikely (t == FPR_zero) || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Usual case. */
+ tau = (((a-t) + b) + c) + d;
+ u = t + tau;
+ z.dval[0] = u; /* Final fixup for long double result. */
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+long double
+_xlqsub (double a, double b, double c, double d)
+{
+ return _xlqadd (a, b, -c, -d);
+}
+
+long double
+_xlqmul (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double t, tau, u, v, w, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ t = a * c; /* Highest order double term. */
+
+ if (unlikely (t != t) || unlikely (t == FPR_zero)
+ || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Finite nonzero result requires summing of terms of two highest
+ orders. */
+
+ /* Use fused multiply-add to get low part of a * c. */
+ asm ("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
+ v = a*d;
+ w = b*c;
+ tau += v + w; /* Add in other second-order terms. */
+ u = t + tau;
+
+ /* Construct long double result. */
+ z.dval[0] = u;
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+long double
+_xlqdiv (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double s, sigma, t, tau, u, v, w, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ t = a / c; /* highest order double term */
+
+ if (unlikely (t != t) || unlikely (t == FPR_zero)
+ || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Finite nonzero result requires corrections to the highest order term. */
+
+ s = c * t; /* (s,sigma) = c*t exactly. */
+ w = -(-b + d * t); /* Written to get fnmsub for speed, but not
+ numerically necessary. */
+
+ /* Use fused multiply-add to get low part of c * t. */
+ asm ("fmsub %0,%1,%2,%3" : "=f"(sigma) : "f"(c), "f"(t), "f"(s));
+ v = a - s;
+
+ tau = ((v-sigma)+w)/c; /* Correction to t. */
+ u = t + tau;
+
+ /* Construct long double result. */
+ z.dval[0] = u;
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+#endif
diff --git a/gcc/config/rs6000/darwin-vecsave.asm b/gcc/config/rs6000/darwin-vecsave.asm
new file mode 100644
index 00000000000..58ec8eaa1a3
--- /dev/null
+++ b/gcc/config/rs6000/darwin-vecsave.asm
@@ -0,0 +1,164 @@
+/* This file contains the vector save and restore routines.
+ *
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * 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, 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 with other programs, and to distribute
+ * those programs 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 another program.)
+ *
+ * This file is distributed in the hope that 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; 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, if you link this library with files
+ * compiled with GCC to produce an executable, this does not 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.
+ */
+
+/* Vector save/restore routines for Darwin. Note that each vector
+ save/restore requires 2 instructions (8 bytes.)
+
+ THE SAVE AND RESTORE ROUTINES CAN HAVE ONLY ONE GLOBALLY VISIBLE
+ ENTRY POINT - callers have to jump to "saveFP+60" to save f29..f31,
+ for example. For FP reg saves/restores, it takes one instruction
+ (4 bytes) to do the operation; for Vector regs, 2 instructions are
+ required (8 bytes.). */
+
+.text
+ .align 2
+
+.private_extern saveVEC
+saveVEC:
+ li r11,-192
+ stvx v20,r11,r0
+ li r11,-176
+ stvx v21,r11,r0
+ li r11,-160
+ stvx v22,r11,r0
+ li r11,-144
+ stvx v23,r11,r0
+ li r11,-128
+ stvx v24,r11,r0
+ li r11,-112
+ stvx v25,r11,r0
+ li r11,-96
+ stvx v26,r11,r0
+ li r11,-80
+ stvx v27,r11,r0
+ li r11,-64
+ stvx v28,r11,r0
+ li r11,-48
+ stvx v29,r11,r0
+ li r11,-32
+ stvx v30,r11,r0
+ li r11,-16
+ stvx v31,r11,r0
+ blr
+
+.private_extern restVEC
+restVEC:
+ li r11,-192
+ lvx v20,r11,r0
+ li r11,-176
+ lvx v21,r11,r0
+ li r11,-160
+ lvx v22,r11,r0
+ li r11,-144
+ lvx v23,r11,r0
+ li r11,-128
+ lvx v24,r11,r0
+ li r11,-112
+ lvx v25,r11,r0
+ li r11,-96
+ lvx v26,r11,r0
+ li r11,-80
+ lvx v27,r11,r0
+ li r11,-64
+ lvx v28,r11,r0
+ li r11,-48
+ lvx v29,r11,r0
+ li r11,-32
+ lvx v30,r11,r0
+ li r11,-16
+ lvx v31,r11,r0
+ blr
+
+/* saveVEC_vr11 -- as saveVEC but VRsave is returned in R11. */
+
+.private_extern saveVEC_vr11
+saveVEC_vr11:
+ li r11,-192
+ stvx v20,r11,r0
+ li r11,-176
+ stvx v21,r11,r0
+ li r11,-160
+ stvx v22,r11,r0
+ li r11,-144
+ stvx v23,r11,r0
+ li r11,-128
+ stvx v24,r11,r0
+ li r11,-112
+ stvx v25,r11,r0
+ li r11,-96
+ stvx v26,r11,r0
+ li r11,-80
+ stvx v27,r11,r0
+ li r11,-64
+ stvx v28,r11,r0
+ li r11,-48
+ stvx v29,r11,r0
+ li r11,-32
+ stvx v30,r11,r0
+ li r11,-16
+ stvx v31,r11,r0
+ mfspr r11,VRsave
+ blr
+
+/* As restVec, but the original VRsave value passed in R10. */
+
+.private_extern restVEC_vr10
+restVEC_vr10:
+ li r11,-192
+ lvx v20,r11,r0
+ li r11,-176
+ lvx v21,r11,r0
+ li r11,-160
+ lvx v22,r11,r0
+ li r11,-144
+ lvx v23,r11,r0
+ li r11,-128
+ lvx v24,r11,r0
+ li r11,-112
+ lvx v25,r11,r0
+ li r11,-96
+ lvx v26,r11,r0
+ li r11,-80
+ lvx v27,r11,r0
+ li r11,-64
+ lvx v28,r11,r0
+ li r11,-48
+ lvx v29,r11,r0
+ li r11,-32
+ lvx v30,r11,r0
+ li r11,-16
+ lvx v31,r11,r0
+ /* restore VRsave from R10. */
+ mtspr VRsave,r10
+ blr
diff --git a/gcc/config/rs6000/darwin-world.asm b/gcc/config/rs6000/darwin-world.asm
new file mode 100644
index 00000000000..57b516f9b4f
--- /dev/null
+++ b/gcc/config/rs6000/darwin-world.asm
@@ -0,0 +1,264 @@
+/* This file contains the exception-handling save_world and
+ * restore_world routines, which need to do a run-time check to see if
+ * they should save and restore the vector registers.
+ *
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * 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, 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 with other programs, and to distribute
+ * those programs 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 another program.)
+ *
+ * This file is distributed in the hope that 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; 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, if you link this library with files
+ * compiled with GCC to produce an executable, this does not 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.
+ */
+
+.data
+ .align 2
+
+#ifdef __DYNAMIC__
+
+.non_lazy_symbol_pointer
+L_has_vec$non_lazy_ptr:
+ .indirect_symbol __cpu_has_altivec
+ .long 0
+
+#else
+
+/* For static, "pretend" we have a non-lazy-pointer. */
+
+L_has_vec$non_lazy_ptr:
+ .long __cpu_has_altivec
+
+#endif
+
+
+.text
+ .align 2
+
+/* save_world and rest_world save/restore F14-F31 and possibly V20-V31
+ (assuming you have a CPU with vector registers; we use a global var
+ provided by the System Framework to determine this.)
+
+ SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11
+ (the stack frame size) as parameters. It returns VRsave in R0 if
+ we`re on a CPU with vector regs.
+
+ With gcc3, we now need to save and restore CR as well, since gcc3's
+ scheduled prologs can cause comparisons to be moved before calls to
+ save_world!
+
+ USES: R0 R11 R12 */
+
+.private_extern save_world
+save_world:
+ stw r0,8(r1)
+ mflr r0
+ bcl 20,31,Ls$pb
+Ls$pb: mflr r12
+ addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Ls$pb)
+ lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12)
+ mtlr r0
+ lwz r12,0(r12)
+ /* grab CR */
+ mfcr r0
+ /* test HAS_VEC */
+ cmpwi r12,0
+ stfd f14,-144(r1)
+ stfd f15,-136(r1)
+ stfd f16,-128(r1)
+ stfd f17,-120(r1)
+ stfd f18,-112(r1)
+ stfd f19,-104(r1)
+ stfd f20,-96(r1)
+ stfd f21,-88(r1)
+ stfd f22,-80(r1)
+ stfd f23,-72(r1)
+ stfd f24,-64(r1)
+ stfd f25,-56(r1)
+ stfd f26,-48(r1)
+ stfd f27,-40(r1)
+ stfd f28,-32(r1)
+ stfd f29,-24(r1)
+ stfd f30,-16(r1)
+ stfd f31,-8(r1)
+ stmw r13,-220(r1)
+ /* stash CR */
+ stw r0,4(r1)
+ /* set R12 pointing at Vector Reg save area */
+ addi r12,r1,-224
+ /* allocate stack frame */
+ stwux r1,r1,r11
+ /* ...but return if HAS_VEC is zero */
+ bne+ L$saveVMX
+ /* Not forgetting to restore CR. */
+ mtcr r0
+ blr
+
+L$saveVMX:
+ /* We're saving Vector regs too. */
+ /* Restore CR from R0. No More Branches! */
+ mtcr r0
+
+ /* We should really use VRSAVE to figure out which vector regs
+ we actually need to save and restore. Some other time :-/ */
+
+ li r11,-192
+ stvx v20,r11,r12
+ li r11,-176
+ stvx v21,r11,r12
+ li r11,-160
+ stvx v22,r11,r12
+ li r11,-144
+ stvx v23,r11,r12
+ li r11,-128
+ stvx v24,r11,r12
+ li r11,-112
+ stvx v25,r11,r12
+ li r11,-96
+ stvx v26,r11,r12
+ li r11,-80
+ stvx v27,r11,r12
+ li r11,-64
+ stvx v28,r11,r12
+ li r11,-48
+ stvx v29,r11,r12
+ li r11,-32
+ stvx v30,r11,r12
+ mfspr r0,VRsave
+ li r11,-16
+ stvx v31,r11,r12
+ /* VRsave lives at -224(R1) */
+ stw r0,0(r12)
+ blr
+
+
+/* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR.
+ R10 is the C++ EH stack adjust parameter, we return to the caller`s caller.
+
+ USES: R0 R10 R11 R12 and R7 R8
+ RETURNS: C++ EH Data registers (R3 - R6.)
+
+ We now set up R7/R8 and jump to rest_world_eh_r7r8.
+
+ rest_world doesn't use the R10 stack adjust parameter, nor does it
+ pick up the R3-R6 exception handling stuff. */
+
+.private_extern rest_world
+rest_world:
+ /* Pickup previous SP */
+ lwz r11, 0(r1)
+ li r7, 0
+ lwz r8, 8(r11)
+ li r10, 0
+ b rest_world_eh_r7r8
+
+.private_extern eh_rest_world_r10
+eh_rest_world_r10:
+ /* Pickup previous SP */
+ lwz r11, 0(r1)
+ mr r7,r10
+ lwz r8, 8(r11)
+ /* pickup the C++ EH data regs (R3 - R6.) */
+ lwz r6,-420(r11)
+ lwz r5,-424(r11)
+ lwz r4,-428(r11)
+ lwz r3,-432(r11)
+
+ b rest_world_eh_r7r8
+
+/* rest_world_eh_r7r8 is jumped to -- not called! -- when we're doing
+ the exception-handling epilog. R7 contains the offset to add to
+ the SP, and R8 contains the 'real' return address.
+
+ USES: R0 R11 R12 [R7/R8]
+ RETURNS: C++ EH Data registers (R3 - R6.) */
+
+rest_world_eh_r7r8:
+ bcl 20,31,Lr7r8$pb
+Lr7r8$pb: mflr r12
+ lwz r11,0(r1)
+ /* R11 := previous SP */
+ addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7r8$pb)
+ lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7r8$pb)(r12)
+ lwz r0,4(r11)
+ /* R0 := old CR */
+ lwz r12,0(r12)
+ /* R12 := HAS_VEC */
+ mtcr r0
+ cmpwi r12,0
+ lmw r13,-220(r11)
+ beq L.rest_world_fp_eh
+ /* restore VRsave and V20..V31 */
+ lwz r0,-224(r11)
+ li r12,-416
+ mtspr VRsave,r0
+ lvx v20,r11,r12
+ li r12,-400
+ lvx v21,r11,r12
+ li r12,-384
+ lvx v22,r11,r12
+ li r12,-368
+ lvx v23,r11,r12
+ li r12,-352
+ lvx v24,r11,r12
+ li r12,-336
+ lvx v25,r11,r12
+ li r12,-320
+ lvx v26,r11,r12
+ li r12,-304
+ lvx v27,r11,r12
+ li r12,-288
+ lvx v28,r11,r12
+ li r12,-272
+ lvx v29,r11,r12
+ li r12,-256
+ lvx v30,r11,r12
+ li r12,-240
+ lvx v31,r11,r12
+
+L.rest_world_fp_eh:
+ lfd f14,-144(r11)
+ lfd f15,-136(r11)
+ lfd f16,-128(r11)
+ lfd f17,-120(r11)
+ lfd f18,-112(r11)
+ lfd f19,-104(r11)
+ lfd f20,-96(r11)
+ lfd f21,-88(r11)
+ lfd f22,-80(r11)
+ lfd f23,-72(r11)
+ lfd f24,-64(r11)
+ lfd f25,-56(r11)
+ lfd f26,-48(r11)
+ lfd f27,-40(r11)
+ lfd f28,-32(r11)
+ lfd f29,-24(r11)
+ lfd f30,-16(r11)
+ /* R8 is the exception-handler's address */
+ mtctr r8
+ lfd f31,-8(r11)
+ /* set SP to original value + R7 offset */
+ add r1,r11,r7
+ bctr
diff --git a/gcc/config/rs6000/libgcc-ppc64.ver b/gcc/config/rs6000/libgcc-ppc64.ver
new file mode 100644
index 00000000000..116d5e73fa0
--- /dev/null
+++ b/gcc/config/rs6000/libgcc-ppc64.ver
@@ -0,0 +1,7 @@
+GCC_3.4 {
+ # long double support
+ _xlqadd
+ _xlqsub
+ _xlqmul
+ _xlqdiv
+}
diff --git a/gcc/config/rs6000/power5.md b/gcc/config/rs6000/power5.md
new file mode 100644
index 00000000000..59baa79c30c
--- /dev/null
+++ b/gcc/config/rs6000/power5.md
@@ -0,0 +1,299 @@
+;; Scheduling description for IBM POWER5 processor.
+;; 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.
+
+;; Sources: IBM Red Book and White Paper on POWER5
+
+;; The POWER5 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip).
+;; Instructions that update more than one register get broken into two
+;; (split) or more internal ops. The chip can issue up to 5
+;; internal ops per cycle.
+
+(define_automaton "power5iu,power5fpu,power5misc")
+
+(define_cpu_unit "iu1_power5,iu2_power5" "power5iu")
+(define_cpu_unit "lsu1_power5,lsu2_power5" "power5misc")
+(define_cpu_unit "fpu1_power5,fpu2_power5" "power5fpu")
+(define_cpu_unit "bpu_power5,cru_power5" "power5misc")
+(define_cpu_unit "du1_power5,du2_power5,du3_power5,du4_power5,du5_power5"
+ "power5misc")
+
+(define_reservation "lsq_power5"
+ "(du1_power5,lsu1_power5)\
+ |(du2_power5,lsu2_power5)\
+ |(du3_power5,nothing,lsu2_power5)\
+ |(du4_power5,nothing,lsu1_power5)")
+
+(define_reservation "iq_power5"
+ "(du1_power5,iu1_power5)\
+ |(du2_power5,iu2_power5)\
+ |(du3_power5,nothing,iu2_power5)\
+ |(du4_power5,nothing,iu1_power5)")
+
+(define_reservation "fpq_power5"
+ "(du1_power5,fpu1_power5)\
+ |(du2_power5,fpu2_power5)\
+ |(du3_power5,nothing,fpu2_power5)\
+ |(du4_power5,nothing,fpu1_power5)")
+
+; Dispatch slots are allocated in order conforming to program order.
+(absence_set "du1_power5" "du2_power5,du3_power5,du4_power5,du5_power5")
+(absence_set "du2_power5" "du3_power5,du4_power5,du5_power5")
+(absence_set "du3_power5" "du4_power5,du5_power5")
+(absence_set "du4_power5" "du5_power5")
+
+
+; Load/store
+(define_insn_reservation "power5-load" 4 ; 3
+ (and (eq_attr "type" "load")
+ (eq_attr "cpu" "power5"))
+ "lsq_power5")
+
+(define_insn_reservation "power5-load-ext" 5
+ (and (eq_attr "type" "load_ext")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-ext-update" 5
+ (and (eq_attr "type" "load_ext_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ lsu1_power5+iu2_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-ext-update-indexed" 5
+ (and (eq_attr "type" "load_ext_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu1_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-update-indexed" 3
+ (and (eq_attr "type" "load_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu2_power5")
+
+(define_insn_reservation "power5-load-update" 4 ; 3
+ (and (eq_attr "type" "load_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5")
+
+(define_insn_reservation "power5-fpload" 6 ; 5
+ (and (eq_attr "type" "fpload")
+ (eq_attr "cpu" "power5"))
+ "lsq_power5")
+
+(define_insn_reservation "power5-fpload-update" 6 ; 5
+ (and (eq_attr "type" "fpload_u,fpload_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5")
+
+(define_insn_reservation "power5-store" 1
+ (and (eq_attr "type" "store")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,lsu1_power5,iu1_power5)\
+ |(du2_power5,lsu2_power5,iu2_power5)\
+ |(du3_power5,lsu2_power5,nothing,iu2_power5)\
+ |(du4_power5,lsu1_power5,nothing,iu1_power5)")
+
+(define_insn_reservation "power5-store-update" 1
+ (and (eq_attr "type" "store_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5,iu1_power5")
+
+(define_insn_reservation "power5-store-update-indexed" 1
+ (and (eq_attr "type" "store_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu2_power5,iu2_power5")
+
+(define_insn_reservation "power5-fpstore" 1
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,lsu1_power5,fpu1_power5)\
+ |(du2_power5,lsu2_power5,fpu2_power5)\
+ |(du3_power5,lsu2_power5,nothing,fpu2_power5)\
+ |(du4_power5,lsu1_power5,nothing,fpu1_power5)")
+
+(define_insn_reservation "power5-fpstore-update" 1
+ (and (eq_attr "type" "fpstore_u,fpstore_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5,fpu1_power5")
+
+
+; Integer latency is 2 cycles
+(define_insn_reservation "power5-integer" 2
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "power5"))
+ "iq_power5")
+
+(define_insn_reservation "power5-insert" 4
+ (and (eq_attr "type" "insert_word")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5,nothing,iu2_power5")
+
+(define_insn_reservation "power5-cmp" 3
+ (and (eq_attr "type" "cmp,fast_compare")
+ (eq_attr "cpu" "power5"))
+ "iq_power5")
+
+(define_insn_reservation "power5-compare" 2
+ (and (eq_attr "type" "compare,delayed_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5,iu2_power5")
+
+(define_bypass 4 "power5-compare" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-lmul-cmp" 7
+ (and (eq_attr "type" "lmul_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5*6,iu2_power5")
+
+(define_bypass 10 "power5-lmul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-imul-cmp" 5
+ (and (eq_attr "type" "imul_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5*4,iu2_power5")
+
+(define_bypass 8 "power5-imul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-lmul" 7
+ (and (eq_attr "type" "lmul")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*6)\
+ |(du2_power5,iu2_power5*6)\
+ |(du3_power5,iu2_power5*6)\
+ |(du4_power5,iu2_power5*6)")
+; |(du3_power5,nothing,iu2_power5*6)\
+; |(du4_power5,nothing,iu2_power5*6)")
+
+(define_insn_reservation "power5-imul" 5
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*4)\
+ |(du2_power5,iu2_power5*4)\
+ |(du3_power5,iu2_power5*4)\
+ |(du4_power5,iu1_power5*4)")
+; |(du3_power5,nothing,iu2_power5*4)\
+; |(du4_power5,nothing,iu1_power5*4)")
+
+(define_insn_reservation "power5-imul3" 4
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*3)\
+ |(du2_power5,iu2_power5*3)\
+ |(du3_power5,iu2_power5*3)\
+ |(du4_power5,iu1_power5*3)")
+; |(du3_power5,nothing,iu2_power5*3)\
+; |(du4_power5,nothing,iu1_power5*3)")
+
+
+; SPR move only executes in first IU.
+; Integer division only executes in second IU.
+(define_insn_reservation "power5-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu2_power5*35")
+
+(define_insn_reservation "power5-ldiv" 68
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu2_power5*67")
+
+
+(define_insn_reservation "power5-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,bpu_power5")
+
+
+; Branches take dispatch Slot 4. The presence_sets prevent other insn from
+; grabbing previous dispatch slots once this is assigned.
+(define_insn_reservation "power5-branch" 2
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "power5"))
+ "(du5_power5\
+ |du4_power5+du5_power5\
+ |du3_power5+du4_power5+du5_power5\
+ |du2_power5+du3_power5+du4_power5+du5_power5\
+ |du1_power5+du2_power5+du3_power5+du4_power5+du5_power5),bpu_power5")
+
+
+; Condition Register logical ops are split if non-destructive (RT != RB)
+(define_insn_reservation "power5-crlogical" 2
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,cru_power5")
+
+(define_insn_reservation "power5-delayedcr" 4
+ (and (eq_attr "type" "delayed_cr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,cru_power5,cru_power5")
+
+; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu
+(define_insn_reservation "power5-mfcr" 6
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ du1_power5+du2_power5+du3_power5+du4_power5+cru_power5,\
+ cru_power5,cru_power5,cru_power5")
+
+; mfcrf (1 field)
+(define_insn_reservation "power5-mfcrf" 3
+ (and (eq_attr "type" "mfcrf")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,cru_power5")
+
+; mtcrf (1 field)
+(define_insn_reservation "power5-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,iu1_power5")
+
+; Basic FP latency is 6 cycles
+(define_insn_reservation "power5-fp" 6
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "power5"))
+ "fpq_power5")
+
+(define_insn_reservation "power5-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "power5"))
+ "fpq_power5")
+
+(define_insn_reservation "power5-sdiv" 33
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,fpu1_power5*28)\
+ |(du2_power5,fpu2_power5*28)\
+ |(du3_power5,fpu2_power5*28)\
+ |(du4_power5,fpu1_power5*28)")
+; |(du3_power5,nothing,fpu2_power5*28)\
+; |(du4_power5,nothing,fpu1_power5*28)")
+
+(define_insn_reservation "power5-sqrt" 40
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,fpu1_power5*35)\
+ |(du2_power5,fpu2_power5*35)\
+ |(du3_power5,fpu2_power5*35)\
+ |(du4_power5,fpu2_power5*35)")
+; |(du3_power5,nothing,fpu2_power5*35)\
+; |(du4_power5,nothing,fpu2_power5*35)")
+
diff --git a/gcc/config/rs6000/t-rtems b/gcc/config/rs6000/t-rtems
new file mode 100644
index 00000000000..364a22d2278
--- /dev/null
+++ b/gcc/config/rs6000/t-rtems
@@ -0,0 +1,86 @@
+# Multilibs for powerpc RTEMS targets.
+
+MULTILIB_OPTIONS = \
+mcpu=403/mcpu=505/mcpu=601/mcpu=602/mcpu=603/mcpu=603e/mcpu=604/mcpu=750/mcpu=821/mcpu=860 \
+Dmpc509/Dmpc8260 \
+D_OLD_EXCEPTIONS \
+msoft-float
+
+MULTILIB_DIRNAMES = \
+m403 m505 m601 m602 m603 m603e m604 m750 m821 m860 \
+mpc509 \
+mpc8260 \
+roe \
+nof
+
+MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align
+
+# MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT}
+MULTILIB_MATCHES = ${MULTILIB_MATCHES_ENDIAN} \
+ ${MULTILIB_MATCHES_SYSV} \
+ mcpu?505/Dmpc505=mcpu?505/Dmpc509
+
+#
+# RTEMS old/new-exceptions handling
+#
+# old-exception processing is depredicated, therefore
+#
+# * Cpu-variants supporting new exception processing are build
+# with new exception processing only
+# * Cpu-variants not having been ported to new exception processing are
+# build with old and new exception processing
+#
+
+# Cpu-variants supporting new exception processing only
+MULTILIB_NEW_EXCEPTIONS_ONLY = \
+*mcpu=604*/*D_OLD_EXCEPTIONS* \
+*mcpu=750*/*D_OLD_EXCEPTIONS* \
+*mcpu=821*/*D_OLD_EXCEPTIONS* \
+*Dmpc8260*/*D_OLD_EXCEPTIONS* \
+*mcpu=860*/*D_OLD_EXCEPTIONS*
+
+# Soft-float only, default implies msoft-float
+# NOTE: Must match with MULTILIB_MATCHES_FLOAT and MULTILIB_MATCHES
+MULTILIB_SOFTFLOAT_ONLY = \
+mcpu=403/*msoft-float* \
+mcpu=821/*msoft-float* \
+mcpu=860/*msoft-float*
+
+# Hard-float only, take out msoft-float
+MULTILIB_HARDFLOAT_ONLY = \
+mcpu=505/*msoft-float*
+
+MULTILIB_EXCEPTIONS =
+
+# Disallow -D_OLD_EXCEPTIONS without other options
+MULTILIB_EXCEPTIONS += D_OLD_EXCEPTIONS*
+
+# Disallow -Dppc and -Dmpc without other options
+MULTILIB_EXCEPTIONS += Dppc* Dmpc*
+
+MULTILIB_EXCEPTIONS += \
+${MULTILIB_NEW_EXCEPTIONS_ONLY} \
+${MULTILIB_SOFTFLOAT_ONLY} \
+${MULTILIB_HARDFLOAT_ONLY}
+
+# Special rules
+# Take out all variants we don't want
+MULTILIB_EXCEPTIONS += mcpu=403/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=403/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=505/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=505/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=601/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=601/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=602/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=602/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=603/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=603/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=603e/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=604/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=604/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=750/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=750/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=821/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=821/Dmpc8260*
+MULTILIB_EXCEPTIONS += mcpu=860/Dmpc509*
+MULTILIB_EXCEPTIONS += mcpu=860/Dmpc8260*
diff --git a/gcc/config/sh/libgcc-std.ver b/gcc/config/sh/libgcc-std.ver
new file mode 100644
index 00000000000..bd4cfbf3d34
--- /dev/null
+++ b/gcc/config/sh/libgcc-std.ver
@@ -0,0 +1,218 @@
+GCC_3.0 {
+ # libgcc1 integer symbols
+ __absvsi2
+ __addvsi3
+ # __ashlsi3
+ # __ashrsi3
+ __divsi3
+ # __lshrsi3
+ __modsi3
+ __mulsi3
+ __mulvsi3
+ __negvsi2
+ __subvsi3
+ # __udivsi3
+ __umodsi3
+
+ # libgcc1 floating point symbols
+ __addsf3
+ __adddf3
+ __addxf3
+ __addtf3
+ __divsf3
+ __divdf3
+ __divxf3
+ __divtf3
+ __eqsf2
+ __eqdf2
+ __eqxf2
+ __eqtf2
+ __extenddfxf2
+ __extenddftf2
+ __extendsfdf2
+ __extendsfxf2
+ __extendsftf2
+ __fixsfsi
+ __fixdfsi
+ __fixxfsi
+ __fixtfsi
+ __floatsisf
+ __floatsidf
+ __floatsixf
+ __floatsitf
+ __gesf2
+ __gedf2
+ __gexf2
+ __getf2
+ __gtsf2
+ __gtdf2
+ __gtxf2
+ __gttf2
+ __lesf2
+ __ledf2
+ __lexf2
+ __letf2
+ __ltsf2
+ __ltdf2
+ __ltxf2
+ __lttf2
+ __mulsf3
+ __muldf3
+ __mulxf3
+ __multf3
+ __negsf2
+ __negdf2
+ __negxf2
+ __negtf2
+ __nesf2
+ __nedf2
+ __nexf2
+ __netf2
+ __subsf3
+ __subdf3
+ __subxf3
+ __subtf3
+ __truncdfsf2
+ __truncxfsf2
+ __trunctfsf2
+ __truncxfdf2
+ __trunctfdf2
+
+ # libgcc2 DImode arithmetic (for 32-bit targets).
+ __absvdi2
+ __addvdi3
+ __ashldi3
+ __ashrdi3
+ __cmpdi2
+ __divdi3
+ __ffsdi2
+ __fixdfdi
+ __fixsfdi
+ __fixtfdi
+ __fixxfdi
+ __fixunsdfdi
+ __fixunsdfsi
+ __fixunssfsi
+ __fixunssfdi
+ __fixunstfdi
+ __fixunstfsi
+ __fixunsxfdi
+ __fixunsxfsi
+ __floatdidf
+ __floatdisf
+ __floatdixf
+ __floatditf
+ __lshrdi3
+ __moddi3
+ __muldi3
+ __mulvdi3
+ __negdi2
+ __negvdi2
+ __subvdi3
+ __ucmpdi2
+ __udivdi3
+ __udivmoddi4
+ __umoddi3
+
+ # libgcc2 TImode arithmetic (for 64-bit targets).
+ __ashlti3
+ __ashrti3
+ __cmpti2
+ __divti3
+ __ffsti2
+ __fixdfti
+ __fixsfti
+ __fixtfti
+ __fixxfti
+ __lshrti3
+ __modti3
+ __multi3
+ __negti2
+ __ucmpti2
+ __udivmodti4
+ __udivti3
+ __umodti3
+ __fixunsdfti
+ __fixunssfti
+ __fixunstfti
+ __fixunsxfti
+ __floattidf
+ __floattisf
+ __floattixf
+ __floattitf
+
+ # Used to deal with trampoline initialization on some platforms
+ __clear_cache
+
+ # EH symbols
+ _Unwind_DeleteException
+ _Unwind_Find_FDE
+ _Unwind_ForcedUnwind
+ _Unwind_GetGR
+ _Unwind_GetIP
+ _Unwind_GetLanguageSpecificData
+ _Unwind_GetRegionStart
+ _Unwind_GetTextRelBase
+ _Unwind_GetDataRelBase
+ _Unwind_RaiseException
+ _Unwind_Resume
+ _Unwind_SetGR
+ _Unwind_SetIP
+ __deregister_frame
+ __deregister_frame_info
+ __deregister_frame_info_bases
+ __register_frame
+ __register_frame_info
+ __register_frame_info_bases
+ __register_frame_info_table
+ __register_frame_info_table_bases
+ __register_frame_table
+
+ # SjLj EH symbols
+ _Unwind_SjLj_Register
+ _Unwind_SjLj_Unregister
+ _Unwind_SjLj_RaiseException
+ _Unwind_SjLj_ForcedUnwind
+ _Unwind_SjLj_Resume
+}
+
+%inherit GCC_3.3 GCC_3.0
+GCC_3.3 {
+ _Unwind_FindEnclosingFunction
+ _Unwind_GetCFA
+ _Unwind_Backtrace
+ _Unwind_Resume_or_Rethrow
+ _Unwind_SjLj_Resume_or_Rethrow
+}
+
+%inherit GCC_3.3.1 GCC_3.3
+GCC_3.3.1 {
+ __gcc_personality_sj0
+ __gcc_personality_v0
+}
+
+%inherit GCC_3.3.2 GCC_3.3.1
+GCC_3.3.2 {
+}
+%inherit GCC_3.3.4 GCC_3.3.2
+GCC_3.3.4 {
+ __unorddf2
+ __unordsf2
+}
+
+%inherit GCC_3.4 GCC_3.3.4
+GCC_3.4 {
+ # bit scanning and counting built-ins
+ __clzsi2
+ __clzdi2
+ __clzti2
+ __ctzsi2
+ __ctzdi2
+ __ctzti2
+ __popcountsi2
+ __popcountdi2
+ __popcountti2
+ __paritysi2
+ __paritydi2
+ __parityti2
+}
diff --git a/gcc/config/sh/t-1e b/gcc/config/sh/t-1e
new file mode 100644
index 00000000000..74b0f9a606a
--- /dev/null
+++ b/gcc/config/sh/t-1e
@@ -0,0 +1 @@
+MULTILIB_ENDIAN =
diff --git a/gcc/config/sh/t-linux64 b/gcc/config/sh/t-linux64
new file mode 100644
index 00000000000..126b0163754
--- /dev/null
+++ b/gcc/config/sh/t-linux64
@@ -0,0 +1 @@
+EXTRA_MULTILIB_PARTS= crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
diff --git a/gcc/config/sh/t-mlib-sh1 b/gcc/config/sh/t-mlib-sh1
new file mode 100644
index 00000000000..9ba70541c6c
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh1
@@ -0,0 +1 @@
+ML_sh1=m1/
diff --git a/gcc/config/sh/t-mlib-sh2 b/gcc/config/sh/t-mlib-sh2
new file mode 100644
index 00000000000..d8857bab66b
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2
@@ -0,0 +1 @@
+ML_sh2=m2/
diff --git a/gcc/config/sh/t-mlib-sh2e b/gcc/config/sh/t-mlib-sh2e
new file mode 100644
index 00000000000..58841327cfe
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2e
@@ -0,0 +1 @@
+ML_sh2e=m2e/
diff --git a/gcc/config/sh/t-mlib-sh3 b/gcc/config/sh/t-mlib-sh3
new file mode 100644
index 00000000000..2c89d749a99
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh3
@@ -0,0 +1 @@
+ML_sh3=m3/
diff --git a/gcc/config/sh/t-mlib-sh3e b/gcc/config/sh/t-mlib-sh3e
new file mode 100644
index 00000000000..ca18b1bcf8b
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh3e
@@ -0,0 +1 @@
+ML_sh3e=m3e/
diff --git a/gcc/config/sh/t-mlib-sh4 b/gcc/config/sh/t-mlib-sh4
new file mode 100644
index 00000000000..be7f5c4febd
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4
@@ -0,0 +1 @@
+ML_sh4=m4/
diff --git a/gcc/config/sh/t-mlib-sh4-nofpu b/gcc/config/sh/t-mlib-sh4-nofpu
new file mode 100644
index 00000000000..fa12433714b
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4-nofpu
@@ -0,0 +1 @@
+ML_sh4_nofpu=m4-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh4-single b/gcc/config/sh/t-mlib-sh4-single
new file mode 100644
index 00000000000..f81bddd1efe
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4-single
@@ -0,0 +1 @@
+ML_sh4_single=m4-single/
diff --git a/gcc/config/sh/t-mlib-sh4-single-only b/gcc/config/sh/t-mlib-sh4-single-only
new file mode 100644
index 00000000000..121d598d69f
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4-single-only
@@ -0,0 +1 @@
+ML_sh4_single_only=m4-single-only/
diff --git a/gcc/config/sh/t-mlib-sh5-32media b/gcc/config/sh/t-mlib-sh5-32media
new file mode 100644
index 00000000000..f03fd291153
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-32media
@@ -0,0 +1 @@
+ML_sh5_32media=m5-32media/
diff --git a/gcc/config/sh/t-mlib-sh5-32media-nofpu b/gcc/config/sh/t-mlib-sh5-32media-nofpu
new file mode 100644
index 00000000000..0d84f0eed77
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-32media-nofpu
@@ -0,0 +1 @@
+ML_sh5_32media_nofpu=m5-32media-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh5-64media b/gcc/config/sh/t-mlib-sh5-64media
new file mode 100644
index 00000000000..d324f62b5b8
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-64media
@@ -0,0 +1 @@
+ML_sh5_64media=m5-64media/
diff --git a/gcc/config/sh/t-mlib-sh5-64media-nofpu b/gcc/config/sh/t-mlib-sh5-64media-nofpu
new file mode 100644
index 00000000000..127bc47e45e
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-64media-nofpu
@@ -0,0 +1 @@
+ML_sh5_64media_nofpu=m5-64media-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh5-compact b/gcc/config/sh/t-mlib-sh5-compact
new file mode 100644
index 00000000000..e330c25e69e
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-compact
@@ -0,0 +1 @@
+ML_sh5_compact=m5-compact/
diff --git a/gcc/config/sh/t-mlib-sh5-compact-nofpu b/gcc/config/sh/t-mlib-sh5-compact-nofpu
new file mode 100644
index 00000000000..cf6afdc4d3c
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-compact-nofpu
@@ -0,0 +1 @@
+ML_sh5_compact_nofpu=m5-compact-nofpu/
diff --git a/gcc/config/t-slibgcc-darwin b/gcc/config/t-slibgcc-darwin
new file mode 100644
index 00000000000..34cb0d4160f
--- /dev/null
+++ b/gcc/config/t-slibgcc-darwin
@@ -0,0 +1,30 @@
+# Build a shared libgcc library with the darwin linker.
+SHLIB_MINOR = 1
+SHLIB_REVISION = 0
+SHLIB_VERSTRING = -compatibility_version $(SHLIB_MINOR) -current_version $(SHLIB_MINOR).$(SHLIB_REVISION)
+SHLIB_EXT = .dylib
+SHLIB_SOLINK = @shlib_base_name@.dylib
+SHLIB_SONAME = @shlib_so_name@.$(SHLIB_MINOR).$(SHLIB_REVISION).dylib
+SHLIB_NAME = @shlib_dir@@shlib_so_name@.$(SHLIB_MINOR).$(SHLIB_REVISION).dylib
+SHLIB_MAP = @shlib_map_file@
+SHLIB_OBJS = @shlib_objs@
+SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
+
+SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -dynamiclib -nodefaultlibs \
+ -Wl,-install_name,$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME) \
+ -Wl,-flat_namespace -o $(SHLIB_NAME) \
+ $(SHLIB_VERSTRING) \
+ @multilib_flags@ $(SHLIB_OBJS) -lc && \
+ rm -f $(SHLIB_SOLINK) && \
+ $(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
+# $(slibdir) double quoted to protect it from expansion while building
+# libgcc.mk. We want this delayed until actual install time.
+SHLIB_INSTALL = \
+ $$(mkinstalldirs) $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
+ $(INSTALL_DATA) $(SHLIB_NAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME); \
+ rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
+ $(LN_S) $(SHLIB_SONAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
+SHLIB_MKMAP = $(srcdir)/mkmap-symver.awk
+SHLIB_MAPFILES = $(srcdir)/libgcc-darwin.ver
diff --git a/gcc/config/vax/t-memfuncs b/gcc/config/vax/t-memfuncs
new file mode 100644
index 00000000000..6a8da6146b5
--- /dev/null
+++ b/gcc/config/vax/t-memfuncs
@@ -0,0 +1,3 @@
+LIB2FUNCS_EXTRA = \
+ $(srcdir)/config/memcmp.c $(srcdir)/config/memcpy.c \
+ $(srcdir)/config/memmove.c $(srcdir)/config/memset.c
diff --git a/gcc/config/x-linux b/gcc/config/x-linux
new file mode 100644
index 00000000000..d14586b0b36
--- /dev/null
+++ b/gcc/config/x-linux
@@ -0,0 +1,4 @@
+host-linux.o : $(srcdir)/config/host-linux.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h hosthooks.h hosthooks-def.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/host-linux.c
diff --git a/gcc/config/x-solaris b/gcc/config/x-solaris
new file mode 100644
index 00000000000..782f4a36802
--- /dev/null
+++ b/gcc/config/x-solaris
@@ -0,0 +1,4 @@
+host-solaris.o : $(srcdir)/config/host-solaris.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h hosthooks.h hosthooks-def.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/host-solaris.c
diff --git a/gcc/configure.ac b/gcc/configure.ac
new file mode 100644
index 00000000000..d965c1147b3
--- /dev/null
+++ b/gcc/configure.ac
@@ -0,0 +1,3257 @@
+# configure.ac for GCC
+# Process this file with autoconf to generate a configuration script.
+
+# Copyright 1997, 1998, 1999, 2000, 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.
+
+# --------------------------------
+# Initialization and sanity checks
+# --------------------------------
+
+AC_PREREQ(2.59)
+AC_INIT
+AC_CONFIG_SRCDIR(tree.c)
+AC_CONFIG_HEADER(auto-host.h:config.in)
+
+# Determine the host, build, and target systems
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+# Determine the noncanonical target name, for directory use.
+_GCC_TOPLEV_NONCANONICAL_TARGET
+
+# Determine the target- and build-specific subdirectories
+GCC_TOPLEV_SUBDIRS
+
+# Set program_transform_name
+AC_ARG_PROGRAM
+
+# Check for bogus environment variables.
+# Test if LIBRARY_PATH contains the notation for the current directory
+# since this would lead to problems installing/building glibc.
+# LIBRARY_PATH contains the current directory if one of the following
+# is true:
+# - one of the terminals (":" and ";") is the first or last sign
+# - two terminals occur directly after each other
+# - the path contains an element with a dot in it
+AC_MSG_CHECKING(LIBRARY_PATH variable)
+changequote(,)dnl
+case ${LIBRARY_PATH} in
+ [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
+ library_path_setting="contains current directory"
+ ;;
+ *)
+ library_path_setting="ok"
+ ;;
+esac
+changequote([,])dnl
+AC_MSG_RESULT($library_path_setting)
+if test "$library_path_setting" != "ok"; then
+AC_MSG_ERROR([
+*** LIBRARY_PATH shouldn't contain the current directory when
+*** building gcc. Please change the environment variable
+*** and run configure again.])
+fi
+
+# Test if GCC_EXEC_PREFIX contains the notation for the current directory
+# since this would lead to problems installing/building glibc.
+# GCC_EXEC_PREFIX contains the current directory if one of the following
+# is true:
+# - one of the terminals (":" and ";") is the first or last sign
+# - two terminals occur directly after each other
+# - the path contains an element with a dot in it
+AC_MSG_CHECKING(GCC_EXEC_PREFIX variable)
+changequote(,)dnl
+case ${GCC_EXEC_PREFIX} in
+ [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
+ gcc_exec_prefix_setting="contains current directory"
+ ;;
+ *)
+ gcc_exec_prefix_setting="ok"
+ ;;
+esac
+changequote([,])dnl
+AC_MSG_RESULT($gcc_exec_prefix_setting)
+if test "$gcc_exec_prefix_setting" != "ok"; then
+AC_MSG_ERROR([
+*** GCC_EXEC_PREFIX shouldn't contain the current directory when
+*** building gcc. Please change the environment variable
+*** and run configure again.])
+fi
+
+# -----------
+# Directories
+# -----------
+
+# Specify the local prefix
+local_prefix=
+AC_ARG_WITH(local-prefix,
+[ --with-local-prefix=DIR specifies directory to put local include],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for local include directory prefix) ;;
+no) ;;
+*) local_prefix=$with_local_prefix ;;
+esac])
+
+# Default local prefix if it is empty
+if test x$local_prefix = x; then
+ local_prefix=/usr/local
+fi
+
+# Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
+# passed in by the toplevel make and thus we'd get different behavior
+# depending on where we built the sources.
+gcc_gxx_include_dir=
+# Specify the g++ header file directory
+AC_ARG_WITH(gxx-include-dir,
+[ --with-gxx-include-dir=DIR
+ specifies directory to put g++ header files],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for g++ include directory) ;;
+no) ;;
+*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
+esac])
+
+if test x${gcc_gxx_include_dir} = x; then
+ if test x${enable_version_specific_runtime_libs} = xyes; then
+ gcc_gxx_include_dir='${libsubdir}/include/c++'
+ else
+ topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
+changequote(<<, >>)dnl
+ gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/"${libstdcxx_incdir}
+changequote([, ])dnl
+ fi
+fi
+
+AC_ARG_WITH(cpp_install_dir,
+[ --with-cpp-install-dir=DIR
+ install the user visible C preprocessor in DIR
+ (relative to PREFIX) as well as PREFIX/bin],
+[if test x$withval = xyes; then
+ AC_MSG_ERROR([option --with-cpp-install-dir requires an argument])
+elif test x$withval != xno; then
+ cpp_install_dir=$withval
+fi])
+
+# We would like to our source tree to be readonly. However when releases or
+# pre-releases are generated, the flex/bison generated files as well as the
+# various formats of manuals need to be included along with the rest of the
+# sources. Therefore we have --enable-generated-files-in-srcdir to do
+# just that.
+
+AC_MSG_CHECKING([whether to place generated files in the source directory])
+ dnl generated-files-in-srcdir is disabled by default
+ AC_ARG_ENABLE(generated-files-in-srcdir,
+[ --enable-generated-files-in-srcdir
+ put copies of generated files in source dir
+ intended for creating source tarballs for users
+ without texinfo bison or flex.],
+ generated_files_in_srcdir=$enableval,
+ generated_files_in_srcdir=no)
+
+AC_MSG_RESULT($generated_files_in_srcdir)
+
+if test "$generated_files_in_srcdir" = "yes"; then
+ GENINSRC=''
+else
+ GENINSRC='#'
+fi
+AC_SUBST(GENINSRC)
+
+# -------------------
+# Find default linker
+# -------------------
+
+# With GNU ld
+AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld arrange to work with GNU ld.],
+gnu_ld_flag="$with_gnu_ld",
+gnu_ld_flag=no)
+
+# With pre-defined ld
+AC_ARG_WITH(ld,
+[ --with-ld arrange to use the specified ld (full pathname)],
+DEFAULT_LINKER="$with_ld")
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_LINKER"; then
+ 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
+ AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$DEFAULT_LINKER",
+ [Define to enable the use of a default linker.])
+fi
+
+AC_MSG_CHECKING([whether a default linker was specified])
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test x"$gnu_ld_flag" = x"no"; then
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER)])
+ else
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER - GNU ld)])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+# With demangler in GNU ld
+AC_ARG_WITH(demangler-in-ld,
+[ --with-demangler-in-ld try to use demangler in GNU ld.],
+demangler_in_ld="$with_demangler_in_ld",
+demangler_in_ld=no)
+
+# ----------------------
+# Find default assembler
+# ----------------------
+
+# With GNU as
+AC_ARG_WITH(gnu-as,
+[ --with-gnu-as arrange to work with GNU as],
+gas_flag="$with_gnu_as",
+gas_flag=no)
+
+AC_ARG_WITH(as,
+[ --with-as arrange to use the specified as (full pathname)],
+DEFAULT_ASSEMBLER="$with_as")
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_ASSEMBLER"; then
+ 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
+ AC_DEFINE_UNQUOTED(DEFAULT_ASSEMBLER,"$DEFAULT_ASSEMBLER",
+ [Define to enable the use of a default assembler.])
+fi
+
+AC_MSG_CHECKING([whether a default assembler was specified])
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test x"$gas_flag" = x"no"; then
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER)])
+ else
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER - GNU as)])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+# ---------------
+# Find C compiler
+# ---------------
+
+# If a non-executable a.out is present (e.g. created by GNU as above even if
+# invoked with -v only), the IRIX 6 native ld just overwrites the existing
+# file, even when creating an executable, so an execution test fails.
+# Remove possible default executable files to avoid this.
+#
+# FIXME: This really belongs into AC_PROG_CC and can be removed once
+# Autoconf includes it.
+rm -f a.out a.exe b.out
+
+# Find the native compiler
+AC_PROG_CC
+AC_PROG_CC_C_O
+# autoconf is lame and doesn't give us any substitution variable for this.
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+ NO_MINUS_C_MINUS_O=yes
+else
+ OUTPUT_OPTION='-o $@'
+fi
+AC_SUBST(NO_MINUS_C_MINUS_O)
+AC_SUBST(OUTPUT_OPTION)
+
+# -------------------------
+# Check C compiler features
+# -------------------------
+
+AC_PROG_CPP
+AC_C_INLINE
+
+gcc_AC_C_LONG_LONG
+
+# sizeof(char) is 1 by definition.
+AC_COMPILE_CHECK_SIZEOF(void *)
+AC_COMPILE_CHECK_SIZEOF(short)
+AC_COMPILE_CHECK_SIZEOF(int)
+AC_COMPILE_CHECK_SIZEOF(long)
+if test $ac_cv_c_long_long = yes; then
+ AC_COMPILE_CHECK_SIZEOF(long long)
+fi
+if test $ac_cv_c___int64 = yes; then
+ AC_COMPILE_CHECK_SIZEOF(__int64)
+fi
+
+# ---------------------
+# Warnings and checking
+# ---------------------
+
+# Check $CC warning features (if it's GCC).
+# We want to use -pedantic, but we don't want warnings about
+# * 'long long'
+# * variadic macros
+# So, we only use -pedantic if we can disable those warnings.
+
+AC_CACHE_CHECK(
+ [whether ${CC} accepts -Wno-long-long],
+ [ac_cv_prog_cc_w_no_long_long],
+ [save_CFLAGS="$CFLAGS"
+ CFLAGS="-Wno-long-long"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])],
+ [ac_cv_prog_cc_w_no_long_long=yes],
+ [ac_cv_prog_cc_w_no_long_long=no])
+ CFLAGS="$save_CFLAGS"
+ ])
+
+AC_CACHE_CHECK(
+ [whether ${CC} accepts -Wno-variadic-macros],
+ [ac_cv_prog_cc_w_no_variadic_macros],
+ [save_CFLAGS="$CFLAGS"
+ CFLAGS="-Wno-variadic-macros"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])],
+ [ac_cv_prog_cc_w_no_variadic_macros=yes],
+ [ac_cv_prog_cc_w_no_variadic_macros=no])
+ CFLAGS="$save_CFLAGS"
+ ])
+
+strict1_warn=
+if test $ac_cv_prog_cc_w_no_long_long = yes \
+ && test $ac_cv_prog_cc_w_no_variadic_macros = yes ; then
+ strict1_warn="-pedantic -Wno-long-long -Wno-variadic-macros"
+fi
+AC_SUBST(strict1_warn)
+
+# Add -Wold-style-definition if it's accepted
+AC_CACHE_CHECK(
+ [whether ${CC} accepts -Wold-style-definition],
+ [ac_cv_prog_cc_w_old_style_definition],
+ [save_CFLAGS="$CFLAGS"
+ CFLAGS="-Wold-style-definition"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])],
+ [ac_cv_prog_cc_w_old_style_definition=yes],
+ [ac_cv_prog_cc_w_old_style_definition=no])
+ CFLAGS="$save_CFLAGS"
+ ])
+if test $ac_cv_prog_cc_w_old_style_definition = yes ; then
+ strict1_warn="${strict1_warn} -Wold-style-definition"
+fi
+
+# Enable -Werror, period.
+AC_ARG_ENABLE(werror_always,
+[ --enable-werror-always enable -Werror always], [],
+[enable_werror_always=no])
+if test x${enable_werror_always} = xyes ; then
+ strict1_warn="${strict1_warn} -Werror"
+ WERROR=-Werror
+fi
+
+# If the native compiler is GCC, we can enable warnings even in stage1.
+# That's useful for people building cross-compilers, or just running a
+# quick `make'.
+warn_cflags=
+if test "x$GCC" = "xyes"; then
+ warn_cflags='$(GCC_WARN_CFLAGS)'
+fi
+AC_SUBST(warn_cflags)
+
+# Enable -Werror in bootstrap stage2 and later.
+# Change the default to "no" on release branches.
+AC_ARG_ENABLE(werror,
+[ --enable-werror enable -Werror in bootstrap stage2 and later], [],
+[enable_werror=yes])
+if test x$enable_werror = xyes ; then
+ WERROR=-Werror
+fi
+AC_SUBST(WERROR)
+
+# Enable expensive internal checks
+AC_ARG_ENABLE(checking,
+[ --enable-checking[=LIST]
+ enable expensive run-time checks. With LIST,
+ enable only specific categories of checks.
+ Categories are: misc,tree,rtl,rtlflag,gc,gcac,fold;
+ default is misc,tree,gc,rtlflag],
+[ac_checking=
+ac_tree_checking=
+ac_rtl_checking=
+ac_rtlflag_checking=
+ac_gc_checking=
+ac_gc_always_collect=
+ac_fold_checking=
+case "${enableval}" in
+yes) ac_checking=1 ; ac_tree_checking=1 ; ac_gc_checking=1 ;
+ ac_rtlflag_checking=1 ;;
+no) ;;
+*) IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS,"
+ set fnord $enableval; shift
+ IFS="$ac_save_IFS"
+ for check
+ do
+ case $check in
+ misc) ac_checking=1 ;;
+ tree) ac_tree_checking=1 ;;
+ rtlflag) ac_rtlflag_checking=1 ;;
+ rtl) ac_rtl_checking=1 ;;
+ gc) ac_gc_checking=1 ;;
+ gcac) ac_gc_always_collect=1 ;;
+ fold) ac_fold_checking=1 ;;
+ valgrind) ac_checking_valgrind=1 ;;
+ *) AC_MSG_ERROR(unknown check category $check) ;;
+ esac
+ done
+ ;;
+esac
+],
+# Enable some checks by default for development versions of GCC
+[ac_checking=1; ac_tree_checking=1; ac_gc_checking=1; ac_rtlflag_checking=1;])
+nocommon_flag=""
+if test x$ac_checking != x ; then
+ AC_DEFINE(ENABLE_CHECKING, 1,
+[Define if you want more run-time sanity checks. This one gets a grab
+ bag of miscellaneous but relatively cheap checks.])
+ nocommon_flag=-fno-common
+fi
+AC_SUBST(nocommon_flag)
+if test x$ac_tree_checking != x ; then
+ AC_DEFINE(ENABLE_TREE_CHECKING, 1,
+[Define if you want all operations on trees (the basic data
+ structure of the front ends) to be checked for dynamic type safety
+ at runtime. This is moderately expensive. The tree browser debugging
+ routines will also be enabled by this option.
+ ])
+ TREEBROWSER=tree-browser.o
+fi
+AC_SUBST(TREEBROWSER)
+if test x$ac_rtl_checking != x ; then
+ AC_DEFINE(ENABLE_RTL_CHECKING, 1,
+[Define if you want all operations on RTL (the basic data structure
+ of the optimizer and back end) to be checked for dynamic type safety
+ at runtime. This is quite expensive.])
+fi
+if test x$ac_rtlflag_checking != x ; then
+ AC_DEFINE(ENABLE_RTL_FLAG_CHECKING, 1,
+[Define if you want RTL flag accesses to be checked against the RTL
+ codes that are supported for each access macro. This is relatively
+ cheap.])
+fi
+if test x$ac_gc_checking != x ; then
+ AC_DEFINE(ENABLE_GC_CHECKING, 1,
+[Define if you want the garbage collector to do object poisoning and
+ other memory allocation checks. This is quite expensive.])
+fi
+if test x$ac_gc_always_collect != x ; then
+ AC_DEFINE(ENABLE_GC_ALWAYS_COLLECT, 1,
+[Define if you want the garbage collector to operate in maximally
+ paranoid mode, validating the entire heap and collecting garbage at
+ every opportunity. This is extremely expensive.])
+fi
+if test x$ac_fold_checking != x ; then
+ AC_DEFINE(ENABLE_FOLD_CHECKING, 1,
+[Define if you want fold checked that it never destructs its argument.
+ This is quite expensive.])
+fi
+valgrind_path_defines=
+valgrind_command=
+
+dnl # This check AC_REQUIREs various stuff, so it *must not* be inside
+dnl # an if statement. This was the source of very frustrating bugs
+dnl # in converting to autoconf 2.5x!
+AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
+
+if test x$ac_checking_valgrind != x ; then
+ # It is certainly possible that there's valgrind but no valgrind.h.
+ # GCC relies on making annotations so we must have both.
+ AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
+ AC_TRY_CPP(
+ [#include <valgrind/memcheck.h>
+#ifndef VALGRIND_DISCARD
+#error VALGRIND_DISCARD not defined
+#endif],
+ [gcc_cv_header_valgrind_memcheck_h=yes],
+ [gcc_cv_header_valgrind_memcheck_h=no])
+ AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
+ AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
+ AC_TRY_CPP(
+ [#include <memcheck.h>
+#ifndef VALGRIND_DISCARD
+#error VALGRIND_DISCARD not defined
+#endif],
+ [gcc_cv_header_memcheck_h=yes],
+ gcc_cv_header_memcheck_h=no)
+ AC_MSG_RESULT($gcc_cv_header_memcheck_h)
+ AM_PATH_PROG_WITH_TEST(valgrind_path, valgrind,
+ [$ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1])
+ if test "x$valgrind_path" = "x" \
+ || (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ AC_MSG_ERROR([*** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h])
+ fi
+ valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
+ valgrind_command="$valgrind_path -q"
+ AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1,
+[Define if you want to run subprograms and generated programs
+ through valgrind (a memory checker). This is extremely expensive.])
+ if test $gcc_cv_header_valgrind_memcheck_h = yes; then
+ AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
+ [Define if valgrind's valgrind/memcheck.h header is installed.])
+ fi
+ if test $gcc_cv_header_memcheck_h = yes; then
+ AC_DEFINE(HAVE_MEMCHECK_H, 1,
+ [Define if valgrind's memcheck.h header is installed.])
+ fi
+fi
+AC_SUBST(valgrind_path_defines)
+AC_SUBST(valgrind_command)
+
+AC_ARG_ENABLE(mapped-location,
+[ --enable-mapped-location location_t is fileline integer cookie],,
+enable_mapped_location=no)
+
+if test "$enable_mapped_location" = yes ; then
+ AC_DEFINE(USE_MAPPED_LOCATION, 1,
+[Define if location_t is fileline integer cookie.])
+fi
+
+# Enable code coverage collection
+AC_ARG_ENABLE(coverage,
+[ --enable-coverage[=LEVEL]
+ enable compiler\'s code coverage collection.
+ Use to measure compiler performance and locate
+ unused parts of the compiler. With LEVEL, specify
+ optimization. Values are opt, noopt,
+ default is noopt],
+[case "${enableval}" in
+ yes|noopt)
+ coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O0"
+ ;;
+ opt)
+ coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O2"
+ ;;
+ no)
+ # a.k.a. --disable-coverage
+ coverage_flags=""
+ ;;
+ *)
+ AC_MSG_ERROR(unknown coverage setting $enableval)
+ ;;
+esac],
+[coverage_flags=""])
+AC_SUBST(coverage_flags)
+
+AC_ARG_ENABLE(gather-detailed-mem-stats,
+[ --enable-gather-detailed-mem-stats enable detailed memory allocation stats gathering], [],
+[enable_gather_detailed_mem_stats=no])
+if test x$enable_gather_detailed_mem_stats = xyes ; then
+ AC_DEFINE(GATHER_STATISTICS, 1,
+ [Define to enable detailed memory allocation stats gathering.])
+fi
+
+# -------------------------------
+# Miscenalleous configure options
+# -------------------------------
+
+# With stabs
+AC_ARG_WITH(stabs,
+[ --with-stabs arrange to use stabs instead of host debug format],
+stabs="$with_stabs",
+stabs=no)
+
+# Determine whether or not multilibs are enabled.
+AC_ARG_ENABLE(multilib,
+[ --enable-multilib enable library support for multiple ABIs],
+[], [enable_multilib=yes])
+AC_SUBST(enable_multilib)
+
+# Enable __cxa_atexit for C++.
+AC_ARG_ENABLE(__cxa_atexit,
+[ --enable-__cxa_atexit enable __cxa_atexit for C++],
+[], [])
+
+# Enable threads
+# Pass with no value to take the default
+# Pass with a value to specify a thread package
+AC_ARG_ENABLE(threads,
+[ --enable-threads enable thread usage for target GCC
+ --enable-threads=LIB use LIB thread package for target GCC],,
+[enable_threads=''])
+
+AC_ARG_ENABLE(objc-gc,
+[ --enable-objc-gc enable the use of Boehm's garbage collector with
+ the GNU Objective-C runtime],
+if test x$enable_objc_gc = xno; then
+ objc_boehm_gc=''
+else
+ objc_boehm_gc=1
+fi,
+objc_boehm_gc='')
+
+AC_ARG_WITH(dwarf2,
+[ --with-dwarf2 force the default debug format to be DWARF 2],
+dwarf2="$with_dwarf2",
+dwarf2=no)
+
+AC_ARG_ENABLE(shared,
+[ --disable-shared don't provide a shared libgcc],
+[
+ case $enable_shared in
+ yes | no) ;;
+ *)
+ enable_shared=no
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "Xgcc" || test "X$pkg" = "Xlibgcc"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+ esac
+], [enable_shared=yes])
+AC_SUBST(enable_shared)
+
+AC_ARG_WITH(sysroot,
+[ --with-sysroot[=DIR] Search for usr/lib, usr/include, et al, within DIR.],
+[
+ case ${with_sysroot} in
+ yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_noncanonical}/sys-root' ;;
+ *) TARGET_SYSTEM_ROOT=$with_sysroot ;;
+ esac
+
+ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
+ CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR)'
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+ case ${TARGET_SYSTEM_ROOT} in
+ "${test_prefix}"|"${test_prefix}/"*|\
+ '${exec_prefix}'|'${exec_prefix}/'*)
+ t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE"
+ TARGET_SYSTEM_ROOT_DEFINE="$t"
+ ;;
+ esac
+], [
+ TARGET_SYSTEM_ROOT=
+ TARGET_SYSTEM_ROOT_DEFINE=
+ CROSS_SYSTEM_HEADER_DIR='$(gcc_tooldir)/sys-include'
+])
+AC_SUBST(TARGET_SYSTEM_ROOT)
+AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
+AC_SUBST(CROSS_SYSTEM_HEADER_DIR)
+
+# Build with intermodule optimisations
+AC_ARG_ENABLE(intermodule,
+[ --enable-intermodule build the compiler in one step],
+[case ${enable_intermodule} in
+ yes) onestep="-onestep";;
+ *) onestep="";;
+esac],
+[onestep=""])
+AC_SUBST(onestep)
+
+# Sanity check enable_languages in case someone does not run the toplevel
+# configure # script.
+AC_ARG_ENABLE(languages,
+[ --enable-languages=LIST specify which front-ends to build],
+[case ,${enable_languages}, in
+ ,,|,yes,)
+ # go safe -- we cannot be much sure without the toplevel
+ # configure's
+ # analysis of which target libs are present and usable
+ enable_languages=c
+ ;;
+ *,all,*)
+ AC_MSG_ERROR([only the toplevel supports --enable-languages=all])
+ ;;
+ *,c,*)
+ ;;
+ *)
+ enable_languages=c,${enable_languages}
+ ;;
+esac],
+[enable_languages=c])
+
+subdirs=
+for lang in ${srcdir}/*/config-lang.in
+do
+ case $lang in
+ # The odd quoting in the next line works around
+ # an apparent bug in bash 1.12 on linux.
+changequote(,)dnl
+ ${srcdir}/[*]/config-lang.in) ;;
+ *)
+ lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang`
+ if test "x$lang_alias" = x
+ then
+ echo "$lang doesn't set \$language." 1>&2
+ exit 1
+ fi
+ case ",$enable_languages," in
+ *,$lang_alias,*)
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`" ;;
+ esac
+ ;;
+changequote([,])dnl
+ esac
+done
+
+
+# -------------------------
+# Checks for other programs
+# -------------------------
+
+AC_PROG_MAKE_SET
+
+# Find some useful tools
+AC_PROG_AWK
+# We need awk to create options.c and options.h.
+# Bail out if it's missing.
+case ${AWK} in
+ "") AC_MSG_ERROR([can't build without awk, bailing out]) ;;
+esac
+
+gcc_AC_PROG_LN_S
+ACX_PROG_LN($LN_S)
+AC_PROG_RANLIB
+case "${host}" in
+*-*-darwin*)
+ # By default, the Darwin ranlib will not treat common symbols as
+ # definitions when building the archive table of contents. Other
+ # ranlibs do that; pass an option to the Darwin ranlib that makes
+ # it behave similarly.
+ ranlib_flags="-c"
+ ;;
+*)
+ ranlib_flags=""
+esac
+AC_SUBST(ranlib_flags)
+
+gcc_AC_PROG_INSTALL
+
+# See if cmp has --ignore-initial.
+gcc_AC_PROG_CMP_IGNORE_INITIAL
+
+# See if we have the mktemp command.
+AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no)
+
+# Do we have a single-tree copy of texinfo?
+if test -f $srcdir/../texinfo/Makefile.in; then
+ MAKEINFO='$(objdir)/../texinfo/makeinfo/makeinfo'
+ gcc_cv_prog_makeinfo_modern=yes
+ AC_MSG_RESULT([Using makeinfo from the unified source tree.])
+else
+ # See if makeinfo has been installed and is modern enough
+ # that we can use it.
+ gcc_AC_CHECK_PROG_VER(MAKEINFO, makeinfo, --version,
+ [GNU texinfo.* \([0-9][0-9.]*\)],
+ [4.[2-9]*])
+fi
+
+if test $gcc_cv_prog_makeinfo_modern = no; then
+ AC_MSG_WARN([
+*** Makeinfo is missing or too old.
+*** Info documentation will not be built.])
+ BUILD_INFO=
+else
+ BUILD_INFO=info AC_SUBST(BUILD_INFO)
+fi
+
+# Is pod2man recent enough to regenerate manpages?
+AC_MSG_CHECKING([for recent Pod::Man])
+if (perl -e 'use 1.10 Pod::Man') >/dev/null 2>&1; then
+ AC_MSG_RESULT(yes)
+ GENERATED_MANPAGES=generated-manpages AC_SUBST(GENERATED_MANPAGES)
+else
+ AC_MSG_RESULT(no)
+ GENERATED_MANPAGES=
+fi
+
+# How about lex?
+dnl Don't use AC_PROG_LEX; we insist on flex.
+dnl LEXLIB is not useful in gcc.
+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)
+fi
+
+# Bison?
+# The -L switch is so bison can find its skeleton file.
+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)
+fi
+
+# --------------------
+# Checks for C headers
+# --------------------
+
+AC_MSG_CHECKING(for GNU C library)
+AC_CACHE_VAL(gcc_cv_glibc,
+[AC_TRY_COMPILE(
+ [#include <features.h>],[
+#if ! (defined __GLIBC__ || defined __GNU_LIBRARY__)
+#error Not a GNU C library system
+#endif],
+ [gcc_cv_glibc=yes],
+ gcc_cv_glibc=no)])
+AC_MSG_RESULT($gcc_cv_glibc)
+if test $gcc_cv_glibc = yes; then
+ AC_DEFINE(_GNU_SOURCE, 1, [Always define this when using the GNU C Library])
+fi
+
+# Need to reject headers which give warnings, so that the -Werror bootstrap
+# works later. *sigh* This needs to come before all header checks.
+AC_PROG_CPP_WERROR
+
+AC_HEADER_STDC
+AC_HEADER_TIME
+ACX_HEADER_STRING
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h \
+ fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
+ sys/resource.h sys/param.h sys/times.h sys/stat.h \
+ direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
+
+# Check for thread headers.
+AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
+AC_CHECK_HEADER(pthread.h, [have_pthread_h=yes], [have_pthread_h=])
+
+# These tests can't be done till we know if we have limits.h.
+gcc_AC_C_CHAR_BIT
+AC_C_BIGENDIAN_CROSS
+
+# --------
+# UNSORTED
+# --------
+
+# Stage specific cflags for build.
+stage1_cflags=
+case $build in
+vax-*-*)
+ if test x$GCC = xyes
+ then
+ stage1_cflags="-Wa,-J"
+ else
+ stage1_cflags="-J"
+ fi
+ ;;
+powerpc-*-darwin*)
+ # The spiffy cpp-precomp chokes on some legitimate constructs in GCC
+ # sources; use -no-cpp-precomp to get to GNU cpp.
+ # Apple's GCC has bugs in designated initializer handling, so disable
+ # that too.
+ stage1_cflags="-no-cpp-precomp -DHAVE_DESIGNATED_INITIALIZERS=0"
+ ;;
+esac
+AC_SUBST(stage1_cflags)
+
+# These libraries may be used by collect2.
+# We may need a special search path to get them linked.
+AC_CACHE_CHECK(for collect2 libraries, gcc_cv_collect2_libs,
+[save_LIBS="$LIBS"
+for libs in '' -lld -lmld \
+ '-L/usr/lib/cmplrs/cc2.11 -lmld' \
+ '-L/usr/lib/cmplrs/cc3.11 -lmld'
+do
+ LIBS="$libs"
+ AC_TRY_LINK_FUNC(ldopen,
+ [gcc_cv_collect2_libs="$libs"; break])
+done
+LIBS="$save_LIBS"
+test -z "$gcc_cv_collect2_libs" && gcc_cv_collect2_libs='none required'])
+case $gcc_cv_collect2_libs in
+ "none required") ;;
+ *) COLLECT2_LIBS=$gcc_cv_collect2_libs ;;
+esac
+AC_SUBST(COLLECT2_LIBS)
+
+# When building Ada code on Alpha, we need exc_resume which is usually in
+# -lexc. So test for it.
+save_LIBS="$LIBS"
+LIBS=
+AC_SEARCH_LIBS(exc_resume, exc)
+GNAT_LIBEXC="$LIBS"
+LIBS="$save_LIBS"
+AC_SUBST(GNAT_LIBEXC)
+
+# Some systems put ldexp and frexp in libm instead of libc; assume
+# they're both in the same place. jcf-dump needs them.
+save_LIBS="$LIBS"
+LIBS=
+AC_SEARCH_LIBS(ldexp, m)
+LDEXP_LIB="$LIBS"
+LIBS="$save_LIBS"
+AC_SUBST(LDEXP_LIB)
+
+# Use <inttypes.h> only if it exists,
+# doesn't clash with <sys/types.h>, and declares intmax_t.
+AC_MSG_CHECKING(for inttypes.h)
+AC_CACHE_VAL(gcc_cv_header_inttypes_h,
+[AC_TRY_COMPILE(
+ [#include <sys/types.h>
+#include <inttypes.h>],
+ [intmax_t i = -1;],
+ [gcc_cv_header_inttypes_h=yes],
+ gcc_cv_header_inttypes_h=no)])
+AC_MSG_RESULT($gcc_cv_header_inttypes_h)
+if test $gcc_cv_header_inttypes_h = yes; then
+ AC_DEFINE(HAVE_INTTYPES_H, 1,
+ [Define if you have a working <inttypes.h> header file.])
+fi
+
+dnl Disabled until we have a complete test for buggy enum bitfields.
+dnl gcc_AC_C_ENUM_BF_UNSIGNED
+
+AC_CHECK_FUNCS(times clock dup2 kill getrlimit setrlimit atoll atoq \
+ sysconf strsignal putc_unlocked fputc_unlocked fputs_unlocked \
+ fwrite_unlocked fprintf_unlocked getrusage nl_langinfo \
+ scandir alphasort gettimeofday mbstowcs wcswidth mmap mincore \
+ setlocale)
+
+if test x$ac_cv_func_mbstowcs = xyes; then
+ AC_CACHE_CHECK(whether mbstowcs works, gcc_cv_func_mbstowcs_works,
+[ AC_TRY_RUN([#include <stdlib.h>
+int main()
+{
+ mbstowcs(0, "", 0);
+ return 0;
+}],
+ gcc_cv_func_mbstowcs_works=yes,
+ gcc_cv_func_mbstowcs_works=no,
+ gcc_cv_func_mbstowcs_works=yes)])
+ if test x$gcc_cv_func_mbstowcs_works = xyes; then
+ AC_DEFINE(HAVE_WORKING_MBSTOWCS, 1,
+ [Define this macro if mbstowcs does not crash when its
+ first argument is NULL.])
+ fi
+fi
+
+AC_CHECK_TYPE(ssize_t, int)
+
+# Try to determine the array type of the second argument of getgroups
+# for the target system (int or gid_t).
+AC_TYPE_GETGROUPS
+if test "${target}" = "${build}"; then
+ TARGET_GETGROUPS_T=$ac_cv_type_getgroups
+else
+ case "${target}" in
+ # This condition may need some tweaking. It should include all
+ # targets where the array type of the second argument of getgroups
+ # is int and the type of gid_t is not equivalent to int.
+ *-*-sunos* | *-*-ultrix*)
+ TARGET_GETGROUPS_T=int
+ ;;
+ *)
+ TARGET_GETGROUPS_T=gid_t
+ ;;
+ esac
+fi
+AC_SUBST(TARGET_GETGROUPS_T)
+
+gcc_AC_FUNC_PRINTF_PTR
+gcc_AC_FUNC_MMAP_BLACKLIST
+
+case "${host}" in
+*-*-*vms*)
+ # Under VMS, vfork works very differently than on Unix. The standard test
+ # won't work, and it isn't easily adaptable. It makes more sense to
+ # just force it.
+ ac_cv_func_vfork_works=yes
+ ;;
+esac
+AC_FUNC_VFORK
+
+AM_ICONV
+# Until we have in-tree GNU iconv:
+LIBICONV_DEP=
+AC_SUBST(LIBICONV_DEP)
+
+AM_LC_MESSAGES
+
+# We will need to find libiberty.h and ansidecl.h
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include"
+gcc_AC_CHECK_DECLS(getenv atol sbrk abort atof getcwd getwd \
+ strsignal putc_unlocked fputs_unlocked fwrite_unlocked \
+ fprintf_unlocked strstr errno snprintf vasprintf \
+ malloc realloc calloc free basename getopt clock, , ,[
+#include "ansidecl.h"
+#include "system.h"])
+
+gcc_AC_CHECK_DECLS(getrlimit setrlimit getrusage, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+])
+
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+],[rlim_t l = 0;],,[AC_DEFINE([rlim_t],[long],
+[Define to \`long' if <sys/resource.h> doesn't define.])])
+
+gcc_AC_CHECK_DECLS(ldgetname, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_LDFCN_H
+#include <ldfcn.h>
+#endif
+])
+
+gcc_AC_CHECK_DECLS(times, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+])
+
+# More time-related stuff.
+AC_CACHE_CHECK(for struct tms, ac_cv_struct_tms, [
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+], [struct tms tms;], ac_cv_struct_tms=yes, ac_cv_struct_tms=no)])
+if test $ac_cv_struct_tms = yes; then
+ AC_DEFINE(HAVE_STRUCT_TMS, 1,
+ [Define if <sys/times.h> defines struct tms.])
+fi
+
+# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
+# revisit after autoconf 2.50.
+AC_CACHE_CHECK(for clock_t, gcc_cv_type_clock_t, [
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+], [clock_t x;], gcc_cv_type_clock_t=yes, gcc_cv_type_clock_t=no)])
+if test $gcc_cv_type_clock_t = yes; then
+ AC_DEFINE(HAVE_CLOCK_T, 1,
+ [Define if <time.h> defines clock_t.])
+fi
+
+# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
+CFLAGS="$saved_CFLAGS"
+
+gcc_AC_INITFINI_ARRAY
+
+# mkdir takes a single argument on some systems.
+gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
+
+# File extensions
+manext='.1'
+objext='.o'
+AC_SUBST(manext)
+AC_SUBST(objext)
+
+# With Setjmp/Longjmp based exception handling.
+AC_ARG_ENABLE(sjlj-exceptions,
+[ --enable-sjlj-exceptions
+ arrange to use setjmp/longjmp exception handling],
+[sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
+AC_DEFINE_UNQUOTED(CONFIG_SJLJ_EXCEPTIONS, $sjlj,
+ [Define 0/1 to force the choice for exception handling model.])])
+
+if test x$host = x$target; then
+ AC_CHECK_LIB(unwind, main, use_libunwind_default=yes, use_libunwind_default=no)
+else
+ use_libunwind_default=no
+fi
+# Use libunwind based exception handling.
+AC_ARG_ENABLE(libunwind-exceptions,
+[ --enable-libunwind-exceptions force use libunwind for exceptions],
+use_libunwind_exceptions=$enableval,
+use_libunwind_exceptions=$use_libunwind_default)
+if test x"$use_libunwind_exceptions" = xyes; then
+ AC_DEFINE(USE_LIBUNWIND_EXCEPTIONS, 1,
+ [Define if gcc should use -lunwind.])
+fi
+
+# --------------------------------------------------------
+# Build, host, and target specific configuration fragments
+# --------------------------------------------------------
+
+# Collect build-machine-specific information.
+. ${srcdir}/config.build
+
+# Collect host-machine-specific information.
+. ${srcdir}/config.host
+
+target_gtfiles=
+
+# Collect target-machine-specific information.
+. ${srcdir}/config.gcc
+
+extra_objs="${host_extra_objs} ${extra_objs}"
+extra_gcc_objs="${host_extra_gcc_objs} ${extra_gcc_objs}"
+
+# Default the target-machine variables that were not explicitly set.
+if test x"$tm_file" = x
+then tm_file=$cpu_type/$cpu_type.h; fi
+
+if test x"$extra_headers" = x
+then extra_headers=; fi
+
+if test x$md_file = x
+then md_file=$cpu_type/$cpu_type.md; fi
+
+if test x$out_file = x
+then out_file=$cpu_type/$cpu_type.c; fi
+
+if test x"$tmake_file" = x
+then tmake_file=$cpu_type/t-$cpu_type
+fi
+
+if test x"$dwarf2" = xyes
+then tm_file="$tm_file tm-dwarf2.h"
+fi
+
+# Say what files are being used for the output code and MD file.
+echo "Using \`$srcdir/config/$out_file' for machine-specific logic."
+echo "Using \`$srcdir/config/$md_file' as machine description file."
+
+# If any of the xm_file variables contain nonexistent files, warn
+# about them and drop them.
+
+bx=
+for x in $build_xm_file; do
+ if test -f $srcdir/config/$x
+ then bx="$bx $x"
+ else AC_MSG_WARN($srcdir/config/$x does not exist.)
+ fi
+done
+build_xm_file="$bx"
+
+hx=
+for x in $host_xm_file; do
+ if test -f $srcdir/config/$x
+ then hx="$hx $x"
+ else AC_MSG_WARN($srcdir/config/$x does not exist.)
+ fi
+done
+host_xm_file="$hx"
+
+tx=
+for x in $xm_file; do
+ if test -f $srcdir/config/$x
+ then tx="$tx $x"
+ else AC_MSG_WARN($srcdir/config/$x does not exist.)
+ fi
+done
+xm_file="$tx"
+
+count=a
+for f in $tm_file; do
+ count=${count}x
+done
+if test $count = ax; then
+ echo "Using \`$srcdir/config/$tm_file' as target machine macro file."
+else
+ echo "Using the following target machine macro files:"
+ for f in $tm_file; do
+ echo " $srcdir/config/$f"
+ done
+fi
+
+if test x$need_64bit_hwint = xyes; then
+ AC_DEFINE(NEED_64BIT_HOST_WIDE_INT, 1,
+[Define to 1 if HOST_WIDE_INT must be 64 bits wide (see hwint.h).])
+fi
+
+count=a
+for f in $host_xm_file; do
+ count=${count}x
+done
+if test $count = a; then
+ :
+elif test $count = ax; then
+ echo "Using \`$srcdir/config/$host_xm_file' as host machine macro file."
+else
+ echo "Using the following host machine macro files:"
+ for f in $host_xm_file; do
+ echo " $srcdir/config/$f"
+ done
+fi
+echo "Using ${out_host_hook_obj} for host machine hooks."
+
+if test "$host_xm_file" != "$build_xm_file"; then
+ count=a
+ for f in $build_xm_file; do
+ count=${count}x
+ done
+ if test $count = a; then
+ :
+ elif test $count = ax; then
+ echo "Using \`$srcdir/config/$build_xm_file' as build machine macro file."
+ else
+ echo "Using the following build machine macro files:"
+ for f in $build_xm_file; do
+ echo " $srcdir/config/$f"
+ done
+ fi
+fi
+
+# ---------
+# Threading
+# ---------
+
+# Check if a valid thread package
+case ${enable_threads} in
+ "" | no)
+ # No threads
+ target_thread_file='single'
+ ;;
+ yes)
+ # default
+ target_thread_file='single'
+ ;;
+ aix | dce | gnat | irix | posix | rtems | \
+ single | solaris | vxworks | win32 )
+ target_thread_file=${enable_threads}
+ ;;
+ *)
+ echo "${enable_threads} is an unknown thread package" 1>&2
+ exit 1
+ ;;
+esac
+
+if test x${thread_file} = x; then
+ # No thread file set by target-specific clauses in config.gcc,
+ # so use file chosen by default logic above
+ thread_file=${target_thread_file}
+fi
+
+# Make gthr-default.h if we have a thread file.
+gthread_flags=
+if test $thread_file != single; then
+ rm -f gthr-default.h
+ echo "#include \"gthr-${thread_file}.h\"" > gthr-default.h
+ gthread_flags=-DHAVE_GTHR_DEFAULT
+fi
+AC_SUBST(gthread_flags)
+
+# --------
+# UNSORTED
+# --------
+
+if test x$enable___cxa_atexit = xyes || \
+ test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then
+ AC_CHECK_FUNC(__cxa_atexit,
+ [AC_DEFINE(DEFAULT_USE_CXA_ATEXIT, 1,
+ [Define if you want to use __cxa_atexit, rather than atexit, to
+ register C++ destructors for local statics and global objects.
+ This is essential for fully standards-compliant handling of
+ destructors, but requires __cxa_atexit in libc.])],
+ echo "__cxa_atexit can't be enabled on this target")
+fi
+
+# Look for a file containing extra machine modes.
+if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
+ extra_modes_file='$(srcdir)'/config/${extra_modes}
+ AC_SUBST(extra_modes_file)
+ AC_DEFINE_UNQUOTED(EXTRA_MODES_FILE, "config/$extra_modes",
+ [Define to the name of a file containing a list of extra machine modes
+ for this architecture.])
+fi
+
+# auto-host.h is the file containing items generated by autoconf and is
+# the first file included by config.h.
+# If host=build, it is correct to have bconfig include auto-host.h
+# as well. If host!=build, we are in error and need to do more
+# work to find out the build config parameters.
+if test x$host = x$build
+then
+ build_auto=auto-host.h
+ FORBUILD=..
+else
+ # We create a subdir, then run autoconf in the subdir.
+ # To prevent recursion we set host and build for the new
+ # invocation of configure to the build for this invocation
+ # of configure.
+ tempdir=build.$$
+ rm -rf $tempdir
+ mkdir $tempdir
+ cd $tempdir
+ case ${srcdir} in
+ /* | [A-Za-z]:[\\/]* ) realsrcdir=${srcdir};;
+ *) realsrcdir=../${srcdir};;
+ esac
+ saved_CFLAGS="${CFLAGS}"
+ CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
+ ${realsrcdir}/configure \
+ --enable-languages=${enable_languages-all} \
+ --target=$target_alias --host=$build_alias --build=$build_alias
+ CFLAGS="${saved_CFLAGS}"
+
+ # We just finished tests for the build machine, so rename
+ # the file auto-build.h in the gcc directory.
+ mv auto-host.h ../auto-build.h
+ cd ..
+ rm -rf $tempdir
+ build_auto=auto-build.h
+ FORBUILD=../${build_subdir}
+fi
+AC_SUBST(FORBUILD)
+
+tm_file="${tm_file} defaults.h"
+tm_p_file="${tm_p_file} tm-preds.h"
+host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
+build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
+# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
+# put this back in temporarily.
+xm_file="ansidecl.h ${xm_file}"
+
+# --------
+# UNSORTED
+# --------
+
+# Get the version trigger filename from the toplevel
+if test "${with_gcc_version_trigger+set}" = set; then
+ gcc_version_trigger=$with_gcc_version_trigger
+else
+ gcc_version_trigger=${srcdir}/version.c
+fi
+changequote(,)dnl
+gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*"\([^"]*\)".*/\1/'`
+gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
+
+# Compile in configure arguments.
+if test -f configargs.h ; then
+ # Being re-configured.
+ gcc_config_arguments=`grep configuration_arguments configargs.h | sed -e 's/.*"\([^"]*\)".*/\1/'`
+ gcc_config_arguments="$gcc_config_arguments : (reconfigured) $TOPLEVEL_CONFIGURE_ARGUMENTS"
+else
+ gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
+fi
+
+# Double all backslashes and backslash all quotes to turn
+# gcc_config_arguments into a C string.
+sed -e 's/\\/\\\\/g; s/"/\\"/g' <<EOF >conftest.out
+$gcc_config_arguments
+EOF
+gcc_config_arguments_str=`cat conftest.out`
+rm -f conftest.out
+
+cat > configargs.h <<EOF
+/* Generated automatically. */
+static const char configuration_arguments[] = "$gcc_config_arguments_str";
+static const char thread_model[] = "$thread_file";
+
+static const struct {
+ const char *name, *value;
+} configure_default_options[] = $configure_default_options;
+EOF
+changequote([,])dnl
+
+# Internationalization
+PACKAGE=gcc
+VERSION="$gcc_version"
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+ZW_GNU_GETTEXT_SISTER_DIR
+
+# If LIBINTL contains LIBICONV, then clear LIBICONV so we don't get
+# -liconv on the link line twice.
+case "$LIBINTL" in *$LIBICONV*)
+ LIBICONV= ;;
+esac
+
+# Windows32 Registry support for specifying GCC installation paths.
+AC_ARG_ENABLE(win32-registry,
+[ --disable-win32-registry
+ disable lookup of installation paths in the
+ Registry on Windows hosts
+ --enable-win32-registry enable registry lookup (default)
+ --enable-win32-registry=KEY
+ use KEY instead of GCC version as the last portion
+ of the registry key],,)
+case $host_os in
+ win32 | pe | cygwin* | mingw32* | uwin*)
+AC_MSG_CHECKING(whether windows registry support is requested)
+if test "x$enable_win32_registry" != xno; then
+ AC_DEFINE(ENABLE_WIN32_REGISTRY, 1,
+[Define to 1 if installation paths should be looked up in Windows32
+ Registry. Ignored on non windows32 hosts.])
+ AC_MSG_RESULT(yes)
+ AC_SEARCH_LIBS(RegOpenKeyExA, advapi32)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# Check if user specified a different registry key.
+case "x${enable_win32_registry}" in
+x | xyes)
+ # default.
+ gcc_cv_win32_registry_key="$VERSION"
+ ;;
+xno)
+ # no registry lookup.
+ gcc_cv_win32_registry_key=''
+ ;;
+*)
+ # user-specified key.
+ gcc_cv_win32_registry_key="$enable_win32_registry"
+ ;;
+esac
+
+if test "x$enable_win32_registry" != xno; then
+ AC_MSG_CHECKING(registry key on windows hosts)
+ AC_DEFINE_UNQUOTED(WIN32_REGISTRY_KEY, "$gcc_cv_win32_registry_key",
+ [Define to be the last portion of registry key on windows hosts.])
+ AC_MSG_RESULT($gcc_cv_win32_registry_key)
+fi
+;;
+esac
+
+# Get an absolute path to the GCC top-level source directory
+holddir=`${PWDCMD-pwd}`
+cd $srcdir
+topdir=`${PWDCMD-pwd}`
+cd $holddir
+
+# Conditionalize the makefile for this host machine.
+xmake_file=
+for f in ${host_xmake_file}
+do
+ if test -f ${srcdir}/config/$f
+ then
+ xmake_file="${xmake_file} \$(srcdir)/config/$f"
+ fi
+done
+
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+ if test -f ${srcdir}/config/$f
+ then
+ tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+ fi
+done
+tmake_file="${tmake_file_}"
+
+symbolic_link='ln -s'
+
+# If the host doesn't support symlinks, modify CC in
+# FLAGS_TO_PASS so CC="stage1/xgcc -Bstage1/" works.
+# Otherwise, we can use "CC=$(CC)".
+rm -f symtest.tem
+if $symbolic_link $srcdir/gcc.c symtest.tem 2>/dev/null
+then
+ cc_set_by_configure="\$(CC)"
+ quoted_cc_set_by_configure="\$(CC)"
+ stage_prefix_set_by_configure="\$(STAGE_PREFIX)"
+ quoted_stage_prefix_set_by_configure="\$(STAGE_PREFIX)"
+else
+ rm -f symtest.tem
+ if cp -p $srcdir/gcc.c symtest.tem 2>/dev/null
+ then
+ symbolic_link="cp -p"
+ else
+ symbolic_link="cp"
+ fi
+ cc_set_by_configure="\`case '\$(CC)' in stage*) echo '\$(CC)' | sed -e 's|stage|../stage|g';; *) echo '\$(CC)';; esac\`"
+ quoted_cc_set_by_configure="\\\`case '\\\$(CC)' in stage*) echo '\\\$(CC)' | sed -e 's|stage|../stage|g';; *) echo '\\\$(CC)';; esac\\\`"
+ stage_prefix_set_by_configure="\`case '\$(STAGE_PREFIX)' in stage*) echo '\$(STAGE_PREFIX)' | sed -e 's|stage|../stage|g';; *) echo '\$(STAGE_PREFIX)';; esac\`"
+ quoted_stage_prefix_set_by_configure="\\\`case '\\\$(STAGE_PREFIX)' in stage*) echo '\\\$(STAGE_PREFIX)' | sed -e 's|stage|../stage|g';; *) echo '\\\$(STAGE_PREFIX)';; esac\\\`"
+fi
+rm -f symtest.tem
+
+out_object_file=`basename $out_file .c`.o
+
+tm_file_list=
+tm_include_list=
+for f in $tm_file; do
+ case $f in
+ defaults.h )
+ tm_file_list="${tm_file_list} \$(srcdir)/$f"
+ tm_include_list="${tm_include_list} $f"
+ ;;
+ * )
+ tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ tm_include_list="${tm_include_list} config/$f"
+ ;;
+ esac
+done
+
+tm_p_file_list=
+tm_p_include_list=
+for f in $tm_p_file; do
+ case $f in
+ tm-preds.h )
+ tm_p_file_list="${tm_p_file_list} $f"
+ tm_p_include_list="${tm_p_include_list} $f"
+ ;;
+ * )
+ tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
+ tm_p_include_list="${tm_p_include_list} config/$f"
+ esac
+done
+
+xm_file_list=
+xm_include_list=
+for f in $xm_file; do
+ case $f in
+ ansidecl.h )
+ xm_file_list="${xm_file_list} \$(srcdir)/../include/$f"
+ xm_include_list="${xm_include_list} $f"
+ ;;
+ auto-host.h )
+ xm_file_list="${xm_file_list} $f"
+ xm_include_list="${xm_include_list} $f"
+ ;;
+ * )
+ xm_file_list="${xm_file_list} \$(srcdir)/config/$f"
+ xm_include_list="${xm_include_list} config/$f"
+ ;;
+ esac
+done
+
+host_xm_file_list=
+host_xm_include_list=
+for f in $host_xm_file; do
+ case $f in
+ ansidecl.h )
+ host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/$f"
+ host_xm_include_list="${host_xm_include_list} $f"
+ ;;
+ auto-host.h )
+ host_xm_file_list="${host_xm_file_list} $f"
+ host_xm_include_list="${host_xm_include_list} $f"
+ ;;
+ * )
+ host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
+ host_xm_include_list="${host_xm_include_list} config/$f"
+ ;;
+ esac
+done
+
+build_xm_file_list=
+for f in $build_xm_file; do
+ case $f in
+ ansidecl.h )
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/$f"
+ build_xm_include_list="${build_xm_include_list} $f"
+ ;;
+ auto-build.h | auto-host.h )
+ build_xm_file_list="${build_xm_file_list} $f"
+ build_xm_include_list="${build_xm_include_list} $f"
+ ;;
+ * )
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
+ build_xm_include_list="${build_xm_include_list} config/$f"
+ ;;
+ esac
+done
+
+# Define macro CROSS_COMPILE in compilation if this is a cross-compiler.
+# Also use all.cross instead of all.internal and adjust SYSTEM_HEADER_DIR.
+CROSS= AC_SUBST(CROSS)
+ALL=all.internal AC_SUBST(ALL)
+SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)' AC_SUBST(SYSTEM_HEADER_DIR)
+if test x$host != x$target
+then
+ CROSS="-DCROSS_COMPILE"
+ ALL=all.cross
+ SYSTEM_HEADER_DIR='$(CROSS_SYSTEM_HEADER_DIR)'
+ case "$host","$target" in
+ # Darwin crosses can use the host system's libraries and headers,
+ # because of the fat library support. Of course, it must be the
+ # same version of Darwin on both sides. Allow the user to
+ # just say --target=foo-darwin without a version number to mean
+ # "the version on this system".
+ *-*-darwin*,*-*-darwin*)
+ hostos=`echo $host | sed 's/.*-darwin/darwin/'`
+ targetos=`echo $target | sed 's/.*-darwin/darwin/'`
+ if test $hostos = $targetos -o $targetos = darwin ; then
+ CROSS=
+ SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
+ with_headers=yes
+ fi
+ ;;
+
+ i?86-*-*,x86_64-*-* \
+ | powerpc*-*-*,powerpc64*-*-*)
+ CROSS="$CROSS -DNATIVE_CROSS" ;;
+ esac
+elif test "x$TARGET_SYSTEM_ROOT" != x; then
+ # This is just $(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR)
+ SYSTEM_HEADER_DIR='$(CROSS_SYSTEM_HEADER_DIR)'
+fi
+
+# If this is a cross-compiler that does not
+# have its own set of headers then define
+# inhibit_libc
+
+# If this is using newlib, without having the headers available now,
+# then define inhibit_libc in LIBGCC2_CFLAGS.
+# This prevents libgcc2 from containing any code which requires libc
+# support.
+inhibit_libc=
+if { { test x$host != x$target && test "x$with_sysroot" = x ; } ||
+ test x$with_newlib = xyes ; } &&
+ { test "x$with_headers" = x || test "x$with_headers" = xno ; } ; then
+ inhibit_libc=-Dinhibit_libc
+fi
+AC_SUBST(inhibit_libc)
+
+# When building gcc with a cross-compiler, we need to adjust things so
+# that the generator programs are still built with the native compiler.
+# Also, we cannot run fixincludes or fix-header.
+
+# These are the normal (build=host) settings:
+BUILD_PREFIX= AC_SUBST(BUILD_PREFIX)
+BUILD_PREFIX_1=ignore- AC_SUBST(BUILD_PREFIX_1)
+CC_FOR_BUILD='$(CC)' AC_SUBST(CC_FOR_BUILD)
+BUILD_CFLAGS='$(ALL_CFLAGS)' AC_SUBST(BUILD_CFLAGS)
+
+STMP_FIXINC=stmp-fixinc AC_SUBST(STMP_FIXINC)
+
+# Possibly disable fixproto, on a per-target basis.
+case ${use_fixproto} in
+ no)
+ STMP_FIXPROTO=
+ ;;
+ yes)
+ STMP_FIXPROTO=stmp-fixproto
+ ;;
+esac
+AC_SUBST(STMP_FIXPROTO)
+
+# And these apply if build != host, or we are generating coverage data
+if test x$build != x$host || test "x$coverage_flags" != x
+then
+ BUILD_PREFIX=build-
+ BUILD_PREFIX_1=build-
+ BUILD_CFLAGS='$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS_FOR_BUILD)'
+
+ if test "x$TARGET_SYSTEM_ROOT" = x; then
+ STMP_FIXINC=
+ STMP_FIXPROTO=
+ fi
+fi
+
+# Expand extra_headers to include complete path.
+# This substitutes for lots of t-* files.
+extra_headers_list=
+# Prepend $(srcdir)/config/${cpu_type}/ to every entry in extra_headers.
+for file in ${extra_headers} ; do
+ extra_headers_list="${extra_headers_list} \$(srcdir)/config/${cpu_type}/${file}"
+done
+
+# Define collect2 in Makefile.
+case $host_can_use_collect2 in
+ no) collect2= ;;
+ *) collect2='collect2$(exeext)' ;;
+esac
+AC_SUBST([collect2])
+
+# Add a definition of USE_COLLECT2 if system wants one.
+case $use_collect2 in
+ no) use_collect2= ;;
+ "") ;;
+ *)
+ host_xm_defines="${host_xm_defines} USE_COLLECT2"
+ xm_defines="${xm_defines} USE_COLLECT2"
+ case $host_can_use_collect2 in
+ no)
+ AC_MSG_ERROR([collect2 is required but cannot be built on this system])
+ ;;
+ esac
+ ;;
+esac
+
+# ---------------------------
+# Assembler & linker features
+# ---------------------------
+
+# Identify the assembler which will work hand-in-glove with the newly
+# built GCC, so that we can examine its features. This is the assembler
+# which will be driven by the driver program.
+#
+# If build != host, and we aren't building gas in-tree, we identify a
+# build->target assembler and hope that it will have the same features
+# as the host->target assembler we'll be using.
+AC_MSG_CHECKING(what assembler to use)
+in_tree_gas=no
+gcc_cv_as=
+gcc_cv_gas_major_version=
+gcc_cv_gas_minor_version=
+gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
+if test -x "$DEFAULT_ASSEMBLER"; then
+ gcc_cv_as="$DEFAULT_ASSEMBLER"
+elif test -x as$host_exeext; then
+ # Build using assembler in the current directory.
+ gcc_cv_as=./as$host_exeext
+elif test -f $gcc_cv_as_gas_srcdir/configure.in \
+ && test -f ../gas/Makefile \
+ && test x$build = x$host; then
+ # Single tree build which includes gas. We want to prefer it
+ # over whatever linker top-level may have detected, since
+ # we'll use what we're building after installation anyway.
+ in_tree_gas=yes
+ _gcc_COMPUTE_GAS_VERSION
+ rm -f as$host_exeext
+ $symbolic_link ../gas/as-new$host_exeext as$host_exeext 2>/dev/null
+ in_tree_gas_is_elf=no
+ if grep 'obj_format = elf' ../gas/Makefile > /dev/null \
+ || (grep 'obj_format = multi' ../gas/Makefile \
+ && grep 'extra_objects =.* obj-elf' ../gas/Makefile) > /dev/null
+ then
+ in_tree_gas_is_elf=yes
+ fi
+m4_pattern_allow([AS_FOR_TARGET])dnl
+elif test -x "$AS_FOR_TARGET"; then
+ gcc_cv_as="$AS_FOR_TARGET"
+elif test -x "$AS" && test x$host = x$target; then
+ gcc_cv_as="$AS"
+fi
+
+if test "x$gcc_cv_as" = x; then
+ # Search the same directories that the installed compiler will
+ # search. Else we may find the wrong assembler and lose. If we
+ # do not find a suitable assembler binary, then try the user's
+ # path.
+ #
+ # Also note we have to check MD_EXEC_PREFIX before checking the
+ # user's path. Unfortunately, there is no good way to get at the
+ # value of MD_EXEC_PREFIX here. So we do a brute force search
+ # through all the known MD_EXEC_PREFIX values. Ugh. This needs
+ # to be fixed as part of the make/configure rewrite too.
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+
+ # If the loop below does not find an assembler, then use whatever
+ # one we can find in the users's path.
+ # user's path.
+ if test "x$program_prefix" != xNONE; then
+ gcc_cv_as=${program_prefix}as$host_exeext
+ else
+ gcc_cv_as=`echo as | sed "${program_transform_name}"`$host_exeext
+ fi
+
+ test_dirs="$test_prefix/libexec/gcc/$target_noncanonical/$gcc_version \
+ $test_prefix/libexec/gcc/$target_noncanonical \
+ /usr/lib/gcc/$target_noncanonical/$gcc_version \
+ /usr/lib/gcc/$target_noncanonical \
+ $test_prefix/$target_noncanonical/bin/$target_noncanonical/$gcc_version \
+ $test_prefix/$target_noncanonical/bin"
+
+ if test x$host = x$target; then
+ test_dirs="$test_dirs \
+ /usr/libexec \
+ /usr/ccs/gcc \
+ /usr/ccs/bin \
+ /udk/usr/ccs/bin \
+ /bsd43/usr/lib/cmplrs/cc \
+ /usr/cross64/usr/bin \
+ /usr/lib/cmplrs/cc \
+ /sysv/usr/lib/cmplrs/cc \
+ /svr4/usr/lib/cmplrs/cc \
+ /usr/bin"
+ fi
+
+ for dir in $test_dirs; do
+ if test -x $dir/as$host_exeext; then
+ gcc_cv_as=$dir/as$host_exeext
+ break;
+ fi
+ done
+fi
+case $in_tree_gas in
+ yes)
+ AC_MSG_RESULT("newly built gas")
+ ;;
+ no)
+ AC_MSG_RESULT($gcc_cv_as)
+ ;;
+esac
+
+# Identify the linker which will work hand-in-glove with the newly
+# built GCC, so that we can examine its features. This is the linker
+# which will be driven by the driver program.
+#
+# If build != host, and we aren't building gas in-tree, we identify a
+# build->target linker and hope that it will have the same features
+# as the host->target linker we'll be using.
+AC_MSG_CHECKING(what linker to use)
+in_tree_ld=no
+gcc_cv_ld=
+gcc_cv_gld_major_version=
+gcc_cv_gld_minor_version=
+gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
+gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
+if test -x "$DEFAULT_LINKER"; then
+ gcc_cv_ld="$DEFAULT_LINKER"
+elif test -x collect-ld$host_exeext; then
+ # Build using linker in the current directory.
+ gcc_cv_ld=./collect-ld$host_exeext
+elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
+ && test -f ../ld/Makefile \
+ && test x$build = x$host; then
+ # Single tree build which includes ld. We want to prefer it
+ # over whatever linker top-level may have detected, since
+ # we'll use what we're building after installation anyway.
+ in_tree_ld=yes
+ in_tree_ld_is_elf=no
+ if (grep 'EMUL = .*elf' ../ld/Makefile \
+ || grep 'EMUL = .*linux' ../ld/Makefile) > /dev/null; then
+ in_tree_ld_is_elf=yes
+ fi
+ for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
+ do
+changequote(,)dnl
+ gcc_cv_gld_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
+changequote([,])dnl
+ if test x$gcc_cv_gld_version != x; then
+ break
+ fi
+ done
+changequote(,)dnl
+ gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
+ gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+changequote([,])dnl
+ rm -f collect-ld$host_exeext
+ $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext \
+ 2>/dev/null
+elif test -x "$LD_FOR_TARGET"; then
+ gcc_cv_ld="$LD_FOR_TARGET"
+elif test -x "$LD" && test x$host = x$target; then
+ gcc_cv_ld="$LD"
+fi
+
+if test "x$gcc_cv_ld" = x; then
+ # Search the same directories that the installed compiler will
+ # search. Else we may find the wrong linker and lose. If we
+ # do not find a suitable linker binary, then try the user's
+ # path.
+ #
+ # Also note we have to check MD_EXEC_PREFIX before checking the
+ # user's path. Unfortunately, there is no good way to get at the
+ # value of MD_EXEC_PREFIX here. So we do a brute force search
+ # through all the known MD_EXEC_PREFIX values. Ugh. This needs
+ # to be fixed as part of the make/configure rewrite too.
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+
+ # If the loop below does not find an linker, then use whatever
+ # one we can find in the users's path.
+ # user's path.
+ if test "x$program_prefix" != xNONE; then
+ gcc_cv_ld=${program_prefix}ld$host_exeext
+ else
+ gcc_cv_ld=`echo ld | sed "${program_transform_name}"`$host_exeext
+ fi
+
+ test_dirs="$test_prefix/libexec/gcc/$target_noncanonical/$gcc_version \
+ $test_prefix/libexec/gcc/$target_noncanonical \
+ /usr/lib/gcc/$target_noncanonical/$gcc_version \
+ /usr/lib/gcc/$target_noncanonical \
+ $test_prefix/$target_noncanonical/bin/$target_noncanonical/$gcc_version \
+ $test_prefix/$target_noncanonical/bin"
+
+ if test x$host = x$target; then
+ test_dirs="$test_dirs \
+ /usr/libexec \
+ /usr/ccs/gcc \
+ /usr/ccs/bin \
+ /udk/usr/ccs/bin \
+ /bsd43/usr/lib/cmplrs/cc \
+ /usr/cross64/usr/bin \
+ /usr/lib/cmplrs/cc \
+ /sysv/usr/lib/cmplrs/cc \
+ /svr4/usr/lib/cmplrs/cc \
+ /usr/bin"
+ fi
+
+ for dir in $test_dirs; do
+ if test -x $dir/ld$host_exeext; then
+ gcc_cv_ld=$dir/ld$host_exeext
+ break;
+ fi
+ done
+fi
+case $in_tree_ld in
+ yes)
+ AC_MSG_RESULT("newly built ld")
+ ;;
+ no)
+ AC_MSG_RESULT($gcc_cv_ld)
+ ;;
+esac
+
+# Figure out what nm we will be using.
+gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
+AC_MSG_CHECKING(what nm to use)
+in_tree_nm=no
+if test -x nm$host_exeext; then
+ gcc_cv_nm=./nm$host_exeext
+elif test -f $gcc_cv_binutils_srcdir/configure.in \
+ && test -f ../binutils/Makefile; then
+ # Single tree build which includes binutils.
+ in_tree_nm=yes
+ gcc_cv_nm=./nm$host_exeext
+ rm -f nm$host_exeext
+ $symbolic_link ../binutils/nm-new$host_exeext nm$host_exeext 2>/dev/null
+elif test "x$program_prefix" != xNONE; then
+ gcc_cv_nm=${program_prefix}nm$host_exeext
+else
+ gcc_cv_nm=`echo nm | sed "${program_transform_name}"`$host_exeext
+fi
+case $in_tree_nm in
+ yes) AC_MSG_RESULT("newly built nm") ;;
+ no) AC_MSG_RESULT($gcc_cv_nm) ;;
+esac
+
+# Figure out what objdump we will be using.
+AC_MSG_CHECKING(what objdump to use)
+in_tree_objdump=no
+if test -x objdump$host_exeext; then
+ gcc_cv_objdump=./objdump$host_exeext
+elif test -f $gcc_cv_binutils_srcdir/configure.in \
+ && test -f ../binutils/Makefile; then
+ # Single tree build which includes binutils.
+ in_tree_objdump=yes
+ gcc_cv_objdump=./objdump$host_exeext
+ rm -f objdump$host_exeext
+ $symbolic_link ../binutils/objdump$host_exeext \
+ objdump$host_exeext 2>/dev/null
+elif test "x$program_prefix" != xNONE; then
+ gcc_cv_objdump=${program_prefix}objdump$host_exeext
+else
+ gcc_cv_objdump=`echo objdump | \
+ sed "${program_transform_name}"`$host_exeext
+fi
+case $in_tree_objdump in
+ yes) AC_MSG_RESULT("newly built objdump") ;;
+ no) AC_MSG_RESULT($gcc_cv_objdump) ;;
+esac
+
+# Figure out what assembler alignment features are present.
+gcc_GAS_CHECK_FEATURE([.balign and .p2align], gcc_cv_as_balign_and_p2align,
+ [2,6,0],,
+[.balign 4
+.p2align 2],,
+[AC_DEFINE(HAVE_GAS_BALIGN_AND_P2ALIGN, 1,
+ [Define if your assembler supports .balign and .p2align.])])
+
+gcc_GAS_CHECK_FEATURE([.p2align with maximum skip], gcc_cv_as_max_skip_p2align,
+ [2,8,0],,
+ [.p2align 4,,7],,
+[AC_DEFINE(HAVE_GAS_MAX_SKIP_P2ALIGN, 1,
+ [Define if your assembler supports specifying the maximum number
+ of bytes to skip when using the GAS .p2align command.])])
+
+gcc_GAS_CHECK_FEATURE([working .subsection -1], gcc_cv_as_subsection_m1,
+ [elf,2,9,0],,
+ [conftest_label1: .word 0
+.subsection -1
+conftest_label2: .word 0
+.previous],
+ [if test x$gcc_cv_nm != x; then
+ $gcc_cv_nm conftest.o | grep conftest_label1 > conftest.nm1
+ $gcc_cv_nm conftest.o | grep conftest_label2 | sed -e 's/label2/label1/' > conftest.nm2
+ if cmp conftest.nm1 conftest.nm2 > /dev/null 2>&1
+ then :
+ else gcc_cv_as_subsection_m1=yes
+ fi
+ rm -f conftest.nm1 conftest.nm2
+ fi],
+ [AC_DEFINE(HAVE_GAS_SUBSECTION_ORDERING, 1,
+ [Define if your assembler supports .subsection and .subsection -1 starts
+ emitting at the beginning of your section.])])
+
+gcc_GAS_CHECK_FEATURE([.weak], gcc_cv_as_weak,
+ [2,2,0],,
+ [ .weak foobar],,
+[AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
+
+# .hidden needs to be supported in both the assembler and the linker,
+# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
+# This is irritatingly difficult to feature test for; we have to check the
+# date string after the version number. If we've got an in-tree
+# ld, we don't know its patchlevel version, so we set the baseline at 2.13
+# to be safe.
+# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
+gcc_GAS_CHECK_FEATURE([.hidden], gcc_cv_as_hidden,
+ [elf,2,13,0],,
+[ .hidden foobar
+foobar:])
+
+AC_CACHE_CHECK(linker for .hidden support, gcc_cv_ld_hidden,
+[if test $in_tree_ld = yes ; then
+ gcc_cv_ld_hidden=no
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 13 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_hidden=yes
+ fi
+else
+ gcc_cv_ld_hidden=yes
+ ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
+ if echo "$ld_ver" | grep GNU > /dev/null; then
+changequote(,)dnl
+ ld_vers=`echo $ld_ver | sed -n \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p'`
+ ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
+ if test 0"$ld_date" -lt 20020404; then
+ if test -n "$ld_date"; then
+ # If there was date string, but was earlier than 2002-04-04, fail
+ gcc_cv_ld_hidden=no
+ elif test -z "$ld_vers"; then
+ # If there was no date string nor ld version number, something is wrong
+ gcc_cv_ld_hidden=no
+ else
+ ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
+ ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
+ ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+ test -z "$ld_vers_patch" && ld_vers_patch=0
+ if test "$ld_vers_major" -lt 2; then
+ gcc_cv_ld_hidden=no
+ elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
+ gcc_cv_ld_hidden="no"
+ elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 -a "$ld_vers_patch" -eq 0; then
+ gcc_cv_ld_hidden=no
+ fi
+ fi
+changequote([,])dnl
+ fi
+ else
+ case "${target}" in
+ hppa64*-*-hpux* | ia64*-*-hpux*)
+ gcc_cv_ld_hidden=yes
+ ;;
+ *)
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
+ fi
+fi])
+libgcc_visibility=no
+AC_SUBST(libgcc_visibility)
+if test $gcc_cv_as_hidden = yes && test $gcc_cv_ld_hidden = yes; then
+ libgcc_visibility=yes
+ AC_DEFINE(HAVE_GAS_HIDDEN, 1,
+ [Define if your assembler and linker support .hidden.])
+fi
+
+# Check if we have .[us]leb128, and support symbol arithmetic with it.
+gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,
+ [elf,2,11,0],,
+[ .data
+ .uleb128 L2 - L1
+L1:
+ .uleb128 1280
+ .sleb128 -1010
+L2:],
+ [# GAS versions before 2.11 do not support uleb128,
+ # despite appearing to.
+ # ??? There exists an elf-specific test that will crash
+ # the assembler. Perhaps it's better to figure out whether
+ # arbitrary sections are supported and try the test.
+ as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
+ if echo "$as_ver" | grep GNU > /dev/null; then
+changequote(,)dnl
+ as_ver=`echo $as_ver | sed -e 's/GNU assembler \([0-9.][0-9.]*\).*/\1/'`
+ as_major=`echo $as_ver | sed 's/\..*//'`
+ as_minor=`echo $as_ver | sed 's/[^.]*\.\([0-9]*\).*/\1/'`
+changequote([,])dnl
+ if test $as_major -eq 2 && test $as_minor -lt 11
+ then :
+ else gcc_cv_as_leb128=yes
+ fi
+ fi],
+ [AC_DEFINE(HAVE_AS_LEB128, 1,
+ [Define if your assembler supports .sleb128 and .uleb128.])])
+
+# GAS versions up to and including 2.11.0 may mis-optimize
+# .eh_frame data.
+gcc_GAS_CHECK_FEATURE(eh_frame optimization, gcc_cv_as_eh_frame,
+ [elf,2,12,0],,
+[ .text
+.LFB1:
+ .4byte 0
+.L1:
+ .4byte 0
+.LFE1:
+ .section .eh_frame,"aw",@progbits
+__FRAME_BEGIN__:
+ .4byte .LECIE1-.LSCIE1
+.LSCIE1:
+ .4byte 0x0
+ .byte 0x1
+ .ascii "z\0"
+ .byte 0x1
+ .byte 0x78
+ .byte 0x1a
+ .byte 0x0
+ .byte 0x4
+ .4byte 1
+ .p2align 1
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1
+.LASFDE1:
+ .4byte .LASFDE1-__FRAME_BEGIN__
+ .4byte .LFB1
+ .4byte .LFE1-.LFB1
+ .byte 0x4
+ .4byte .LFE1-.LFB1
+ .byte 0x4
+ .4byte .L1-.LFB1
+.LEFDE1:],
+[ dnl # For autoconf 2.5x, must protect trailing spaces with @&t@.
+cat > conftest.lit <<EOF
+ 0000 10000000 00000000 017a0001 781a0004 .........z..x...
+ 0010 01000000 12000000 18000000 00000000 ................
+ 0020 08000000 04080000 0044 .........D @&t@
+EOF
+cat > conftest.big <<EOF
+ 0000 00000010 00000000 017a0001 781a0004 .........z..x...
+ 0010 00000001 00000012 00000018 00000000 ................
+ 0020 00000008 04000000 0844 .........D @&t@
+EOF
+ # If the assembler didn't choke, and we can objdump,
+ # and we got the correct data, then succeed.
+ if test x$gcc_cv_objdump != x \
+ && $gcc_cv_objdump -s -j .eh_frame conftest.o 2>/dev/null \
+ | tail -3 > conftest.got \
+ && { cmp conftest.lit conftest.got > /dev/null 2>&1 \
+ || cmp conftest.big conftest.got > /dev/null 2>&1; }
+ then
+ gcc_cv_as_eh_frame=yes
+ elif AC_TRY_COMMAND($gcc_cv_as -o conftest.o --traditional-format /dev/null); then
+ gcc_cv_as_eh_frame=buggy
+ else
+ # Uh oh, what do we do now?
+ gcc_cv_as_eh_frame=no
+ fi])
+
+if test $gcc_cv_as_eh_frame = buggy; then
+ AC_DEFINE(USE_AS_TRADITIONAL_FORMAT, 1,
+ [Define if your assembler mis-optimizes .eh_frame data.])
+fi
+
+gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
+ [elf,2,12,0], [--fatal-warnings],
+ [.section .rodata.str, "aMS", @progbits, 1])
+AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE,
+ [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`],
+[Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.])
+
+# Thread-local storage - the check is heavily parametrized.
+conftest_s=
+tls_first_major=
+tls_first_minor=
+tls_as_opt=
+case "$target" in
+changequote(,)dnl
+ alpha*-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ ldq $27,__tls_get_addr($29) !literal!1
+ lda $16,foo($29) !tlsgd!1
+ jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
+ ldq $27,__tls_get_addr($29) !literal!2
+ lda $16,foo($29) !tlsldm!2
+ jsr $26,($27),__tls_get_addr !lituse_tlsldm!2
+ ldq $1,foo($29) !gotdtprel
+ ldah $2,foo($29) !dtprelhi
+ lda $3,foo($2) !dtprello
+ lda $4,foo($29) !dtprel
+ ldq $1,foo($29) !gottprel
+ ldah $2,foo($29) !tprelhi
+ lda $3,foo($2) !tprello
+ lda $4,foo($29) !tprel'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ i[34567]86-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ movl %gs:0, %eax
+ leal foo@TLSGD(,%ebx,1), %eax
+ leal foo@TLSLDM(%ebx), %eax
+ leal foo@DTPOFF(%eax), %edx
+ movl foo@GOTTPOFF(%ebx), %eax
+ subl foo@GOTTPOFF(%ebx), %eax
+ addl foo@GOTNTPOFF(%ebx), %eax
+ movl foo@INDNTPOFF, %eax
+ movl $foo@TPOFF, %eax
+ subl $foo@TPOFF, %eax
+ leal foo@NTPOFF(%ecx), %eax'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt=--fatal-warnings
+ ;;
+ x86_64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ movq %fs:0, %rax
+ leaq foo@TLSGD(%rip), %rdi
+ leaq foo@TLSLD(%rip), %rdi
+ leaq foo@DTPOFF(%rax), %rdx
+ movq foo@GOTTPOFF(%rip), %rax
+ movq $foo@TPOFF, %rax'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt=--fatal-warnings
+ ;;
+ ia64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: data8 25
+ .text
+ addl r16 = @ltoff(@dtpmod(foo#)), gp
+ addl r17 = @ltoff(@dtprel(foo#)), gp
+ addl r18 = @ltoff(@tprel(foo#)), gp
+ addl r19 = @dtprel(foo#), gp
+ adds r21 = @dtprel(foo#), r13
+ movl r23 = @dtprel(foo#)
+ addl r20 = @tprel(foo#), gp
+ adds r22 = @tprel(foo#), r13
+ movl r24 = @tprel(foo#)'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ powerpc-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+ .align 2
+ld0: .space 4
+ld1: .space 4
+x1: .space 4
+x2: .space 4
+x3: .space 4
+ .text
+ addi 3,31,ld0@got@tlsgd
+ bl __tls_get_addr
+ addi 3,31,x1@got@tlsld
+ bl __tls_get_addr
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ lwz 9,x3@got@tprel(31)
+ add 9,9,x@tls
+ addi 9,2,x1@tprel
+ addis 9,2,x2@tprel@ha
+ addi 9,9,x2@tprel@l'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-a32 --fatal-warnings"
+ ;;
+ powerpc64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+ .align 3
+ld0: .space 8
+ld1: .space 8
+x1: .space 8
+x2: .space 8
+x3: .space 8
+ .text
+ addi 3,2,ld0@got@tlsgd
+ bl .__tls_get_addr
+ nop
+ addi 3,2,ld1@toc
+ bl .__tls_get_addr
+ nop
+ addi 3,2,x1@got@tlsld
+ bl .__tls_get_addr
+ nop
+ addi 9,3,x1@dtprel
+ bl .__tls_get_addr
+ nop
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ bl .__tls_get_addr
+ nop
+ ld 9,x3@got@dtprel(2)
+ add 9,9,3
+ bl .__tls_get_addr
+ nop'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-a64 --fatal-warnings"
+ ;;
+ s390-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@NTPOFF
+ .long foo@GOTNTPOFF
+ .long foo@INDNTPOFF
+ l %r1,foo@GOTNTPOFF(%r12)
+ l %r1,0(%r1):tls_load:foo
+ bas %r14,0(%r1,%r13):tls_gdcall:foo
+ bas %r14,0(%r1,%r13):tls_ldcall:foo'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-m31 --fatal-warnings"
+ ;;
+ s390x-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .quad foo@TLSGD
+ .quad foo@TLSLDM
+ .quad foo@DTPOFF
+ .quad foo@NTPOFF
+ .quad foo@GOTNTPOFF
+ lg %r1,foo@GOTNTPOFF(%r12)
+ larl %r1,foo@INDNTPOFF
+ brasl %r14,__tls_get_offset@PLT:tls_gdcall:foo
+ brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-m64 -Aesame --fatal-warnings"
+ ;;
+ sh-*-* | sh[34]-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@GOTTPOFF
+ .long foo@TPOFF'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ sparc*-*-*)
+ case "$target" in
+ sparc*-sun-solaris2.*)
+ on_solaris=yes
+ ;;
+ *)
+ on_solaris=no
+ ;;
+ esac
+ if test x$on_solaris = xyes && test x$gas_flag = xno; then
+ conftest_s='
+ .section ".tdata",#alloc,#write,#tls
+foo: .long 25
+ .text
+ sethi %tgd_hi22(foo), %o0
+ add %o0, %tgd_lo10(foo), %o1
+ add %l7, %o1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(foo), %l1
+ add %l1, %tldm_lo10(foo), %l2
+ add %l7, %l2, %o0, %tldm_add(foo)
+ call __tls_get_addr, %tldm_call(foo)
+ sethi %tldo_hix22(foo), %l3
+ xor %l3, %tldo_lox10(foo), %l4
+ add %o0, %l4, %l5, %tldo_add(foo)
+ sethi %tie_hi22(foo), %o3
+ add %o3, %tie_lo10(foo), %o3
+ ld [%l7 + %o3], %o2, %tie_ld(foo)
+ add %g7, %o2, %o4, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %o5
+ ld [%g7 + %o5], %o1'
+ tls_first_major=0
+ tls_first_minor=0
+ else
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ sethi %tgd_hi22(foo), %o0
+ add %o0, %tgd_lo10(foo), %o1
+ add %l7, %o1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(foo), %l1
+ add %l1, %tldm_lo10(foo), %l2
+ add %l7, %l2, %o0, %tldm_add(foo)
+ call __tls_get_addr, %tldm_call(foo)
+ sethi %tldo_hix22(foo), %l3
+ xor %l3, %tldo_lox10(foo), %l4
+ add %o0, %l4, %l5, %tldo_add(foo)
+ sethi %tie_hi22(foo), %o3
+ add %o3, %tie_lo10(foo), %o3
+ ld [%l7 + %o3], %o2, %tie_ld(foo)
+ add %g7, %o2, %o4, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %o5
+ ld [%g7 + %o5], %o1'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-32 --fatal-warnings"
+ fi
+ ;;
+changequote([,])dnl
+esac
+if test -z "$tls_first_major"; then
+ : # If we don't have a check, assume no support.
+else
+ gcc_GAS_CHECK_FEATURE(thread-local storage support, gcc_cv_as_tls,
+ [$tls_first_major,$tls_first_minor,0], [$tls_as_opt], [$conftest_s],,
+ [AC_DEFINE(HAVE_AS_TLS, 1,
+ [Define if your assembler supports thread-local storage.])])
+fi
+
+# Target-specific assembler checks.
+
+if test x"$demangler_in_ld" = xyes; then
+ AC_MSG_CHECKING(linker --demangle support)
+ gcc_cv_ld_demangle=no
+ if test $in_tree_ld = yes; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then \
+ gcc_cv_ld_demangle=yes
+ fi
+ elif test x$gcc_cv_ld != x -a x"$gnu_ld" = xyes; then
+ # Check if the GNU linker supports --demangle option
+ if $gcc_cv_ld --help 2>/dev/null | grep no-demangle > /dev/null; then
+ gcc_cv_ld_demangle=yes
+ fi
+ fi
+ if test x"$gcc_cv_ld_demangle" = xyes; then
+ AC_DEFINE(HAVE_LD_DEMANGLE, 1,
+[Define if your linker supports --demangle option.])
+ fi
+ AC_MSG_RESULT($gcc_cv_ld_demangle)
+fi
+
+case "$target" in
+ # All TARGET_ABI_OSF targets.
+ alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
+ gcc_GAS_CHECK_FEATURE([explicit relocation support],
+ gcc_cv_as_alpha_explicit_relocs, [2,12,0],,
+[ .set nomacro
+ .text
+ extbl $3, $2, $3 !lituse_bytoff!1
+ ldq $2, a($29) !literal!1
+ ldq $4, b($29) !literal!2
+ ldq_u $3, 0($2) !lituse_base!1
+ ldq $27, f($29) !literal!5
+ jsr $26, ($27), f !lituse_jsr!5
+ ldah $29, 0($26) !gpdisp!3
+ lda $0, c($29) !gprel
+ ldah $1, d($29) !gprelhigh
+ lda $1, d($1) !gprellow
+ lda $29, 0($29) !gpdisp!3],,
+ [AC_DEFINE(HAVE_AS_EXPLICIT_RELOCS, 1,
+ [Define if your assembler supports explicit relocations.])])
+ ;;
+
+ cris-*-*)
+ gcc_GAS_CHECK_FEATURE([-no-mul-bug-abort option],
+ gcc_cv_as_cris_no_mul_bug,[2,15,91],
+ [-no-mul-bug-abort], [.text],,
+ [AC_DEFINE(HAVE_AS_NO_MUL_BUG_ABORT_OPTION, 1,
+ [Define if your assembler supports the -no-mul-bug-abort option.])])
+ ;;
+
+ sparc*-*-*)
+ gcc_GAS_CHECK_FEATURE([.register], gcc_cv_as_sparc_register_op,,,
+ [.register %g2, #scratch],,
+ [AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
+ [Define if your assembler supports .register.])])
+
+ gcc_GAS_CHECK_FEATURE([-relax option], gcc_cv_as_sparc_relax,,
+ [-relax], [.text],,
+ [AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
+ [Define if your assembler supports -relax option.])])
+
+ gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs],
+ gcc_cv_as_sparc_ua_pcrel,,
+ [-K PIC],
+[.text
+foo:
+ nop
+.data
+.align 4
+.byte 0
+.uaword %r_disp32(foo)],
+ [if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
+ gcc_cv_as_sparc_ua_pcrel=yes
+ fi
+ rm -f conftest],
+ [AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+ [Define if your assembler and linker support unaligned PC relative relocs.])
+
+ gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs against hidden symbols],
+ gcc_cv_as_sparc_ua_pcrel_hidden,,
+ [-K PIC],
+[.data
+.align 4
+.byte 0x31
+.uaword %r_disp32(foo)
+.byte 0x32, 0x33, 0x34
+.global foo
+.hidden foo
+foo:
+.skip 4],
+ [if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \
+ && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
+ && $gcc_cv_objdump -s -j .data conftest 2> /dev/null \
+ | grep ' 31000000 07323334' > /dev/null 2>&1; then
+ if $gcc_cv_objdump -R conftest 2> /dev/null \
+ | grep 'DISP32' > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_as_sparc_ua_pcrel_hidden=yes
+ fi
+ fi
+ rm -f conftest],
+ [AC_DEFINE(HAVE_AS_SPARC_UA_PCREL_HIDDEN, 1,
+ [Define if your assembler and linker support unaligned PC relative relocs against hidden symbols.])])
+ ]) # unaligned pcrel relocs
+
+ gcc_GAS_CHECK_FEATURE([offsetable %lo()],
+ gcc_cv_as_sparc_offsetable_lo10,,
+ [-xarch=v9],
+[.text
+ or %g1, %lo(ab) + 12, %g1
+ or %g1, %lo(ab + 12), %g1],
+ [if test x$gcc_cv_objdump != x \
+ && %gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
+ | grep ' 82106000 82106000' > /dev/null 2>&1; then
+ gcc_cv_as_offsetable_lo10=yes
+ fi],
+ [AC_DEFINE(HAVE_AS_OFFSETABLE_LO10, 1,
+ [Define if your assembler supports offsetable %lo().])])
+ ;;
+
+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],,
+ [AC_DEFINE(HAVE_GAS_FILDS_FISTS, 1,
+ [Define if your assembler uses the new HImode fild and fist notation.])])
+
+ gcc_GAS_CHECK_FEATURE([cmov syntax],
+ gcc_cv_as_ix86_cmov_sun_syntax,,,
+ [cmovl.l %edx, %eax],,
+ [AC_DEFINE(HAVE_AS_IX86_CMOV_SUN_SYNTAX, 1,
+ [Define if your assembler supports the Sun syntax for cmov.])])
+
+ # This one is used unconditionally by i386.[ch]; it is to be defined
+ # to 1 if the feature is present, 0 otherwise.
+ gcc_GAS_CHECK_FEATURE([GOTOFF in data],
+ gcc_cv_as_ix86_gotoff_in_data, [2,11,0],,
+[ .text
+.L0:
+ nop
+ .data
+ .long .L0@GOTOFF])
+ AC_DEFINE_UNQUOTED(HAVE_AS_GOTOFF_IN_DATA,
+ [`if test $gcc_cv_as_ix86_gotoff_in_data = yes; then echo 1; else echo 0; fi`],
+ [Define true if the assembler supports '.long foo@GOTOFF'.])
+ ;;
+
+ ia64*-*-*)
+ gcc_GAS_CHECK_FEATURE([ltoffx and ldxmov relocs],
+ gcc_cv_as_ia64_ltoffx_ldxmov_relocs, [2,14,0],,
+[ .text
+ addl r15 = @ltoffx(x#), gp
+ ;;
+ ld8.mov r16 = [[r15]], x#],,
+ [AC_DEFINE(HAVE_AS_LTOFFX_LDXMOV_RELOCS, 1,
+ [Define if your assembler supports ltoffx and ldxmov relocations.])])
+
+ ;;
+
+ powerpc*-*-*)
+ case $target in
+ *-*-aix*) conftest_s=' .csect .text[[PR]]
+ mfcr 3,128';;
+ *-*-darwin*) conftest_s=' .text
+ mfcr r3,128';;
+ *) conftest_s=' .text
+ mfcr 3,128';;
+ esac
+
+ gcc_GAS_CHECK_FEATURE([mfcr field support],
+ gcc_cv_as_powerpc_mfcrf, [2,14,0],,
+ [$conftest_s],,
+ [AC_DEFINE(HAVE_AS_MFCRF, 1,
+ [Define if your assembler supports mfcr field.])])
+ ;;
+
+ mips*-*-*)
+ gcc_GAS_CHECK_FEATURE([explicit relocation support],
+ gcc_cv_as_mips_explicit_relocs, [2,14,0],,
+[ lw $4,%gp_rel(foo)($4)],,
+ [if test x$target_cpu_default = x
+ then target_cpu_default=MASK_EXPLICIT_RELOCS
+ else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
+ fi])
+
+ ;;
+esac
+# ??? Not all targets support dwarf2 debug_line, even within a version
+# of gas. Moreover, we need to emit a valid instruction to trigger any
+# info to the output file. So, as supported targets are added to gas 2.11,
+# add some instruction here to (also) show we expect this might work.
+# ??? Once 2.11 is released, probably need to add first known working
+# version to the per-target configury.
+case "$target" in
+ i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \
+ | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \
+ | xstormy16*-*-* | cris-*-* | xtensa-*-*)
+ insn="nop"
+ ;;
+ ia64*-*-* | s390*-*-*)
+ insn="nop 0"
+ ;;
+ mmix-*-*)
+ insn="swym 0"
+ ;;
+esac
+if test x"$insn" != x; then
+ conftest_s="\
+ .file 1 \"conftest.s\"
+ .loc 1 3 0
+ $insn"
+ gcc_GAS_CHECK_FEATURE([dwarf2 debug_line support],
+ gcc_cv_as_dwarf2_debug_line,
+ [elf,2,11,0],, [$conftest_s],
+ [# ??? This fails with non-gnu grep. Maybe use objdump?
+ if grep debug_line conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_dwarf2_debug_line=yes
+ fi])
+
+# The .debug_line file table must be in the exact order that
+# we specified the files, since these indices are also used
+# by DW_AT_decl_file. Approximate this test by testing if
+# the assembler bitches if the same index is assigned twice.
+ gcc_GAS_CHECK_FEATURE([buggy dwarf2 .file directive],
+ gcc_cv_as_dwarf2_file_buggy,,,
+[ .file 1 "foo.s"
+ .file 1 "bar.s"])
+
+ if test $gcc_cv_as_dwarf2_debug_line = yes \
+ && test $gcc_cv_as_dwarf2_file_buggy = no; then
+ AC_DEFINE(HAVE_AS_DWARF2_DEBUG_LINE, 1,
+ [Define if your assembler supports dwarf2 .file/.loc directives,
+ and preserves file table indices exactly as given.])
+ fi
+
+ gcc_GAS_CHECK_FEATURE([--gdwarf2 option],
+ gcc_cv_as_gdwarf2_flag,
+ [elf,2,11,0], [--gdwarf2], [$insn],,
+ [AC_DEFINE(HAVE_AS_GDWARF2_DEBUG_FLAG, 1,
+[Define if your assembler supports the --gdwarf2 option.])])
+
+ gcc_GAS_CHECK_FEATURE([--gstabs option],
+ gcc_cv_as_gstabs_flag,
+ [elf,2,11,0], [--gstabs], [$insn],
+ [# The native Solaris 9/Intel assembler doesn't understand --gstabs
+ # and warns about it, but still exits successfully. So check for
+ # this.
+ if AC_TRY_COMMAND([$gcc_cv_as --gstabs -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null])
+ then :
+ else gcc_cv_as_gstabs_flag=yes
+ fi],
+ [AC_DEFINE(HAVE_AS_GSTABS_DEBUG_FLAG, 1,
+[Define if your assembler supports the --gstabs option.])])
+fi
+
+AC_MSG_CHECKING(linker read-only and read-write section mixing)
+gcc_cv_ld_ro_rw_mix=unknown
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_ro_rw_mix=read-write
+ fi
+elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
+ echo '.section myfoosect, "a"' > conftest1.s
+ echo '.section myfoosect, "aw"' > conftest2.s
+ echo '.byte 1' >> conftest2.s
+ echo '.section myfoosect, "a"' > conftest3.s
+ echo '.byte 0' >> conftest3.s
+ if $gcc_cv_as -o conftest1.o conftest1.s > /dev/null 2>&1 \
+ && $gcc_cv_as -o conftest2.o conftest2.s > /dev/null 2>&1 \
+ && $gcc_cv_as -o conftest3.o conftest3.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -shared -o conftest1.so conftest1.o \
+ conftest2.o conftest3.o > /dev/null 2>&1; then
+ gcc_cv_ld_ro_rw_mix=`$gcc_cv_objdump -h conftest1.so \
+ | sed -e '/myfoosect/!d' -e N`
+ if echo "$gcc_cv_ld_ro_rw_mix" | grep CONTENTS > /dev/null; then
+ if echo "$gcc_cv_ld_ro_rw_mix" | grep READONLY > /dev/null; then
+ gcc_cv_ld_ro_rw_mix=read-only
+ else
+ gcc_cv_ld_ro_rw_mix=read-write
+ fi
+ fi
+ fi
+changequote(,)dnl
+ rm -f conftest.* conftest[123].*
+changequote([,])dnl
+fi
+if test x$gcc_cv_ld_ro_rw_mix = xread-write; then
+ AC_DEFINE(HAVE_LD_RO_RW_SECTION_MIXING, 1,
+ [Define if your linker links a mix of read-only
+ and read-write sections into a read-write section.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix)
+
+AC_MSG_CHECKING(linker PT_GNU_EH_FRAME support)
+gcc_cv_ld_eh_frame_hdr=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_eh_frame_hdr=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --eh-frame-hdr option
+ if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then
+ gcc_cv_ld_eh_frame_hdr=yes
+ fi
+fi
+if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
+ AC_DEFINE(HAVE_LD_EH_FRAME_HDR, 1,
+[Define if your linker supports --eh-frame-hdr option.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_eh_frame_hdr)
+
+AC_MSG_CHECKING(linker position independent executable support)
+gcc_cv_ld_pie=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_pie=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -pie option
+ if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
+ gcc_cv_ld_pie=yes
+ fi
+fi
+if test x"$gcc_cv_ld_pie" = xyes; then
+ AC_DEFINE(HAVE_LD_PIE, 1,
+[Define if your linker supports -pie option.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_pie)
+
+# --------
+# UNSORTED
+# --------
+
+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
+ gcc_cv_ld_as_needed=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --as-needed and --no-as-needed options
+ if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; 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
+
+if test x$with_sysroot = x && test x$host = x$target \
+ && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
+ AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
+[Define to PREFIX/include if cpp should also search that directory.])
+fi
+
+# Find out what GC implementation we want, or may, use.
+AC_ARG_WITH(gc,
+[ --with-gc={page,zone} choose the garbage collection mechanism to use
+ with the compiler],
+[case "$withval" in
+ page | zone)
+ GGC=ggc-$withval
+ ;;
+ *)
+ AC_MSG_ERROR([$withval is an invalid option to --with-gc])
+ ;;
+esac],
+[GGC=ggc-page])
+AC_SUBST(GGC)
+echo "Using $GGC for garbage collection."
+
+# Use the system's zlib library.
+zlibdir=-L../zlib
+zlibinc="-I\$(srcdir)/../zlib"
+AC_ARG_WITH(system-zlib,
+[ --with-system-zlib use installed libz],
+zlibdir=
+zlibinc=
+)
+AC_SUBST(zlibdir)
+AC_SUBST(zlibinc)
+
+dnl Very limited version of automake's enable-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],
+ maintainer_mode=$enableval,
+ maintainer_mode=no)
+
+AC_MSG_RESULT($maintainer_mode)
+
+if test "$maintainer_mode" = "yes"; then
+ MAINT=''
+else
+ MAINT='#'
+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
+# --------------
+
+# Make empty files to contain the specs and options for each language.
+# Then add #include lines to for a compiler that has specs and/or options.
+
+lang_opt_files=
+lang_specs_files=
+lang_tree_files=
+for subdir in . $subdirs
+do
+ if test -f $srcdir/$subdir/lang.opt; then
+ lang_opt_files="$lang_opt_files $srcdir/$subdir/lang.opt"
+ fi
+ if test -f $srcdir/$subdir/lang-specs.h; then
+ lang_specs_files="$lang_specs_files $srcdir/$subdir/lang-specs.h"
+ fi
+ if test -f $srcdir/$subdir/$subdir-tree.def; then
+ lang_tree_files="$lang_tree_files $srcdir/$subdir/$subdir-tree.def"
+ fi
+done
+
+# These (without "all_") are set in each config-lang.in.
+# `language' must be a single word so is spelled singularly.
+all_languages=
+all_boot_languages=
+all_compilers=
+all_stagestuff=
+all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders libada-mk'
+# List of language makefile fragments.
+all_lang_makefrags=
+# List of language subdirectory makefiles. Deprecated.
+all_lang_makefiles=
+# Files for gengtype
+all_gtfiles="$target_gtfiles"
+# Files for gengtype with language
+all_gtfiles_files_langs=
+all_gtfiles_files_files=
+
+# Add the language fragments.
+# Languages are added via two mechanisms. Some information must be
+# recorded in makefile variables, these are defined in config-lang.in.
+# We accumulate them and plug them into the main Makefile.
+# The other mechanism is a set of hooks for each of the main targets
+# like `clean', `install', etc.
+
+language_hooks="Make-hooks"
+
+for s in $subdirs
+do
+ language=
+ boot_language=
+ compilers=
+ stagestuff=
+ outputs=
+ gtfiles=
+ . ${srcdir}/$s/config-lang.in
+ if test "x$language" = x
+ then
+ echo "${srcdir}/$s/config-lang.in doesn't set \$language." 1>&2
+ exit 1
+ fi
+ all_lang_makefrags="$all_lang_makefrags \$(srcdir)/$s/Make-lang.in"
+ if test -f ${srcdir}/$s/Makefile.in
+ then all_lang_makefiles="$s/Makefile"
+ fi
+ all_languages="$all_languages $language"
+ if test "x$boot_language" = xyes
+ then
+ all_boot_languages="$all_boot_languages $language"
+ fi
+ all_compilers="$all_compilers $compilers"
+ all_stagestuff="$all_stagestuff $stagestuff"
+ all_outputs="$all_outputs $outputs"
+ all_gtfiles="$all_gtfiles $gtfiles"
+ for f in $gtfiles
+ do
+ all_gtfiles_files_langs="$all_gtfiles_files_langs ${s} "
+ all_gtfiles_files_files="$all_gtfiles_files_files ${f} "
+ done
+done
+
+# Pick up gtfiles for c
+gtfiles=
+s="c"
+. ${srcdir}/c-config-lang.in
+all_gtfiles="$all_gtfiles $gtfiles"
+for f in $gtfiles
+do
+ all_gtfiles_files_langs="$all_gtfiles_files_langs ${s} "
+ all_gtfiles_files_files="$all_gtfiles_files_files ${f} "
+done
+
+check_languages=
+for language in $all_languages
+do
+ check_languages="$check_languages check-$language"
+done
+
+# We link each language in with a set of hooks, reached indirectly via
+# lang.${target}.
+
+rm -f Make-hooks
+touch Make-hooks
+target_list="all.build all.cross start.encap rest.encap tags \
+ install-normal install-common install-man \
+ uninstall info man srcextra srcman srcinfo \
+ mostlyclean clean distclean maintainer-clean \
+ stage1 stage2 stage3 stage4 stageprofile stagefeedback"
+for t in $target_list
+do
+ x=
+ for lang in $all_languages
+ do
+ x="$x $lang.$t"
+ done
+ echo "lang.$t: $x" >> Make-hooks
+done
+
+# --------
+# UNSORTED
+# --------
+
+# Create .gdbinit.
+
+echo "dir ." > .gdbinit
+echo "dir ${srcdir}" >> .gdbinit
+if test x$gdb_needs_out_file_path = xyes
+then
+ echo "dir ${srcdir}/config/"`dirname ${out_file}` >> .gdbinit
+fi
+if test "x$subdirs" != x; then
+ for s in $subdirs
+ do
+ echo "dir ${srcdir}/$s" >> .gdbinit
+ done
+fi
+echo "source ${srcdir}/gdbinit.in" >> .gdbinit
+
+# If $(exec_prefix) exists and is not the same as $(prefix), then compute an
+# absolute path for gcc_tooldir based on inserting the number of up-directory
+# movements required to get from $(exec_prefix) to $(prefix) into the basic
+# $(libsubdir)/@(unlibsubdir) based path.
+# Don't set gcc_tooldir to tooldir since that's only passed in by the toplevel
+# make and thus we'd get different behavior depending on where we built the
+# sources.
+if test x$exec_prefix = xNONE -o x$exec_prefix = x$prefix; then
+ gcc_tooldir='$(libsubdir)/$(unlibsubdir)/../$(target_noncanonical)'
+else
+changequote(<<, >>)dnl
+# An explanation of the sed strings:
+# -e 's|^\$(prefix)||' matches and eliminates 'prefix' from 'exec_prefix'
+# -e 's|/$||' match a trailing forward slash and eliminates it
+# -e 's|^[^/]|/|' forces the string to start with a forward slash (*)
+# -e 's|/[^/]*|../|g' replaces each occurrence of /<directory> with ../
+#
+# (*) Note this pattern overwrites the first character of the string
+# with a forward slash if one is not already present. This is not a
+# problem because the exact names of the sub-directories concerned is
+# unimportant, just the number of them matters.
+#
+# The practical upshot of these patterns is like this:
+#
+# prefix exec_prefix result
+# ------ ----------- ------
+# /foo /foo/bar ../
+# /foo/ /foo/bar ../
+# /foo /foo/bar/ ../
+# /foo/ /foo/bar/ ../
+# /foo /foo/bar/ugg ../../
+#
+ dollar='$$'
+ gcc_tooldir="\$(libsubdir)/\$(unlibsubdir)/\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/\$(dollar)||' -e 's|^[^/]|/|' -e 's|/[^/]*|../|g'\`\$(target_noncanonical)"
+changequote([, ])dnl
+fi
+AC_SUBST(gcc_tooldir)
+AC_SUBST(dollar)
+
+# Find a directory in which to install a shared libgcc.
+
+AC_ARG_ENABLE(version-specific-runtime-libs,
+[ --enable-version-specific-runtime-libs
+ specify that runtime libraries should be
+ installed in a compiler-specific directory])
+
+AC_ARG_WITH(slibdir,
+[ --with-slibdir=DIR shared libraries in DIR [LIBDIR]],
+slibdir="$with_slibdir",
+if test "${enable_version_specific_runtime_libs+set}" = set; then
+ slibdir='$(libsubdir)'
+elif test "$host" != "$target"; then
+ slibdir='$(build_tooldir)/lib'
+else
+ slibdir='$(libdir)'
+fi)
+AC_SUBST(slibdir)
+
+objdir=`${PWDCMD-pwd}`
+AC_SUBST(objdir)
+
+# Substitute configuration variables
+AC_SUBST(subdirs)
+AC_SUBST(srcdir)
+AC_SUBST(all_boot_languages)
+AC_SUBST(all_compilers)
+AC_SUBST(all_gtfiles)
+AC_SUBST(all_gtfiles_files_langs)
+AC_SUBST(all_gtfiles_files_files)
+AC_SUBST(all_lang_makefrags)
+AC_SUBST(all_lang_makefiles)
+AC_SUBST(all_languages)
+AC_SUBST(all_stagestuff)
+AC_SUBST(build_exeext)
+AC_SUBST(build_install_headers_dir)
+AC_SUBST(build_xm_file_list)
+AC_SUBST(build_xm_include_list)
+AC_SUBST(build_xm_defines)
+AC_SUBST(check_languages)
+AC_SUBST(cc_set_by_configure)
+AC_SUBST(quoted_cc_set_by_configure)
+AC_SUBST(cpp_install_dir)
+AC_SUBST(xmake_file)
+AC_SUBST(tmake_file)
+AC_SUBST(extra_gcc_objs)
+AC_SUBST(extra_headers_list)
+AC_SUBST(extra_objs)
+AC_SUBST(extra_parts)
+AC_SUBST(extra_passes)
+AC_SUBST(extra_programs)
+AC_SUBST(float_h_file)
+AC_SUBST(gcc_config_arguments)
+AC_SUBST(gcc_gxx_include_dir)
+AC_SUBST(libstdcxx_incdir)
+AC_SUBST(gcc_version)
+AC_SUBST(gcc_version_full)
+AC_SUBST(gcc_version_trigger)
+AC_SUBST(host_exeext)
+AC_SUBST(host_xm_file_list)
+AC_SUBST(host_xm_include_list)
+AC_SUBST(host_xm_defines)
+AC_SUBST(out_host_hook_obj)
+AC_SUBST(install)
+AC_SUBST(lang_opt_files)
+AC_SUBST(lang_specs_files)
+AC_SUBST(lang_tree_files)
+AC_SUBST(local_prefix)
+AC_SUBST(md_file)
+AC_SUBST(objc_boehm_gc)
+AC_SUBST(out_file)
+AC_SUBST(out_object_file)
+AC_SUBST(stage_prefix_set_by_configure)
+AC_SUBST(quoted_stage_prefix_set_by_configure)
+AC_SUBST(symbolic_link)
+AC_SUBST(thread_file)
+AC_SUBST(tm_file_list)
+AC_SUBST(tm_include_list)
+AC_SUBST(tm_defines)
+AC_SUBST(tm_p_file_list)
+AC_SUBST(tm_p_include_list)
+AC_SUBST(xm_file_list)
+AC_SUBST(xm_include_list)
+AC_SUBST(xm_defines)
+AC_SUBST(target_noncanonical)
+AC_SUBST(c_target_objs)
+AC_SUBST(cxx_target_objs)
+AC_SUBST(target_cpu_default)
+
+AC_SUBST_FILE(language_hooks)
+
+# If it doesn't already exist, create document directory
+echo "checking for the document directory." 1>&2
+if test -d doc ; then
+ true
+else
+ mkdir doc
+fi
+
+# Echo link setup.
+if test x${build} = x${host} ; then
+ if test x${host} = x${target} ; then
+ echo "Links are now set up to build a native compiler for ${target}." 1>&2
+ else
+ echo "Links are now set up to build a cross-compiler" 1>&2
+ echo " from ${host} to ${target}." 1>&2
+ fi
+else
+ if test x${host} = x${target} ; then
+ echo "Links are now set up to build (on ${build}) a native compiler" 1>&2
+ echo " for ${target}." 1>&2
+ else
+ echo "Links are now set up to build (on ${build}) a cross-compiler" 1>&2
+ echo " from ${host} to ${target}." 1>&2
+ 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)
+
+# Create the Makefile
+# and configure language subdirectories
+AC_CONFIG_FILES($all_outputs)
+
+AC_CONFIG_COMMANDS([default],
+[
+case ${CONFIG_HEADERS} in
+ *auto-host.h:config.in*)
+ echo > cstamp-h ;;
+esac
+# Make sure all the subdirs exist.
+for d in $subdirs
+do
+ test -d $d || mkdir $d
+done
+# If the host supports symlinks, point stage[1234] at ../stage[1234] so
+# bootstrapping and the installation procedure can still use
+# CC="stage1/xgcc -Bstage1/". If the host doesn't support symlinks,
+# FLAGS_TO_PASS has been modified to solve the problem there.
+# This is virtually a duplicate of what happens in configure.lang; we do
+# an extra check to make sure this only happens if ln -s can be used.
+if test "$symbolic_link" = "ln -s"; then
+ for d in ${subdirs} fixinc ; do
+ STARTDIR=`${PWDCMD-pwd}`
+ cd $d
+ for t in stage1 stage2 stage3 stage4 stageprofile stagefeedback include
+ do
+ rm -f $t
+ $symbolic_link ../$t $t 2>/dev/null
+ done
+ cd $STARTDIR
+ done
+else true ; fi
+],
+[subdirs='$subdirs'
+symbolic_link='$symbolic_link'
+])
+AC_OUTPUT
diff --git a/gcc/cp/ChangeLog.3 b/gcc/cp/ChangeLog.3
new file mode 100644
index 00000000000..57e96f315f5
--- /dev/null
+++ b/gcc/cp/ChangeLog.3
@@ -0,0 +1,22648 @@
+2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13507
+ * decl.c (duplicate_decls): Use build_type_attribute_variant to
+ merge attributes.
+
+ PR c++/13494
+ * tree.c (build_cplus_array_type_1): Only build a minimal array
+ type for dependent types or domains.
+
+2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12774
+ * typeck.c (comp_array_types): Fold non-dependent domains for
+ ABI-1.
+
+2003-12-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13289
+ * semantics.c (finish_id_expression): Only check if the type of
+ a template argument is integral or enumeration when it is not
+ dependent.
+
+2003-12-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12403
+ * parser.c (cp_parser_template_declaration_after_export): Set up
+ template specialization scope in case of explicit specialization.
+
+2003-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13081
+ * decl.c (duplicate_decls): Preserve inline-ness when redeclaring
+ a function template.
+
+ PR c++/12613
+ * decl.c (reshape_init): Reject GNU colon-style designated
+ initializers in arrays.
+
+ PR c++/13009
+ * call.c (build_special_member_call): Do not assume that we have a
+ pointer to the complete object in an assignment operator.
+
+2003-12-28 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/13070
+ * decl.c (duplicate_decls): When setting the type of an anticipated
+ declaration, merge the existing type attributes.
+
+2003-12-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/13268, c++/13339
+ * class.c (add_method): Return early when method is error_mark_node.
+ * pt.c (tsubst_friend_function): Return early when new_friend is
+ error_mark_node.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-lang.c (cp_expr_size): Return zero for empty classes.
+
+ * cp-tree.h (warn_if_uknown_interface): Remove unused function.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+
+2003-12-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13387
+ * cp-lang.c (cxx_get_alias_set): Correct logic for a base type.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_function): Do not check
+ flag_alt_external_templates or flag_external_templates.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+ * lex.c (extract_interface_info): Likewise.
+ * pt.c (lookup_template_class): Likewise.
+
+ PR c++/12862
+ * name-lookup.c (pushdecl): Look up all namespace-scope entities
+ in their corresponding namespace.
+
+ PR c++/12397
+ * typeck.c (finish_class_member_access_expr): Don't tree
+ IDENTIFIER_NODEs as non-dependent expressions.
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/5050
+ * tree.c (cp_start_inlining): Remove.
+ (cp_end_inlining): Remove.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Do not define.
+ (LANG_HOOKS_TREE_INLINING_END_INLINING): Do not define.
+ * cp-tree.h (cp_start_inlining): Do not declare.
+ (cp_end_inlining): Do not declare.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12479
+ * parser.c (cp_parser_declaration_seq_opt): Only issue "extra ;"
+ pedwarn when not in a system header.
+
+2003-12-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Remove CPTI_RECORD_TYPE,
+ CPTI_UNION_TYPE, CPTI_ENUM_TYPE.
+ (record_type_node): Remove.
+ (union_type_node): Likewise.
+ (enum_type_node): Likewise.
+ * decl.c: Remove mention of above tree nodes in comment.
+ * lex.c (cxx_init): Do not assign to record_type_node,
+ union_type_node, or enum_type_node. Simplify handling of
+ class_type_node.
+
+ PR c++/11554
+ * init.c (sort_mem_initializers): Add warning.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * semantics.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cvt.c: Remove uses of "register" specifier in
+ declarations of arguments and local variables.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * expr.c: Likewise.
+ * friend.c: Likewise.
+ * lex.c: Likewise.
+ * name-lookup.c: Likewise.
+ * repo.c: Likewise.
+ * search.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-12-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12795
+ * name-lookup.c (pushdecl): Do not treated any functions as being
+ "nested" in C++.
+
+2003-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/13371
+ * typeck.c (build_modify_expr): Stabilize lhs if we're narrowing.
+ * cvt.c (convert_to_void): Don't warn about the RHS of a comma
+ being useless if TREE_NO_UNUSED_WARNING is set.
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct lang_type_header): Remove __extension__.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/12253
+ * init.c (build_vec_init): Initialization of an element from
+ an initializer list is also a full-expression.
+
+ * parser.c, pt.c, semantics.c: Rename constant_expression_p
+ to integral_constant_expression_p.
+
+2003-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13262
+ * pt.c (instantiate_decl): Wrap push_nested_class and
+ pop_nested_class around cp_finish_decl call for static member
+ variable.
+
+2003-12-18 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/9154
+ * parser.c (cp_parser_template_argument): A type-id followed by '>>'
+ is just an user typo, and should be accepted as last resort if any
+ other parsing fails.
+ (cp_parser_enclosed_template_argument_list): If the argument list is
+ parsed correctly, but the next token is '>>', emit a diagnostic.
+ (cp_parser_next_token_ends_template_argument): Accept '>>' as
+ delimiter of template argument, it will be later detected as a typo.
+
+2003-12-17 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in: Replace cp/g++.1 with $(docobjdir)/g++.1.
+
+2003-12-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10603
+ PR c++/12827
+ * parser.c (cp_parser_error): Help c_parse_error print good
+ messages if the next token is a keyword.
+ (cp_parser_parameter_declaration_list): When resynchronizing after
+ a bad parameter declaration, stop if a comma is found.
+ (cp_parser_parameter_declaration): Avoid backtracking.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12696
+ * decl.c (reshape_init): Recover quickly from errors.
+
+2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9043
+ C++ ABI change: Mangling array indices in templates.
+ * decl.c (compute_array_index_type): Reorganize for earlier
+ template errors. Use value_dependent_expression_p for abi-2.
+ * mangle.c (write_array_type): Check broken mangling for
+ expression indices on abi-1
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12696
+ * decl.c (reshape_init): Recover quickly from errors.
+
+ PR c++/13275
+ * lex.c (reswords): Add "__offsetof" and "__offsetof__".
+ * parser.c (cp_parser): Add in_offsetof_p.
+ (cp_parser_new): Initialize it.
+ (cp_parser_primary_expression): Handle __offsetof__ (...).
+ (cp_parser_postfix_expression): Allow casts to pointer type and
+ uses of "->" in a constant expression if implementing offsetof.
+ (cp_parser_unary_expression): Allow the use of "&" in a constant
+ expression if implementing offsetof.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
+ if the declaration comes from an using declaration.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * semantics.c (finish_id_expression): Refactor the code to handle
+ template parameters, and emit a more informative error message
+ when they are used within an integral constant expression.
+
+2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13387
+ * class.c (finish_struct_1): Compute mode and alias set for
+ CLASSTYPE_AS_BASE.
+ * call.c (build_over_call): Use CLASSTYPE_AS_BASE for trivial
+ assignment of a class, as necessary.
+ * cp-lang.c (cxx_get_alias_set): The alias set as a base is the
+ same as for the complete type.
+
+ PR c++/13242
+ C++ ABI change. Mangling template parameters of reference type
+ * mangle.c (write_template_args): Remove unreachable code.
+ (write_template_arg): Look through an argument of reference type.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
+ if the declaration comes from an using declaration.
+
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10926
+ * decl2.c (grokfield): Robustify.
+
+ PR c++/11116
+ * parser.c (cp_parser_throw_expression): Determine whether or not
+ an assignment-expression is present by doing one-token lookahead.
+
+ PR c++/13269
+ * parser.c (cp_parser_function_definition_after_declarator): Stop
+ scanning tokens when reaching EOF.
+
+ PR c++/12989
+ * typeck.c (cxx_sizeof_or_alignof_expr): Robustify.
+
+ PR c++/13310
+ * pt.c (dependent_template_p): Handle OVERLOADs.
+
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13243
+ PR c++/12573
+ * parser.c (cp_parser_postfix_expression): Tighten handling of
+ integral constant expressions.
+ (cp_parser_unary_expression): Likewise.
+ * pt.c (value_dependent_expression_p): Remove handling for
+ COMPONENT_REFs.
+
+2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Disallow destructor for java classes.
+ * decl.c (xref_basetypes): Check java class inheritance.
+ * decl2.c (check_java_method): Skip artificial params.
+
+ PR c++/13241
+ C++ ABI change. Mangling of symbols in expressions.
+ * mangle.c (write_mangled_name): Add top_level flag. Rework for
+ nested and unnested mangling. Deal with abi version 1 and version
+ 2 differences.
+ (write_expression): Adjust write_mangled_name call.
+ (mangle_decl_string): Use write_mangled_name for all non-type decls.
+
+2003-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10779
+ PR c++/12160
+ * parser.c (struct cp_parser): Add in_template_argument_list_p.
+ (cp_parser_error): Use c_parse_error.
+ (cp_parser_name_lookup_error): New function.
+ (cp_parser_new): Initialize it.
+ (cp_parser_declarator): Add parenthesized_p parameter.
+ (cp_parser_nested_name_specifier_opt): Use
+ cp_parser_name_lookup_error.
+ (cp_parser_parenthesized_expression_list): Improve comments.
+ (cp_parser_condition): Adjust call to cp_parser_declarator.
+ (cp_parser_template_parameter): Adjust call to
+ cp_parser_parameter_declaration.
+ (cp_parser_template_argument_list): Set
+ in_template_argument_list_p.
+ (cp_parser_explicit_instantiation): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_simple_type_specifier): Remove unncessary code.
+ (cp_parser_using_declaration): Use cp_parser_name_lookup_error.
+ (cp_parser_init_declarator): Handle member function definitions.
+ (cp_parser_direct_declarator): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_type_id): Adjust call to cp_parser_declarator.
+ (cp_parser_parameter_declaration_list): Avoid backtracking where
+ possible.
+ (cp_parser_parameter_declaration): Add parenthesized_p parameter.
+ (cp_parser_function_definition): Remove.
+ (cp_parser_member_declaration): Do not backtrack to look for
+ function definitions.
+ (cp_parser_exception_declaration): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_single_declaration): Handle function definitions via
+ cp_parser_init_declarator.
+ (cp_parser_save_member_function_body): New function.
+
+2003-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13106
+ * decl.c (finish_function): Check if return type is dependent before
+ issuing no return statement warning.
+
+2003-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13118
+ * cp-tree.h (lang_decl_u): Add thunk_alias member.
+ (THUNK_VIRTUAL_OFFSET): Must be a FUNCTION_DECL.
+ (THUNK_ALIAS_P): Remove.
+ (THUNK_ALIAS): Adjust.
+ * class.c (update_vtable_entry_for_fn): Get the vbase within the
+ overriding function's return type.
+ (dump_thunk): Adjust THUNK_ALIAS printing.
+ (build_vtbl_initializer): Adjust THUNK_ALIAS use.
+ * method.c (make_thunk): Revert 12881 test change. Clear
+ THUNK_ALIAS.
+ (finish_thunk): Adjust THUNK_ALIAS setting.
+ (use_thunk): Adjust THUNK_ALIAS use.
+ * semantics.c (emit_associated_thunks): Likewise.
+
+ PR c++/13114, c++/13115
+ * class.c (layout_empty_base): Propagate the move of an empty base
+ to offset zero.
+
+ PR c++/12881
+ * method.c (make_thunk): Deal with thunk aliases when searching
+ for a thunk. Robustify assertion.
+
+2003-12-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * mangle.c (conv_type_names): Holds IDENTIFIER_NODEs only.
+ (hash_type): Use TYPE_UID of the identifier's type.
+ (compare_type): Adjust.
+ (mangle_conv_op_name_for_type): Store identifier nodes only, use
+ TYPE_UID has hash value.
+
+2003-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CONV_FN_P): Check that DECL_NAME is non-NULL.
+
+2003-12-08 Matt Austern <austern@apple.com>
+
+ PR c/13134
+ * decl.c (duplicate_decls): Copy visibility flag when appropriate.
+
+2003-12-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * init.c (build_new_1): Deal with an OVERLOAD set when
+ looking up for _Jv_AllocObject.
+ * except.c (build_throw): Likewise for _Jv_Throw.
+
+2003-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/11971
+ * tree.c (build_local_temp): Split out from build_cplus_new.
+ (force_target_expr): New fn.
+ * call.c (call_builtin_trap): Call it. Take a type parm.
+ (convert_arg_to_ellipsis): Pass it.
+ (build_x_va_arg): Use call_builtin_trap.
+
+ PR c++/11929
+ * call.c (magic_varargs_p): New fn.
+ (build_over_call): Do no ellipsis conversions for arguments to
+ functions with magic varargs.
+
+ * name-lookup.c, init.c, except.c: Revert Giovanni's patch from
+ yesterday.
+
+ Give the anonymous namespace a null DECL_NAME.
+ * cp-tree.h: Don't declare anonymous_namespace_name.
+ * decl.c: Don't define it.
+ * dump.c (cp_dump_tree): Don't check for it.
+ * cxx-pretty-print.c (pp_cxx_original_namespace_definition): Likewise.
+ * error.c (dump_decl): Likewise.
+ * name-lookup.c: Define it here.
+ (push_namespace): Put it in DECL_ASSEMBLER_NAME instead.
+ * mangle.c (write_unqualified_name): Adjust.
+
+2003-12-07 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): Always construct an
+ OVERLOAD unless the declaration is a built-in.
+ (set_namespace_binding): While binding OVERLOADs with only one
+ declaration, we still need to call supplement_binding.
+ * init.c (build_new_1): Deal with an OVERLOAD set when
+ looking up for _Jv_AllocObject.
+ * except.c (build_throw): Likewise for _Jv_Throw.
+
+2003-12-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13323
+ * class.c (same_signature_p): Handle conversion operators
+ correctly.
+ (check_for_override): Likewise.
+
+2003-12-06 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (GXX_CROSS_NAME, CXX_CROSS_NAME): Delete.
+ (c++.install_common, cp/g++.1, c++.install-man): Adjust for above.
+ (c++.uninstall): Likewise.
+
+2003-12-05 Danny Smith <dannysmith@gcc.gnu.org>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13305
+ * parser.c (cp_parser_elaborated_type_specifier): Accept
+ attributes.
+
+2003-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13314
+ * parser.c (cp_parser_class_specifier): Match push_scope/pop_scope
+ calls.
+ (cp_parser_class_head): Likewise.
+
+2003-12-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13166
+ * parser.c (cp_parser_late_parsing_default_args): Make sure the
+ context is a class before calling push_nested_class and
+ pop_nested_class.
+
+2003-12-03 James E Wilson <wilson@specifixinc.com>
+
+ * g++spec.c (lang_specific_driver): Delete USE_LIBUNWIND_EXCEPTIONS
+ support.
+
+2003-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9127
+ * cp-tree.h (at_namespace_scope_p): New function.
+ * parser.c (cp_parser_class_head): Handle invalid explicit
+ specializations.
+ * search.c (at_namespace_scope_p): New function.
+
+ PR c++/13179
+ * semantics.c (finish_handler_parms): Do not call eh_type_info for
+ types used in templates.
+
+ PR c++/10771
+ * parser.c (cp_parser_check_for_invalid_template_id): New
+ function.
+ (cp_parser_simple_type_specifier): Use it.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_class_head): Likewise.
+
+2003-12-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/10126
+ * pt.c (convert_nontype_argument): Handle default conversions
+ while converting a pointer to member function.
+
+2003-12-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/12573
+ * pt.c (value_dependent_expression_p): Handle COMPONENT_REFs by
+ looking into them recursively.
+
+2003-12-02 Richard Henderson <rth@redhat.com>
+
+ * name-lookup.h (struct cp_binding_level): Use ENUM_BITFIELD.
+ * parser.c (struct cp_token): Likewise.
+ (struct cp_parser_token_tree_map_node): Likewise.
+ * lex.c (struct resword): Move const after ENUM_BITFIELD.
+
+2003-11-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9849
+ * parser.c (cp_lexer_prev_token): New function.
+ (cp_parser_skip_to_closing_parenthesis): Add consume_paren
+ parameter.
+ (cp_parser_nested_name_specifier_opt): Add is_declaration
+ parameter.
+ (cp_parser_nested_name_specifier): Likewise.
+ (cp_parser_class_or_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_id_expression): Adjust calls to
+ cp_parser_nested_name_specifier_op, cp_parser_template_id,
+ cp_parser_class_name.
+ (cp_parser_unqualified_id): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_pseudo_destructor_name): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_mem_initializer_id): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_type_name): Likewise.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_qualified_namespace_specifier): Likewise.
+ (cp_parser_using_declaration): Likewise.
+ (cp_parser_using_directive): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_declarator_id): Likewise.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_base_specifier): Likewise.
+ (cp_parser_constructor_declarator_p): Likewise.
+ (cp_parser_direct_declarator): Fix typo in comment.
+ (cp_parser_parenthesized_expression_list): Adjust call to
+ cp_parser_skip_to_closing_parenthesis.
+ (cp_parser_selection_statement): Likewise.
+
+2003-11-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12924
+ * typeck.c (finish_class_member_access_expr): Handle TEMPLATE_ID_EXPR
+ with OVERLOAD and DECL nodes as the first operand.
+
+2003-11-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst) <ARRAY_REF>: Remove erroneous argument to build_nt.
+
+2003-11-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5369
+ * friend.c (is_friend): Handle member function of a class
+ template as template friend.
+ (do_friend): Likewise.
+ * decl2.c (check_classfn): Add template_header_p parameter.
+ * decl.c (start_decl): Adjust check_classfn call.
+ (grokfndecl): Likewise.
+ * pt.c (is_specialization_of_friend): New function.
+ (uses_template_parms_level): Likewise.
+ (push_template_decl_real): Use uses_template_parms_level.
+ (tsubst_friend_function): Adjust check_classfn call.
+ * cp-tree.h (check_classfn): Adjust declaration.
+ (uses_template_parms_level): Add declaration.
+ (is_specialization_of_friend): Likewise.
+
+2003-11-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12515
+ * pt.c (build_non_dependent_expr): Handle GNU extension to ?:
+ operator.
+
+2003-11-21 Jan Hubicka <jh@suse.cz>
+
+ * parser.c (cp_parser_postfix_expression): Initialize 's' to
+ NULL_TREE.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (c++.extraclean): Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (check-g++, lang_checks): Add.
+
+2003-11-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12932
+ * class.c (currently_open_derived_class): Check if
+ current_class_type is NULL_TREE.
+ * semantics.c (finish_call_expr): Check if
+ currently_open_derived_class returns NULL_TREE.
+ * cp-tree.h (DERIVED_FROM_P): Add parenthesis around PARENT
+ parameter.
+
+2003-11-17 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Preevaluate placement args.
+ * call.c (build_op_delete_call): Don't expose placement args to
+ overload resolution.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (c++.tags): Create TAGS.sub files in each directory
+ and TAGS files that include them for each front end.
+
+2003-11-15 Bernardo Innocenti <bernie@develer.com>
+
+ PR c++/2294
+ * name-lookup.c: Revert previous patch for PR c++/2294 to prevent
+ build failure on libjava.
+
+2003-11-14 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): Always construct an OVERLOAD
+ unless the declaration is a built-in.
+ (set_namespace_binding): While binding OVERLOADs with only one
+ declaration, we still need to call supplement_binding.
+
+2003-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12762
+ * parser.c (cp_parser_enclosed_template_argument_list): New
+ function.
+ (cp_parser_template_id): Use it.
+ (cp_parser_simple_type_specifier): Recognize invalid template
+ syntax.
+
+2003-11-14 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/2094
+ * pt.c (unify): Add support for PTRMEM_CST and
+ FIELD_DECL unification.
+
+2003-11-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * decl.c (grokfndecl): Change OK to type tree.
+
+2003-11-12 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (build_target_expr_with_type): Treate VA_ARG_EXPR like
+ CONSTRUCTOR.
+
+ * decl.c (cp_make_fname_decl): When creating a top-level
+ __FUNCTION__-like symbol, do register it with pushdecl.
+
+ * decl.c (finish_case_label): Do not check that we are within a
+ switch statement here.
+ * parser.c (struct cp_parser): Add in_iteration_statement_p and
+ in_switch_statement_p.
+ (cp_parser_new): Initialize them.
+ (cp_parser_labeled_statement): Check validity of case labels
+ here.
+ (cp_parser_selection_statement): Set in_switch_statement_p.
+ (cp_parser_iteration_statement): Set in_iteration_statement_p.
+ (cp_parser_jump_statement): Check validity of break/continue
+ statements here.
+
+ PR c++/12735
+ * cp-tree.h (duplicate_decls): Return a tree.
+ * decl.c (duplicate_decls): Clarify documentation. Return
+ error_mark_node to indicate a failed redeclaration.
+ * friend.c (do_friend): Handle that case.
+ * name-lookup.c (pushdecl): Likewise.
+
+2003-11-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_NAMESPACE_ASSOCIATIONS): New macro.
+ * name-lookup.c (parse_using_directive): New fn.
+ (is_associated_namespace): New fn.
+ (arg_assoc_namespace): Also check associated namespaces.
+ * name-lookup.h: Declare new fns.
+ * pt.c (maybe_process_partial_specialization): Allow
+ specialization in associated namespace.
+ * parser.c (cp_parser_using_directive): Accept attributes. Use
+ parse_using_directive.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * cvt.c (convert_to_void): Use void_zero_node after overload failure.
+
+2003-11-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/12832
+ * name-lookup.c (supplement_binding): Gracefully handle names
+ used at non-class scope prior declaration.
+
+2003-11-06 Matt Austern <austern@apple.com>
+
+ * decl.c (duplicate_decls): copy DECL_VISIBILITY field.
+ * method.c (use_thunk): give thunk same visibility as function.
+ * optimize.c (maybe_clone_body): copy DECL_VISIBILITY field.
+
+2003-11-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11616
+ * pt.c (instantiate_pending_templates): Save and restore
+ input_location.
+
+2003-11-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2019
+ * friend.c (add_friend): Don't display previous declaration in
+ case of duplicate friend warning.
+
+2003-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9810
+ * call.c (build_over_call): Check access using primary template
+ if FN is a member function template.
+
+2003-11-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12796
+ * class.c (handle_using_decl): Set input_location before calling
+ error_not_base_type.
+
+2003-10-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10371
+ * semantics.c (finish_non_static_data_member): Handle when
+ both processing_template_decl and qualifying_scope are true.
+
+2003-10-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11076
+ * class.c (handle_using_decl): Swap arguments of error_not_base_type.
+ * parser.c (cp_parser_direct_declarator): Only resolve typename for
+ namespace scope declarations.
+
+2003-10-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12698, c++/12699, c++/12700, c++/12566
+ * cp-tree.h (THUNK_ALIAS_P, THUNK_ALIAS): New.
+ (debug_class, debug_thunks): New.
+ * class.c (dump_class_hierarchy_1): New break out from ...
+ (dump_class_hierarchy): ... here.
+ (dump_thunk, debug_thunks, debug_class): New.
+ (update_vtable_entry_for_fn): Add ssizetype casts. Correct
+ continued search for primary binfo via virtual.
+ (build_vtbl_initializer): Follow covariant thunk alias.
+ * method.c (make_thunk): Clear DECL_THUNKS of the thunk.
+ (finish_thunk): Look for an alias of the covariant thunk and point
+ to it.
+ (use_thunk): We should never use an alias.
+ * semantics.c (emit_associated_thunks): Do not emit aliases.
+
+ PR c++/12566
+ * cp-tree.h (cp_fname_init): Add TYPE pointer param.
+ * decl.c (cp_fname_init): Add TYPE pointer param. Set it. Don't
+ create an ad-hoc ERROR_MARK.
+ (cp_make_fname_decl): Adjust.
+ * pt.c (tsubst_expr): Adjust.
+
+2003-10-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/12726
+ * tree.c (build_target_expr_with_type): Don't call force_rvalue
+ for CONSTRUCTORs.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * init.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11962
+ * typeck.c (build_x_conditional_expr): Handle missing middle
+ operands in templates.
+ * mangle.c (write_expression): Issue errors about attempts to
+ mangle a non-existant middle operator to the ?: operator.
+
+2003-10-21 Robert Bowdidge <bowdidge@apple.com>
+ * decl.c (cp_finish_decl): Remove clause intended for asm directives
+ in struct or class fields: this code is never executed.
+
+2003-10-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (start_decl): Exit if push_template_decl returns
+ error_mark_node.
+
+2003-10-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix typos.
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (start_cleanup_fn): Set DECL_DECLARED_INLINE_P to deffer
+ the expansion.
+
+2003-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (c++.install-info): Remove.
+
+2003-10-20 Jason Merrill <jason@redhat.com>
+
+ * class.c (layout_class_type): Set DECL_ARTIFICIAL on padding
+ field.
+
+2003-10-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9781, c++/10583, c++/11862
+ * decl.c (cp_finish_decl): Exit immediately if decl is an
+ error_mark_node.
+ * pt.c (push_template_decl_real): Return error_mark_node for
+ invalid template declaration of variable.
+
+2003-10-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12495
+ * pt.c (lookup_template_class): Handle when current_class_type
+ is a local class.
+
+2003-10-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2513
+ * decl.c (make_typename_type): Use dependent_type_p.
+ (make_unbound_class_template): Likewise.
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl during substitution of template friend
+ function. Preincrement processing_template_decl rather than
+ postincrement.
+ (get_mostly_instantiated_function_type): Increment
+ processing_template_decl during partial substitution of function
+ type.
+
+2003-10-15 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12574
+ * decl2.c (cxx_callgraph_analyze_expr): Deal with baselink.
+
+2003-10-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/11878
+ * tree.c (build_target_expr_with_type): Call force_rvalue for
+ classes with non-trivial copy ctors.
+
+ PR c++/11063
+ * typeck.c (build_modify_expr): Call convert rather than abort.
+
+2003-10-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Breack out decl.c (3/n)
+ * name-lookup.c: Include flags.h
+ (lookup_name_current_level): Make static.
+ (add_decl_to_level): Likewise.
+ (push_local_binding): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (lookup_type_current_level): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (namespace_ancestor): Likewise.
+ (push_using_directive): Likewise.
+ * decl.c (pushdecl): Move to name-lookup.c.
+ (pushdecl_top_level_1): Likewise.
+ (pushdecl_top_level): Likewise.
+ (pushdecl_top_level_and_finish): Likewise.
+ (maybe_push_decl): Likewise.
+ (push_using_decl): Likewise.
+ (push_overloaded_decl): Likewise.
+ (make_anon_name): Likewise.
+ (anon_cnt): Likewise.
+ (clear_anon_tags): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (check_for_out_of_scope_variable): Likewise.
+ * Make-lang.in (cp/name-lookup.o): Depend on flags.h.
+ * decl.c (warn_extern_redeclared_static): Export.
+ * cp-tree.h (warn_extern_redeclared_static): Declare.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Replace uses of $(target_alias) with
+ $(target_noncanonical).
+
+2003-10-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Add PR number to patch for PR c++/12370.
+
+2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (cxx_scope_find_binding_for_name): Don't export.
+ (binding_for_name): Likewise.
+ (cxx_binding_clear): Move to name-lookup.c.
+ * name-lookup.c (cxx_scope_find_binding_for_name): Now static.
+ (binding_for_name): Likewise.
+ * decl2.c (is_ancestor): Move to name-lookup.c
+ (namespace_ancestor): Likewise.
+ (add_using_namespace): Likewise.
+ (ambiguous_decl): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (set_decl_namespace): Likewise.
+ (decl_namespace): Likewise.
+ (current_decl_namespace): Likewise.
+ (push_decl_namespace): Likewise.
+ (pop_decl_namespace): Likewise.
+ (push_scope): Likewise.
+ (pop_scope): Likewise.
+ (struct arg_lookup): Likewise.
+ (arg_assoc): Likewise.
+ (arg_assoc_args): Likewise.
+ (arg_assoc_type): Likewise.
+ (add_function): Likewise.
+ (arg_assoc_namespace): Likewise.
+ (arg_assoc_class): Likewise.
+ (arg_assoc_template_arg): Likewise.
+ (do_namespace_alias): Likewise.
+ (validate_nonmember_using_decl): Likewise.
+ (do_nonmember_using_decl): Likewise.
+ (do_toplevel_using_decl): Likewise.
+ (do_local_using_decl): Likewise.
+ (do_class_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (constructor_name_full): Likewise.
+ (constructor_name): Likewise.
+ (constructor_name_p): Likewise.
+
+2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Break out decl.c (2/n)
+ * name-lookup.c: Include diagnostic.h
+ (cxx_binding_free): Make static.
+ (cxx_binding_make): Likewise.
+ (binding_table_new): Likewise
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (supplement_binding): Likewise.
+ * name-lookup.h (global_scope_name): Declare extern.
+ (global_type_node): Likewise.
+ (cxx_binding_free): Don't export.
+ (cxx_binding_make): Likewise.
+ (binding_table_new): Likewise.
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ * Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H)
+ * decl.c (lookup_namespace_name): Move to name-lookup.c
+ (select_decl): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_qualified_name): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_nonclass): Likewise.
+ (lookup_function_nonclass): Likewise.
+ (lookup_name): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (lookup_flags): Likewise.
+ (qualify_lookup): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_tag_reverse): Likewise.
+ (getdecls): Likewise.
+ (storedecls): Remove.
+ (cxx_remember_type_decls): Move to name-lookup.c.
+ (global_bindings_p): Likewise.
+ (innermost_nonclass_level): Likewise.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (kept_level_p): Likewise.
+ (innermost_scope_kind): Likewise.
+ (template_parm_scope_p): Likewise.
+ (push_binding): Likewise.
+ (push_local_binding): Likewise.
+ (add_decl_to_level): Likewise. Make extern.
+ (push_class_binding): Move to name-lookup.c.
+ (resume_level): Likewise. Rename to resume_scope.
+ (begin_scope): Move to name-lookup.c.
+ (indent): Likewise.
+ (binding_depth): Likewise.
+ (is_class_level): Likewise.
+ (cxx_scope_descriptor): Likewise.
+ (cxx_scope_debug): Likewise.
+ (namespace_scope_ht_size): Likewise.
+ (leave_scope): Likewise.
+ (pushlevel_class): Likewise.
+ (poplevel_class): Likewise.
+ (clear_identifier_class_values): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_using_directive): Likewise.
+ (identifier_global_value): Likewise.
+ (keep_next_level_flag): Likewise.
+ (keep_next_level): Likewise.
+ (free_binding_level): Likewise.
+ (set_class_shadows): Likewise.
+ (maybe_push_cleanup_level): Likewise.
+ (cp_namespace_decls): Likewise.
+ (bt_print_entry): Likewise.
+ (print_binding_level): Likewise.
+ (print_other_binding_stack): Likewise.
+ (print_binding_stack): Likewise.
+ (push_namespace): Likewise.
+ (pop_namespace): Likewise.
+ (push_nested_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (cxx_saved_binding_make): Likewise.
+ (struct cxx_saved_binding_make): Likewise.
+ (store_bindings): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (identifier_type_value): Likewise.
+ (set_identifier_type_value): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (pop_everything): Likewise.
+ (pushtag): Likewise.
+ (follow_tag_typedef): Likewise.
+ (maybe_process_template_type_declaration): Likewise.
+ (pop_binding): Likewise.
+ * cp-tree.h: Move corresponding declarations to name-lookup.h
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cvt.c (ocp_convert): Move warning to C common code.
+
+2003-10-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/6392
+ * tree.c (build_cplus_array_type): Handle all quals the same.
+ (cp_build_qualified_type_real): Look through arrays first.
+
+ * tree.c (build_cplus_new): Use build_decl to create a VAR_DECL.
+ (build_target_expr_with_type): Likewise.
+
+ * pt.c (instantiate_class_template): Sanity check that our
+ enclosing class has been instantiated.
+
+2003-10-08 Giovanni Bajo <giovannibajo@libero.it>
+
+ * cp_tree.h: Added TFF_NO_FUNCTION_ARGUMENTS.
+ * error.c (dump_function_decl): Use it to skip the dump of the
+ arguments.
+ (dump_expr): When dumping a declaration found within an
+ expression, always set TFF_NO_FUNCTION_ARGUMENTS
+ in the flags.
+
+2003-10-08 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/11097
+ * pt.c (tsubst_decl): Substitute also the DECL_NAME node of
+ USING_DECL.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10147
+ * call.c (initialize_reference): Tweak error message.
+ * cxx-pretty-print.h (cxx_pretty_printer_flags): Remove
+ pp_cxx_flag_qualified_id and pp_cxx_flag_global_scope.
+ * cxx-pretty-print.c (pp_cxx_id_expression): Always display
+ qualified entities using qualified names.
+
+ PR c++/12337
+ * init.c (build_new_1): Make sure that the expression returned is
+ not an lvalue.
+
+ PR c++/12344, c++/12236, c++/8656
+ * decl.c (start_function): Do not ignore attributes embedded in a
+ function declarator.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (c++.info): Remove.
+ (c++.dvi): Remove.
+ (c++.generated-manpages): Replace with ...
+ (generated-manpages): ... this.
+
+2003-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (struct cp_binding_level): Move to name-lookup.h
+ (current_binding_level): Likewise.
+ (class_binding_level): Likewise.
+ * cp-tree.h (enum scope_kind): Likewise.
+
+2003-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.c (binding_entry_free): Nullify name and type
+ fields.
+
+2003-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12486
+ * typeck.c (finish_class_member_access_expr): Issue diagnostic
+ on erroneous use of qualified name.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ PR c++/12370
+ * decl.c (duplicate_decls): Copy DECL_SAVED_INSNS too.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * g++spec.c: Convert to ISO C90 prototypes.
+ * parser.c: Likewise.
+
+2003-09-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (pop_binding): Don't mess with nullifying binding->scope
+ here.
+ * name-lookup.c: Re-format.
+ (cxx_binding_free): Nullify binding->scope.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ PR C++/12047
+ * except.c (build_eh_type_type): Call mark_used on the type.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (c_expand_asm_operands): Take location_t, instead of
+ individual file and line.
+
+2003-09-28 Andreas Jaeger <aj@suse.de>
+
+ * decl.c (cxx_builtin_type_decls): Convert to ISO C90 function
+ definition.
+ * init.c (push_base_cleanups): Likewise.
+ * decl2.c (finish_file): Likewise.
+ * mangle.c (init_mangle): Likewise.
+ (dump_substitution_candidates): Likewise.
+ * search.c: Likewise.
+
+2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (get_global_value_if_present): New function.
+ (is_typename_at_global_scope): Likewise.
+ * except.c (do_begin_catch): Use get_global_value_if_present.
+ (do_end_catch): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (build_throw): Likewise.
+ * parser.c (cp_parser_member_declaration): Likewise.
+ * rtti.c (throw_bad_cast): Likewise.
+ (throw_bad_typeid): Likewise.
+ * decl.c (check_tag_decl): Use is_typename_at_global_scope.
+ (grokdeclarator): Likewise.
+ * cp-tree.h (global_namespace): Move to name-lookup.h
+ * call.c (call_builtin_trap): Tidy.
+
+2003-09-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11415
+ * parser.c (cp_parser_nested_name_specifier_opt): Issue correct
+ error message when parser->scope is global_namespace.
+
+2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h, name-lookup.h, decl.c, decl2.c: Remove reference to
+ macros BINDING_SCOPE, BINDING_VALUE and BINDING_TYPE.
+
+2003-09-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (pop_binding_level, suspend_binding_level,
+ find_class_binding_level): Merge into leave_scope. Remove.
+ (leave_scope): New function.
+ (poplevel): Update.
+ (poplevel_class): Likewise.
+ (pop_namespace): Likewise.
+
+2003-09-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5655
+ * parser.c (cp_parser_check_access_in_redeclaration): New function.
+ (cp_parser_member_declaration): Use it.
+ (cp_parser_template_declaration_after_export): Likewise.
+
+2003-09-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (scope_kind): Add new enumerator.
+ (keep_next_level): Change parameter type to bool.
+ (begin_scope): Change prototype.
+ (pushlevel): Remove declaration.
+ * decl.c (push_binding_level): Fold in begin_scope. Remove.
+ (struct cp_binding_level): Remove tag_tranparent field. Make keep
+ of bitsize one.
+ (keep_next_level_flag): Make a bool.
+ (cxx_scope_descriptor): Update scope names table
+ (make_cxx_scope): Fold in begin_scope. Remove..
+ (namespace_scope_ht_size): New function.
+ (begin_scope): Change prototype. Return a scope. Tidy.
+ (kept_level_p): Update.
+ (pushlevel): Remove.
+ (maybe_push_cleanup_level): Simplify.
+ (poplevel): Update for sk_cleanup and keep change.
+ (print_binding_level): Likewise.
+ (initial_push_namespace_scope): Fold in begin_scope. Remove.
+ (push_namespace): Update.
+ (pushtag): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (cxx_init_decl_processing): Likewise.
+ (start_function): Likewise.
+ (begin_function_body): Likewise.
+ (start_method): Likewise.
+ * pt.c (push_inline_template_parms_recursive): Likewise.
+ (begin_template_parm_list): Likewise.
+ (begin_specialization): Likewise.
+ * semantics.c (do_pushlevel): Likewise.
+ (begin_compound_stmt): Likewise.
+ (begin_stmt_expr): Likewise.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, error.c, init.c,
+ method.c, optimize.c, pt.c, semantics.c, tree.c: Revert.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, error.c, init.c,
+ method.c, optimize.c, pt.c, semantics.c, tree.c: Update for
+ DECL_SOURCE_LOCATION rename and change to const.
+
+2003-09-20 Richard Henderson <rth@redhat.com>
+
+ * decl.c, decl2.c, pt.c: Use %J in diagnostics.
+
+2003-09-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/157
+ * parser.c (cp_parser_direct_declarator): Clear
+ parser->num_template_parameter_lists when parsing function
+ parameters.
+ (cp_parser_constructor_declarator_p): Likewise.
+
+2003-09-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/495
+ * pt.c (tsubst_friend_class): Only use innermost template
+ arguments for the injected friend class template.
+
+2003-09-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12332
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl around the tsubst of a template member
+ function.
+
+2003-09-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (cxx_scope_descriptor): Fix thinko.
+ (struct cp_binding_level): Adjust type of binding_depth field.
+
+2003-09-18 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/12320
+ * call.c (type_passed_as): Check for incomplete type.
+ (convert_for_arg_passing): Likewise.
+
+2003-09-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9848
+ * optimize.c (maybe_clone_body): Don't set MARK_USED on parameters
+ here.
+ * semantics.c (expand_body): Set it here on the remaining clones.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * lex.c (init_operators): Remove operator_name_info for FFS_EXPR.
+ * class.c (instantiate_type): Remove FFS_EXPR case.
+
+2003-09-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Fix recent commit.
+
+2003-09-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Add PR number to patch for PR c++/12316.
+
+2003-09-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_type): Simplify. Use pp_type_specifier_seq for
+ "C" types.
+ * cxx-pretty-print.c (pp_cxx_type_specifier_seq): Fix thinko.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_body): Don't save/restore input_location.
+
+2003-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12266
+ * cp-tree.h (tsubst_flags_t): Add tf_conv.
+ * class.c (standard_conversion): Pass tf_conv to
+ instantiate_type.
+ (resolve_address_of_overloaded_function): Do not call mark_used
+ when just checking conversions.
+
+ PR debug/12066
+ * cp-lang.c (LANG_HOOKS_BUILTIN_TYPE_DECLS): Define.
+ * cp-tree.h (cxx_builtin_type_decls): Declare.
+ * decl.c (builtin_type_decls): New variables.
+ (cxx_builtin_type_decls): New function.
+ (record_builtin_type): Add to builtin_type_decls.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ PR c++/12316
+ * semantics.c (expand_or_defer_fn): Inc/dec function_depth.
+
+2003-09-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7939
+ * typeck.c (comptypes): Don't ICE when its first argument is
+ error_mark_node.
+ (compparms): Reverse the arguments of same_type_p.
+
+2003-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12184
+ * typeck.c (convert_arguments): Return error_mark_node for an
+ incomplete parameter. Make error message more informative.
+
+2003-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3907
+ * class.c (maybe_note_name_used_in_class): Refine test for whether
+ or not we are in a class scope.
+
+ * cp-tree.h (language_function): Remove x_expanding_p.
+ (expanding_p): Remove.
+ (doing_semantic_analysis_p): Remove.
+ (scope_kind): Add sk_function_parms, sk_class,
+ sk_namespace.
+ (innermost_scope_kind): New method.
+ * call.c (cxx_type_promotes_to): Use type_decays_to.
+ * cp-lang.c (LANG_HOOKS_PUSHLEVEL): Redefine.
+ (LANG_HOOKS_POPLEVEL): Likewise.
+ * decl.c (cp_binding_level): Remove parm_flag, template_parms_p,
+ template_spec_p, namespace_p, is_for_scope, is_try_scope, and
+ is_catch_scope. Add kind and explicit_spec_p.
+ (cxx_scope_descriptor): Use a lookup table.
+ (find_class_binding_level): Use "kind" field in binding_level, not
+ the various flags.
+ (pop_binding_level): Likewise.
+ (innermost_nonclass_level): Likewise.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (template_parm_scope_p): Likewise.
+ (innermost_scope_kind): New method.
+ (current_tmpl_spec_kind): Use "kind" field in binding_level, not
+ the various flags.
+ (pushlevel): Remove check for doing_semantic_analysis_p.
+ (begin_scope): Simplify.
+ (add_decl_to_level): Use "kind" field in binding_level, not
+ the various flags.
+ (push_local_binding): Likewise.
+ (pop_label): Remove check for doing_semantic_analysis_p.
+ (poplevel): Use "kind" field in binding_level, not
+ the various flags.
+ (set_block): Remove check for doing_semantic_analysis_p.
+ (pushlevel_class): Use "kind" field in binding_level, not
+ the various flags.
+ (poplevel_class): Likewise.
+ (initial_push_namespace_scope): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (pop_everything): Likewise.
+ (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (check_previous_goto_1): Likewise.
+ (define_label): Likewise.
+ (finish_case_label): Likewise.
+ (lookup_tag): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (record_builtin_type): Likewise.
+ (cp_make_fname_decl): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (cp_finish_decl): Remove check for doing_semantic_analysis_p.
+ (start_function): Use begin_scope, not pushlevel.
+ (finish_function): Use "kind" field in binding_level, not
+ the various flags.
+ (start_method): Use begin_scope, not pushlevel.
+ (make_label_decl): Do not check expanding_p.
+ (save_function-data): Do not set expanding_p.
+ (cxx_push_function_context): Do not clear expanding_p.
+ * semantics.c (cxx_expand_function_start): Do not set expanding_p.
+
+2003-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Make DECL_MODE match TYPE_MODE for
+ an bit-field whose width exceeds that of its type.
+
+2003-09-14 Geoffrey Keating <geoffk@apple.com>
+
+ * rtti.c (get_tinfo_decl): Set TREE_PUBLIC for typeinfo decls.
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * parser.c: Likewise.
+
+2003-09-13 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_file): Check cgraph_assemble_pending_functions
+ during relaxation loop.
+
+2003-09-11 David Edelsohn <edelsohn@gnu.org>
+
+ * decl2.c (var_finalized_p): Swap arms of conditional.
+
+2003-09-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11788
+ * typeck.c (build_address): If it is a function, mark it used.
+ (build_unary_op): Do not lose object's side-effects when taking
+ address of static member function.
+ * class.c (resolve_address_of_overloaded_function): Use
+ tsubst_flags_t parameter. Only expect overload sets. Adjust.
+ (instantiate_type): Adjust flags passing. Do not lose object's
+ side-effects when taking address of static member function.
+
+2003-09-11 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_or_defer_fn): Update for new
+ cgraph_finalize_function argument.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (cxx_callgraph_analyze_expr): Mark argument unused.
+
+2003-09-10 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (var_finalized_p): New.
+ (maybe_emit_vtables, write_out_vars, finish_file): Use it.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (cxx_callgraph_analyze_expr): New, from corpse of
+ mark_member_pointers.
+ (lower_function): Remove.
+ * cp-tree.h: Update to match.
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): New.
+ (LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Remove.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_or_defer_fn): Update call to
+ cgraph_finalize_function.
+
+ * semantics.c (expand_or_defer_fn): Use cgraph_finalize_function
+ always.
+
+ * decl2.c (finish_file): Avoid out-of-bounds array reference
+ during memmove.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers): Rename from
+ mark_member_pointers_and_eh_handlers and don't check eh handlers.
+
+2003-09-09 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR bootstrap/12168
+ * method.c (use_thunk): Clear DECL_RTL of copied nodes.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-lang.c (LANG_HOOKS_REGISTER_BUILTIN_TYPE): Define to
+ c_register_builtin_type.
+
+ PR c++/11786
+ * decl2.c (add_function): Do not complain about seeing the same
+ non-function twice.
+ * semantics.c (perform_koenig_lookup): Improve documentation.
+
+ PR c++/5296
+ * pt.c (try_one_overload): Add addr_p parameter.
+ (resolve_overloaded_unification): Pass it.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * optimize.c (maybe_clone_body): Inc/dec function_depth.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Clear current_function_decl.
+ * decl2.c (mark_used): Don't push/pop gc context.
+ * optimize.c (optimize_function): Likewise.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+ * pt.c (instantiate_decl): Inc/dec function_depth instead.
+ * semantics.c (expand_body): Update for tree_rest_of_compilation
+ nested argument.
+
+2003-09-07 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ PR c++/11762
+ * error.c (dump_decl): Handle namespace-alias-definition.
+ * decl.c (warn_extern_redeclared_static): There is no point in
+ checking changes in storage class specifier for a namespace
+ declaration.
+ (duplicate_decls): Tidy diagnostic message.
+ * cxx-pretty-print.c (pp_cxx_left_brace): New macro.
+ (pp_cxx_right_brace): Likewise.
+ (pp_cxx_original_namespace_definition): New function.
+ (pp_cxx_namespace_alias_definition): Likewise.
+ (pp_cxx_declaration): Use them. Handle NAMESPACE_DECLs.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_emit_vtables, write_out_vars, finish_file):
+ Avoid re-emitting variables in unit-at-a-time mode.
+
+2003-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11867
+ * call.c (standard_conversion): Improve comments.
+ (perform_direct_initialization): Make sure we return an expression
+ of the correct type.
+ * typeck.c (build_static_cast): Check for ambiguity and
+ accessibility when performing conversions.
+
+2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (add_binding): Remove declaration.
+ * name-lookup.h (supplement_binding): Declare.
+ * decl.c (add_binding): Move to name-lookup.c.
+ (push_local_binding): Adjust.
+ (push_class_binding): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ * name-lookup.c (supplement_binding): Rename from add_binding.
+ Return a bool. Improve documentation.
+ (set_namespace_binding): Adjust.
+ * Make-lang.in (cp/name-lookup.o): Depend on toplev.h
+
+2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11794
+ * class.c (pushclass): Push dependent using decls for nested
+ classes of templates too.
+
+2003-09-06 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/11409
+ * class.c (resolve_address_of_overloaded_function): When building
+ list of matching non-template function decls, ignore anticipated
+ declarations of undeclared or shadowed GCC builtins.
+
+2003-09-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c++/11595
+ * decl.c (define_label): Remove unreachable timevar pop.
+ Always return the decl, even if the definition is invalid.
+
+2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12167
+ * parser.c (cp_parser_late_parsing_default_args): Push & pop the
+ unparsed functions queue.
+
+2003-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12163
+ * call.c (perform_direct_initialization): Correct logic for
+ direct-initialization of a class type.
+
+ PR c++/12146
+ * pt.c (lookup_template_function): Robustify.
+
+2003-09-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11922
+ * pt.c (tsubst_qualified_id): Make sure we get a non-type.
+ (tsubst_expr, tsubst_copy_and_build): Pass false, not zero, as
+ is_type_p to lookup_qualified_name.
+
+ * semantics.c (finish_call_expr): Refactor some code.
+
+ PR c++/12037
+ * cp-tree.h (COMPOUND_EXPR_OVERLOADED): New.
+ (build_min_non_dep): Declare.
+ * tree.c (build_min): Propagate TREE_SIDE_EFFECTS.
+ (build_min_non_dep): New.
+ * cvt.c (convert_to_void): Don't explicitly copy
+ TREE_SIDE_EFFECTS, TREE_NO_UNUSED_WARNING.
+ * call.c (build_new_method_call): Use build_min_non_dep.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_offset_ref_call_from_tree): Likewise.
+ * typeck.c (finish_class_member_access_expr,
+ build_x_indirect_ref, build_x_binary_op, build_x_unary_op,
+ build_x_conditional_expr, build_x_compound_expr): Likewise.
+ (build_static_cast, build_reinterpret_cast,
+ build_const_cast): Propagate TREE_SIDE_EFFECTS inside a template.
+ * typeck2.c (build_x_arrow): Use build_min_non_dep.
+ (build_functional_cast): Propagate TREE_SIDE_EFFECTS inside a
+ template.
+ * rtti.c (build_dynamic_cast_1): Set DECL_IS_PURE.
+ (build_dynamic_cast): Set TREE_SIDE_EFFECTS.
+ * pt.c (build_non_dependent_expr): Check COMPOUND_EXPR_OVERLOADED.
+
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers_and_eh_handlers): Update for
+ change in cgraph_mark_needed_node arguments.
+
+2003-09-02 Geoffrey Keating <geoffk@apple.com>
+
+ PR 12161
+ * decl2.c (mark_used): Use ggc_push_context/ggc_pop_context.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+
+2003-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_sizeof, finish_alignof): Remove.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here.
+ (cxx_sizeof_or_alignof_type): Make complain parameter a bool.
+ * parser.c (cp_parser_unary_expression): Commonize alignof and
+ sizeof handling.
+ * pt.c (tsubst_copy_and_build): Adjust alignof and sizeof
+ substitution.
+ * semantics.c (finish_sizeof, finish_alignof): Remove.
+ * typeck.c (cxx_sizeof_or_alignof_type): Complain parameter
+ becomes bool. Set TREE_READONLY.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here. Clear TREE_SIDE_EFFECTS.
+
+2003-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ Remove cast-as-lvalue extension.
+ * call.c (build_conditional_expr): Correct formatting.
+ (convert_like_real): Use lvalue_p, not non_cast_lvalue_p.
+ (initialize_real): Use real_lvalue_p, not real_non_cast_lvalue_p.
+ * cp-tree.h (non_cast_lvalue_p): Remove.
+ (real_non_cast_lvalue_p): Remove.
+ (non_cast_lvalue_or_else): Remove.
+ * tree.c (lvalue_p_1): Remove allow_cast_as_lvalue parameter.
+ (real_lvalue_p): Adjust call to lvalue_p_1.
+ (non_cast_lvalue_p): Remove.
+ (non_cast_lvalue_or_else): Remove.
+ (lvalue_p): Adjust call to lvalue_p_1.
+ (lvalue_or_else): Simplify.
+ * typeck.c (build_unary_op): Use lvalue_or_else, not
+ non_cast_lvalue_or_else.
+ (build_static_cast): Use real_lvalue_p, not real_non_cast_lvalue_p.
+
+2003-09-03 DJ Delorie <dj@redhat.com>
+
+ * decl.c (finish_function): Pass fndecl to aggregate_value_p.
+
+2003-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12053
+ * class.c (include_empty_classes): Correct logic for ABI version 1.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * optimize.c (optimize_function): Push/pop ggc context around
+ the call to optimize_inline_calls.
+
+2003-09-02 Scott Brumbaugh <scottb.lists@verizon.net>
+
+ PR c++/11553
+ * parser.c (cp_parser_decl_specifier_seq): Add check for a
+ duplicate friend decl-specifier.
+
+2003-09-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11847
+ * pt.c (convert_nontype_argument): Correct representation of
+ REFERENCE_TYPE expressions.
+
+ PR c++/11808
+ * cp-tree.h (KOENIG_LOOKUP_P): New macro.
+ (finish_call_expr): Change prototype.
+ * parser.c (cp_parser_postfix_expression): Adjust call to
+ finish_call_expr.
+ * pt.c (tsubst_copy_and_build): Use KOENIG_LOOKUP_P.
+ * semantics.c (finish_call_expr): Add koenig_p parameter.
+
+2003-09-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12114
+ * cp-tree.h (initialize_reference): Change prototype.
+ * call.c (initialize_reference): Add cleanup parameter.
+ * decl.c (grok_reference_init): Likewise.
+ (check_initializer): Likewise.
+ (cp_finish_decl): Insert a CLEANUP_STMT if necessary.
+ (duplicate_decls): When replacing an anticipated builtin, do not
+ honor TREE_NOTHROW.
+ * typeck.c (convert_for_initialization): Correct call to
+ initialize_reference.
+
+ PR c++/11972
+ * pt.c (dependent_type_p_r): Pass only the innermost template
+ arguments to any_dependent_template_arguments_p.
+
+2003-09-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * error.c (dump_expr): Kill BIT_ANDTC_EXPR.
+ * lex.c (init_operators): Kill BIT_ANDTC_EXPR.
+ * pt.c (tsubst_copy): Kill BIT_ANDTC_EXPR.
+ * typeck.c (build_binary_op): Kill BIT_ANDTC_EXPR.
+ (tsubst_copy_and_build): Kill BIT_ANDTC_EXPR.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12093
+ * pt.c (build_non_dependent_expr): Do not build a
+ NON_DEPENDENT_EXPR for a STRING_CST.
+
+ PR c++/11928
+ * search.c (add_conversions): Avoid adding two conversion
+ operators for the same type.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6196
+ * pt.c (tsubst_copy_and_build): Correct handling of
+ address-of-label extension.
+ * semantics.c (finish_goto_stmt): The address of a label must go
+ through the lvalue-to-rvalue conversion.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_START): New.
+ (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * cp-tree.h (cxx_expand_function_start): Declare.
+ * decl.c (start_function): Use allocate_struct_function.
+ Move stmts_are_full_exprs_p assertion from expand_body.
+ Do not free_after_parsing or free_after_compilation.
+ (cxx_push_function_context): Move code to set struct function
+ data from genrtl_start_function.
+ * optimize.c (optimize_function): Don't inc/dec function_depth.
+ * semantics.c (expand_body): Use tree_rest_of_compilation.
+ (cxx_expand_function_start): Rename from genrtl_start_function,
+ omit bits done by tree_rest_of_compilation.
+ (genrtl_finish_function): Remove.
+ (clear_decl_rtl): Move to ../tree-optimize.c.
+
+2003-08-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11811
+ * cxx-pretty-print.c (pp_cxx_canonical_template_parameter): New
+ function.
+ * cxx-pretty-print.h: Declare.
+ * error.c (dump_template_parameter): Use it.
+ (dump_type): Likewise.
+
+2003-08-28 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (decl_constant_value): Deal with COND_EXPR specially.
+ * call.c (build_conditional_expr): Revert previous patch.
+
+ PR optimization/5079
+ * call.c (build_conditional_expr): Use decl_constant_value to
+ simplify the arguments.
+
+2003-08-26 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * parser.c (struct cp_token): Use enum bitfields.
+ (CP_TOKEN_BLOCK_NUM_TOKENS): Make sure cp_token_block fits in a
+ 512B allocation unit.
+ (cp_parser_token_tree_map_node): Use enum bitfields.
+
+2003-08-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11871
+ * decl.c (push_class_level_binding): Correct old_decl value from
+ my 2003-07-29 reorganization.
+
+ * call.c (build_call): Don't set TREE_SIDE_EFFECTS here.
+ (build_new_method_call): Add goto finish.
+ * semantics.c (simplify_aggr_init_exprs_r): Don't set
+ TREE_SIDE_EFFECTS on a call.
+
+2003-08-25 Richard Henderson <rth@redhat.com>
+
+ * cxx-pretty-print.c (pp_cxx_class_name): Remove unused function.
+
+2003-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (pp_cxx_flag_default_argument): New flag.
+ (cxx_pretty_printer): Adjust base type.
+ (pp_cxx_function_specifier): Declare.
+ * cxx-pretty-print.c (pp_cxx_whitespace): New macro.
+ (pp_cxx_left_paren): Likewise.
+ (pp_cxx_right_paren): Likewise.
+ (pp_cxx_dot): Likewise.
+ (pp_cxx_arrow): Likewise.
+ (pp_cxx_semicolon): Likewise.
+ (pp_cxx_identifier): Likewise.
+ (pp_cxx_cv_qualifier_seq): Likewise.
+ (pp_cxx_storage_class_specifier): Likewise.
+ (pp_cxx_expression_list): Likewise.
+ (pp_cxx_space_for_pointer_operator): Likewise.
+ (pp_cxx_init_declarator): Likewise.
+ (pp_cxx_call_argument_list): Likewise.
+ (pp_cxx_nonconsecutive_character): Tidy.
+ (pp_cxx_conversion_function_id): New function.
+ (pp_cxx_template_id): Likewise.
+ (pp_cxx_template_keyword_if_needed): Likewise.
+ (pp_cxx_nested_name_specifier): Likewise.
+ (pp_cxx_unqualified_id): Tidy
+ (pp_cxx_qualified_id): Handle more nodes.
+ (pp_cxx_primary_expression): Tidy.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_new_expression): Tidy.
+ (pp_cxx_delete_expression): Likewise.
+ (pp_cxx_cast_expression): New function.
+ (pp_cxx_pm_expression): Tidy.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_operator): New function.
+ (pp_cxx_assignment_expression): Tidy.
+ (pp_cxx_expression): New function.
+ (pp_cxx_function_specifier): Likewise.
+ (pp_cxx_decl_specifier_seq): Likewise.
+ (pp_cxx_simple_type_specifier): Tidy.
+ (pp_cxx_type_specifier_seq): Likewise.
+ (pp_cxx_ptr_operator): New function.
+ (pp_cxx_implicit_parameter_type): Likewise.
+ (pp_cxx_parameter_declaration): Tidy.
+ (pp_cxx_parameter_declaration_clause): New function.
+ (pp_cxx_exception_specification): Likewise.
+ (pp_cxx_direct_declarator): Tidy.
+ (pp_cxx_declarator): Likewise.
+ (pp_cxx_ctor_initializer): New function.
+ (pp_cxx_function_definition): Likewise.
+ (pp_cxx_abstract_declarator): Tidy.
+ (pp_cxx_direct_abstract_declarator): Likewise.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_exception_declaration): New function.
+ (pp_cxx_statement): Likewise.
+ (pp_cxx_simple_declaration): Likewise.
+ (pp_cxx_template_parameter_list): Likewise.
+ (pp_cxx_template_parameter): Likewise.
+ (pp_cxx_template_declaration): Likewise.
+ (pp_cxx_explicit_specialization): Likewise.
+ (pp_cxx_explicit_instantiation): Likewise.
+ (pp_cxx_declaration): Tidy.
+ (pp_cxx_pretty_printer_init): Initialize more fields.
+
+2003-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8795
+ * cp-tree.h (build_cplus_method_type): Remove.
+ * call.c (standard_conversion): Use build_method_type_directly
+ instead of build_cplus_method_type.
+ * class.c (build_clone): Likewise.
+ (adjust_clone_args): Likewise.
+ * decl.c (build_ptrmem_type): Likewise.
+ (grokdeclarator): Likewise.
+ (check_function_type): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (maybe_retrofit_in_chrg): Likewise.
+ * pt.c (copy_default_args_to_explicit_spec): Likewise.
+ (tsubst_function_type): Likewise.
+ (tsubst): Likewise.
+ * tree.c (build_cplus_method_type): Remove.
+ * typeck.c (merge_types): Use build_method_type_directly.
+
+2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3765
+ * search.c (dfs_access_in_type): Fix typo in comment.
+ (dfs_accessible_queue_p): Likewise.
+ (dfs_accessible_p): Only terminate when a friend is found.
+ (accessible_p): Return immediately if access_in_type allows
+ access.
+
+2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/641, c++/11876
+ * friend.c (add_friend): Add complain parameter.
+ (make_friend_class): Likewise.
+ (do_friend): Adjust add_friend call.
+ * decl.c (grokdeclarator): Adjust make_friend_class call.
+ * parser.c (cp_parser_member_declaration): Likewise.
+ (cp_parser_template_declaration_after_export): Likewise.
+ * pt.c (instantiate_class_template): Adjust make_friend_class
+ and add_friend call.
+ * cp-tree.h (make_friend_class): Adjust declaration.
+ (add_friend): Likewise.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/11283
+ * call.c (build_conditional_expr): Ignore cv-qual differences for
+ non-class types.
+
+2003-08-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11551
+ * parser.c (cp_parser_id_expression): Add declarator_p parameter.
+ (cp_parser_primary_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_unqualified_id): Complain about the use of
+ typedef-names in a destructor declarator.
+ (cp_parser_postfix_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_type_parameter): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_declarator_id): Likewise.
+
+ PR c++/11919
+ * call.c (standard_conversion): Use same_type_p, not pointer
+ equality, to compare types.
+
+ PR c++/10762
+ * parser.c (cp_parser_using_declaration): Check for invalid uses
+ of template-ids here...
+ * decl2.c (do_class_using_decl): ... rather than here.
+
+2003-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11834
+ * pt.c (more_specialized): Bump processing_template_decl.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/11614
+ * decl.c (grokdeclarator): Recognize a flexible array based on the
+ type, not the form of the declarator.
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_expr): Split out from
+ simplify_aggr_init_exprs_r. Convert slot address to match
+ the return type.
+ * cp-tree.h: Declare it.
+ * tree.c (cp_copy_res_decl_for_inlining): Don't clobber the
+ DECL_NAME of a user variable.
+
+2003-08-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11945
+ * pt.c (build_non_dependent_expr): Look inside COND_EXPR and
+ COMPOUND_EXPR.
+ * semantics.c (finish_expr_stmt): Always convert to void.
+ * typeck.c (build_x_compound_exp): Always convert to void.
+
+2003-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11684
+ * cp-tree.h (grok_op_properties): Change prototype.
+ * decl.c (grok_op_properties): Add complain parameter.
+ (grokfndecl): Pass it.
+ * pt.c (tsubst_decl): Adjust accordingly.
+
+ PR c++/10926
+ * decl.c (start_method): Return immediately if push_template_decl
+ does not like the declaration.
+ * pt.c (push_template_decl_real): Disallow member template
+ destructors.
+
+ PR c++/11036
+ * cp-tree.h (add_binding): Add prototype.
+ * class.c (add_method): Set TYPE_HAS_DESTRUCTOR if appropriate.
+ (maybe_warn_about_overly_private_class): Use
+ CLASSTYPE_DESTRUCTORS.
+ (pushclass): Adjust call to set_identifier_type_value.
+ * decl.c (add_binding): Give it external linkage.
+ (push_local_binding): Adjust call to add_binding.
+ (push_class_binding): Likewise.
+ (set_identifier_type_value_with_scope): Change prototype. Use
+ add_binding for global bindings.
+ (set_identifier_type_value): Adjust accordingly.
+ (pushtag): Likewise.
+ (pushdecl): Use set_identifier_type_value, not
+ set_identifier_type_value_with_scope.
+ (pushdecl_namespace_level): Adjust calls to
+ SET_IDENTIFIER_TYPE_VALUE to pass a DECL.
+ (pushdecl_class_level): Likewise.
+ (lookup_tag): Use select_decl.
+ (select_decl): Improve comment.
+ (record_builtin_type): Do not call pushdecl.
+ (cxx_init_decl_processing): Do not call xref_tag for bad_alloc.
+ (cp_finish_decl): Adjust call to set_identifier_type_value.
+ (check_elaborated_type_specifier): Improve checks for invalid uses
+ of typedefs.
+ (xref_tag): Adjust call to check_elaborated_type_specifier.
+ * decl2.c (grokclassfn): Do not set TYPE_HAS_DESTRUCTOR.
+ * name-lookup.c (set_namespace_binding): Use add_binding.
+ * parser.c (cp_parser_simple_type_specifier): Return a TYPE_DECL,
+ rather than an IDENTIFIER_NODE, to represent built-in types, if
+ requested by the caller.
+ (cp_parser_postfix_expression): Adjust call.
+ (cp_parser_type_specifier): Likewise.
+ (cp_parser_elaborated_type_specifier): Adjust call to
+ check_elaborated_type_specifier.
+ * typeck2.c (build_functional_cast): Do not perform name lookups.
+
+ PR c++/10717
+ * decl.c (expand_static_init): Remove unnecessary code.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/10538, PR c/5582
+ * cp/cp-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+
+2003-08-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11174
+ * init.c (build_offset_ref): Perform access checking for
+ pointer to member correctly.
+
+2003-08-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-lang.c (LANG_HOOKS_INITIALIZE_DIAGNOSTICS): Fix spelling.
+
+2003-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11957
+ * cp-tree.h (finish_stmt_expr): Add bool parameter.
+ * init.c (finish_init_stmts): Pass true to finish_stmt_expr. Don't
+ adjust the stmt_expr here.
+ (build_vec_init): Use finish_stmt_expr_expr, convert result to
+ array type.
+ * parser.c (cp_parser_primar_expression): Adjust finish_stmt_expr
+ call.
+ * pt.c (tsubst_copy): Likewise.
+ * semantics.c (finish_stmt_expr): Add parameter.
+
+ * pt.c (instantiate_class_template): Push to class's scope before
+ tsubsting base.
+
+2003-08-17 Jan Hubicka <jh@suse.cz>
+
+ PR C++/11702
+ * semantics.c (finish_id_expression): Mark all functions as used.
+
+2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11512
+ * cvt.c (convert_to_void): Indicate which side of conditional has
+ no effects, and rhs of comma operator. Test for no sideeffect
+ expressions here and always build a convert expr.
+ * init.c (expand_default_init): Convert the init to void.
+ * typeck.c (build_x_compound_expr): Do not check for side effects
+ here.
+ (build_compound_expr): Do not convert lhs when building a
+ template.
+
+2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (NON_DEPENDENT_EXPR): Add operand.
+ * decl2.c (build_offset_ref_call_from_tree): Use
+ build_non_dependent_expr.
+ * error.c (dump_expr) <NON_DEPENDENT_EXPR case>: Dump the operand.
+ * pt.c (build_non_dependent_expr): Set operand.
+
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Rename to...
+ (mark_member_pointers_and_eh_tinfos): ... this one; deal with eh tinfos
+ (lower_function): Update call.
+ * except.c (eh_type_info): Break out from ...
+ (build_eh_type): ... here; tinfo is already used.
+ (finish_eh_spec_block): Mark tinfos as used.
+ * semantics.c (finish_handler_params): Mark tinfo as used.
+ * cp-tree.h (eh_type_info): Declare.
+
+2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_class_template): Set location before
+ substuting bases.
+
+ * decl.c (make_typename_type): Use my_friendly_assert.
+ * pt.c (tsubst_aggr_type): Rearrange context substitution.
+
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * method.c (use_thunk): Expand body directly.
+
+2003-08-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11703
+ * call.c (type_passed_as): Use TYPE_SIZE, not TYPE_PRECISION to
+ determine whether or not to promote types.
+ (convert_for_arg_passing): Likewise.
+ * decl2.c (cp_build_parm_decl): Do not set DECL_ARG_TYPE in
+ templates.
+ * pt.c (tsubst_decl): Do not expect it to be set.
+
+ PR c++/9512
+ PR c++/10923
+ * cp-tree.h (check_elaborated_type_specifier): Declare.
+ (handle_class_head): Remove.
+ (note_got_semicolon): Likewise.
+ (note_list_got_semicolon): Likewise.
+ (finish_class_definition): Likewise.
+ * decl.c (check_elaborated_type_specifier): Make it public.
+ Robustify.
+ (handle_class_head): Remove.
+ * parser.c (cp_parser_elaborated_type_specifier): Use
+ check_elaborated_type_specifier.
+ (cp_parser_class_specifier): Do not call finish_class_definition.
+ (cp_parser_class_head): Or handle_class_head. Check for
+ over-qualified names.
+ * semantics.c (finish_class_definition): Remove.
+
+ * parser.c (cp_parser_check_for_definition_in_return_type): New
+ function.
+ (cp_parser_simple_declaration): Adjust call to
+ cp_parser_init_declarator.
+ (cp_parser_decl_specifier_seq): Change type of
+ declares_class_or_enum parameter.
+ (cp_parser_explicit_instantiation): Adjust accordingly.
+ (cp_parser_type_specifier): Change type of
+ declares_class_or_enum parameter.
+ (cp_parser_init_declarator): Add declares_class_or_enum
+ parameter.
+ (cp_parser_parameter_declaration): Adjust call to
+ cp_parser_decl_specifier_seq.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_single_declaration): Likewise.
+
+ * cp-tree.h (lang_type_class): Remove has_call_overloaded,
+ has_array_ref_overloaded, has_arrow_overloaded, and got_semicolon.
+ (TYPE_OVERLOADS_CALL_EXPR): Remove.
+ (TYPE_OVERLOADS_ARRAY_REF): Likewise.
+ (TYPE_OVERLOADS_ARROW): Likewise.
+ (CLASSTYPE_GOT_SEMICOLON): Likewise.
+ * class.c (check_bases): Do not set them.
+ (finish_struct_1): Likewise.
+ * decl.c (cp_finish_decl): Do not set CLASSTYPE_GOT_SEMICOLON.
+ (build_ptrmemfunc_type): Likewise.
+ (grok_op_properties): Do not set TYPE_OVERLOADS_*.
+ (start_function): Do not check CLASSTYPE_GOT_SEMICOLON.
+ * decl2.c (grokfield): Do not set CLASSTYPE_GOT_SEMICOLON.
+ * lex.c (note_got_semicolon): Remove.
+ (note_list_got_semicolon): Likewise.
+ * parser.c (cp_parser_simple_declaration): Do not call
+ note_list_got_semicolon.
+ * pt.c (list_eq): Remove.
+ (lookup_template_class): Do not set CLASSTYPE_GOT_SEMICOLON.
+ (instantiate_class_template): Do not set TYPE_OVERLOADS*.
+ (instantiate_class_template): Do not set CLASSTYPE_GOT_SEMICOLON.
+ * ptree.c (cxx_print_type): Do not print them.
+ * semantics.c (finish_member_class_template): Do not call
+ note_list_got_semicolon.
+
+2003-08-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * call.c (standard_conversion): Opaque pointers interconvert.
+
+ * testsuite/g++.dg/other/opaque-3.C: New.
+
+2003-08-11 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (merge_types): Handle cv-qualified pointer-to-member
+ types correctly.
+
+2003-08-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11789
+ * cp-tree.h (get_vbase): Remove.
+ (get_vbase_types): Remove.
+ * init.c (expand_member_init): Correct logic for looking up base
+ classes.
+
+2003-08-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Tidy.
+ * cxx-pretty-print.c (pp_cxx_nonconsecutive_character): New.
+ (pp_cxx_begin_template_argument_list): Likewise.
+ (pp_cxx_end_template_argument_list): Likewise.
+ (is_destructor_name): Likewise.
+ (pp_cxx_unqualified_id): Likewise.
+ (pp_cxx_qualified_id): Likewise.
+ (pp_cxx_id_expression): Likewise.
+ (pp_cxx_new_expression): Likewise.
+ (pp_cxx_delete_expression): Likewise.
+ (pp_cxx_pm_expression): Likewise.
+ (pp_cxx_type_specifier): Rework.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_unary_expression): Likewise.
+ (pp_cxx_multiplicative_expression): Likewise.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_expression): Likewise.
+ (pp_cxx_pretty_printer_init): Tidy.
+
+2003-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL
+ NODE is always a TREE_VEC of nonzero size.
+ (NUM_TMPL_ARGS): NODE is always a TREE_VEC.
+ * decl2.c (arg_assoc): Template args will be a vec.
+ * error.c (dump_decl) <TEMPLATE_ID_EXPR case>: Call
+ dump_template_argument_list.
+ (dump_template_parms): Args will be a vec.
+ * parser.c (cp_parser_template_argument_list): Produce a
+ vector, not a list.
+ * pt.c (coerce_template_parms): Args are always vectors.
+ (mangle_class_name_for_template): Likewise.
+ (lookup_template_function): Likewise.
+ (lookup_template_class): Likewise.
+ (tsubst_template_args): Likewise.
+ (tsubst_baselink): Use tsubst_template_args.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_copy) <TEMPLATE_ID_EXPR case>: Likewise.
+ (tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise.
+ (any_dependent_template_args_p): Args are always vectors.
+ * tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case.
+
+ PR c++/11670
+ * call.c (convert_like_real): Add rvalue binding error message.
+ * error.c (dump_expr) <NOP_EXPR case>: Detect when the no expr is
+ really a cast.
+
+ PR c++/10530
+ * pt.c (dependent_type_p_r): A dependent template-id is a class
+ type with dependent template arguments, or a bound template
+ template parameter.
+ (type_dependent_expression_p): A template function decl cannot
+ have a dependent context.
+
+2003-08-07 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5767
+ * parser.c (cp_parser_class_name): Return immediately when scope
+ is error_mark_node.
+
+2003-08-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp/Make-lang.in (cp/call.o): Add dependency for target.h.
+
+ * cp/call.c (standard_conversion): Support opaque types.
+ Include target.h.
+ (strip_top_quals): Use cp_build_qualified_type instead of
+ TYPE_MAIN_VARIANT.
+
+ * cp/typeck.c (convert_for_assignment): Support opaque types.
+
+ * testsuite/g++.dg/other/opaque-1.C: New.
+
+ * testsuite/g++.dg/other/opaque-2.C: New.
+
+2003-08-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (grokparms): Use cp_build_qualified_type instead
+ TYPE_MAIN_VARIANT.
+
+2003-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h: New file.
+ * cxx-pretty-print.c: Likewise.
+ * error.c (scratch_pretty_printer): Change type.
+ (init_error): Tidy.
+ (dump_aggr_type): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_expr): Likewise.
+ (dump_char): Remove.
+ * cp-lang.c (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): Define.
+ (cxx_initialize_diagnostics): New function.
+ * Make-lang.in (CXX_OBJS): Add cp/cxx-pretty-print.o
+ (CXX_PRETTY_PRINT_H): New variable.
+ (cp/cxx-pretty-print.o): New rule.
+ (cp/cp-lang.o): Update dependence.
+ (cp/error.o): Likewise.
+
+2003-08-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (struct lang_decl): Don't include c_lang_decl.
+ (DECL_DECLARED_INLINE_P): Remove.
+ * decl2.c (import_export_decl): Only look at DECL_DECLARED_INLINE_P
+ if decl is a FUNCTION_DECL. This never made sense, but now it is
+ required to avoid a tree check failure.
+ * decl.c (grokfndecl): Don't touch DID_INLINE_FUNC.
+ * optimize.c (maybe_clone_body): Likewise.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (cxx_insert_default_attributes): Delete.
+ * cp-tree.h (cxx_insert_default_attributes): Don't prototype.
+ * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't define.
+
+2003-08-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11704
+ * pt.c (type_dependent_expression_p): Cope with COMPONENT_REF with
+ unknown type.
+
+ PR c++/11766
+ * typeck.c (comp_ptr_ttypes_real): Don't loop on pointers to
+ member functions.
+
+2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9447
+ * cp-tree.def (USING_DECL): Document its type.
+ * class.c (pushclass): If we're entering a template, push any
+ dependent using decls it has.
+ * decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
+ a dependent scope.
+ * pt.c (tsubst_decl) <USING_DECL case>: Set type.
+ (tsubst): Remove USING_DECL checks.
+ (type_dependent_expression_p): Remove USING_DECL case.
+ * semantics.c (finish_member_declaration): A USING_DECL's type
+ indicates whether it is dependent.
+
+2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (pushclass): Remove unneeded parameter.
+ * class.c (pushclass): Remove unneeded MODIFY parm. Adjust.
+ (push_nested_class): Adjust pushclass call.
+ * pt.c (instantiate_class_template): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+
+2003-08-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * typeck2.c (add_exception_specifier): Use 'bool' where appropriate.
+
+2003-08-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11697
+ * decl.c (decls_match): Don't ignore the types of template
+ classes.
+
+ PR c++/11744
+ * pt.c (tsubst_copy_and_build): Refine Koenig lookup logic.
+
+2003-08-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8442, c++/8806
+ * decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
+ preferred.
+ (check_elaborated_type_specifier): Add allow_template_p
+ parameter. Check tag mismatch and class template.
+ (xref_tag): Add template_header_p parameter. Add assertion
+ that name is an IDENTIFIER_NODE. Remove implicit typename
+ warning. Simplify lookup process if globalize is true.
+ (cxx_init_decl_processing): Adjust call to xref_tag.
+ (xref_tag_from_type): Likewise.
+ * decl2.c (handle_class_head): Likewise.
+ * parser.c (cp_parser_elaborated_type_specifier,
+ cp_parser_class_head): Likewise.
+ * rtti.c (init_rtti_processing, build_dynamic_cast1,
+ tinfo_base_init, emit_support_tinfos): Likewise.
+ * class.c (is_base_of_enclosing_class): Remove.
+ * pt.c (convert_template_argument): Don't accept RECORD_TYPE as
+ template template argument.
+ * cp-tree.h (xref_tag): Adjust declaration.
+ (is_base_of_enclosing_class): Remove.
+ * NEWS: Document template template argument change.
+
+2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_parser_init_declarator,
+ cp_paser_member_declaration): Reformat.
+ * pt.c (lookup_template_class, type_unification_real, unify,
+ type_dependent_expression_p): Reformat.
+
+ PR c++/11295
+ * cp-tree.h (tubst_flags_t): Add tf_stmt_expr_cmpd,
+ tf_stmt_expr_body.
+ (finish_stmt_expr_expr): Declare.
+ * parser.c (cp_parser_primary_expression): Tell
+ cp_parser_compount_statement that it is a statement expression.
+ (cp_parser_statement, cp_parser_labeled_statement,
+ cp_parser_compound_statement, cp_parser_statement_seq_opt): Add
+ in_statement_expr_p parameter.
+ (cp_parser_expression_statement): Likewise. Call
+ finish_stmt_expr_expr for final expression of a statement
+ expression.
+ (cp_parser_for_init_statement,
+ cp_parser_implicitly_scoped_statement,
+ cp_parser_already_scoped_statement, cp_parser_function_definition,
+ cp_parser_try_block, cp_parser_handled): Adjust.
+ * pt.c (tsubst_copy) <STMT_EXPR case>: Pass tf_stmt_expr.
+ (tsubst_expr): Process tf_stmt_expr and tf_stmt_exprs flags.
+ (tsubst_expr) <EXPR_STMT case>: Check tf_stmt_exprs flag.
+ * semantics.c (finish_expr_stmt): Do not deal with statement
+ expressions.
+ (begin_stmt_expr): Clear last_expr_type.
+ (finish_stmt_expr_expr): New.
+ (finish_stmt_expr): Process the value expression.
+
+ * typeck.c (build_compound_expr): If RHS is a TARGET_EXPR, put the
+ compound expr inside the target's initializer.
+
+ PR c++/11525
+ * parser.c (cp_parser_primary_expression): Do not set
+ non-constant-p merely because it is a dependent scope.
+
+ PR c++/9447
+ * decl2.c (do_class_using_decl): Set type to NULL_TREE.
+ * semantics.c (finish_expr_stmt): Do not convert to void in a
+ template.
+
+2003-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (coerce_template_parms): Refactor.
+ (fn_type_unification): Increment processing_template_decl when
+ tsubsting an incomplete set of explicit args.
+
+ PR c++/11347
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl around the tsubst of a template member
+ class.
+ (tsubst_qualified_id): Assert we do not have a dependent scope.
+
+ * pt.c (coerce_template_template_parms, lookup_template_class,
+ can_complete_type_without_circularity, instantiate_class_template,
+ tsubst_decl, unify): Reformat.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_make_one_only): Use mark_referenced.
+ * method.c (use_thunk): Likewsie.
+
+2003-07-30 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtable_entry_ref): Kill.
+ (build_vtbl_ref_1): Do not call build_vtable_entry_ref.
+ (build_vfn_ref): Do not call build_vtable_entry_ref.
+ * cp-lang.c (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): Kill.
+ * cp-tree.h (prepare_assemble_variable): Kill.
+ * cp-decl.c (prepare_assemble_variable): Kill.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * parser.c (cp_lexer_new_main): Use c_common_no_more_pch instead
+ of setting valid_pch by hand.
+
+2003-07-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * decl.c (finish_enum): Initialize underlying_type.
+
+2003-07-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9447
+ * decl.c (add_binding): Add bval local variable.
+ (push_class_level_binding): Likewise. Allow a USING_DECL to be
+ pushed.
+ * decl2.c (do_class_using_decl): The type of a using decl is
+ unknown.
+ * parser.c (cp_parser_postfix_expression): Refactor unqualified-id
+ function call lookup code.
+ * pt.c (tsubst): A USING_DECL will have unknown type.
+ (tsubst_copy_and_build): Allow a using decl.
+ (type_dependent_expression_p): A USING_DECL will make it
+ dependent.
+ * semantics.c (finish_member_declaration): Push a dependent using
+ declaration.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11530
+ * parser.c (cp_parser_postfix_expression): Do not call mark_used.
+ * semantics.c (finish_id_expression): Call mark_used for all
+ declarations.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11667
+ * call.c (standard_conversion): Allow all integral->enumeral
+ conversions, after marking them as bad.
+ * decl.c (finish_enum): Make sure that all enumerators are
+ properly converted to the underlying type.
+ (build_enumerator): Set DECL_CONTEXT for namespace-scope
+ enumeration types.
+ * pt.c (tsubst_copy): Adjust handling of CONST_DECLs accordingly.
+ (tsubst_enum): Tidy.
+
+ * Make-lang.in (typeck.o): Depend on convert.h.
+ (class.o): Likewise.
+ (rtti.o): Likewise.
+ * call.c: Include convert.h.
+ (convert_arg_to_ellipsis): Use convert_to_real.
+ * class.c: Include convert.h.
+ (build_base_path): Use convert_to_integer.
+ * rtti.c: Include convert.h.
+ (build_headof): Use convert_to_integer.
+ * typeck.c: Include convert.h.
+ (decay_conversion): Use convert_to_integer.
+ (build_unary_op): Use build_nop.
+ (get_delta_difference): Use convert_to_integer.
+ (build_ptrmemfunc): Avoid unnecessary conversions.
+
+2003-07-28 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Verify that member pointer points to
+ the function.
+
+2003-07-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (begin_compound_stmt): No scope arg is a bool.
+ (finish_compound_stmt): Remove no scope arg.
+ * decl.c (register_dtor_fn): Adjust begin_compound_stmt and
+ end_compound_stmt calls.
+ (expand_static_init, begin_destructor_body, begin_function_body,
+ finish_function_body): Likewise.
+ * decl2.c (start_objects, finish_objects,
+ start_static_storage_duration_function,
+ finish_static_storage_duration_function): Likewise.
+ * init.c (begin_init_stmts, finish_init_stmts,
+ construct_virtual_base, build_vec_init): Likewise.
+ * method.c (do_build_assign_ref, synthesize_method): Likewise.
+ * parser.c (cp_parser_compound_statement,
+ cp_parser_implicitly_scoped_statement,
+ cp_parser_already_scoped_statement): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_compound_stmt): No scope arg is a bool.
+ (finish_compound_stmt): Remove no scope arg.
+
+ * error.c (dump_expr) <COMPOUND_EXPR case>: A compound expr is
+ always dyadic.
+
+2003-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Tweak handling of
+ pointer-to-member types.
+ * pt.c (tsubst): Correctly qualify pointers-to-data member types.
+ * typeck.c (comp_ptr_ttypes_real): Check qualifiers on
+ pointer-to-data member types.
+
+2003-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_parser_type_parameter): Reformat.
+ (cp_parser_parameter_declaration): Deprecate default args where
+ not allowed.
+
+2003-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cfns.h: Rebuilt.
+
+ * cp-tree.h (begin_init_stmts, finish_init_stmts): Remove.
+ (begin_global_stmt_expr, finish_global_stmt_expr): Remove.
+ * init.c (begin_init_stmts): Make static. Return is_global
+ value. Always call begin_stmt_expr.
+ (finish_init_stmts): Make static. Add is_global parm. Always
+ building a stmt tree.
+ (build_aggr_init): Adjust begin_init_stmts, finish_init_stmts calls.
+ (build_vec_init): Likewise. Always building a stmt tree.
+ (expand_default_init): Always building a stmt tree.
+ (get_temp_regvar): Likewise.
+ * semantics.c (begin_global_stmt_expr,
+ finish_global_stmt_expr): Remove.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (build_compound_expr): Take LHS & RHS args.
+ (build_x_compound_expr_from_list): Declare.
+ * typeck.c (build_x_compound_expr_from_list): New.
+ (build_x_compound_expr): Adjust.
+ (build_compound_expr): Remove unreachable code. Take two
+ parameters, adjust.
+ * decl.c (grok_reference_init): Use
+ build_x_compound_expr_from_list.
+ (expand_static_init): Adjust build_compound_expr call.
+ (cxx_maybe_build_cleanup): Likewise.
+ * init.c (perform_member_init): Use
+ build_x_compound_expr_from_list.
+ (build_new_1): Likewise.
+ (build_vec_delete): Adjust build_compound_expr calls.
+ (build_vbase_delete): Likewise.
+ * typeck2.c (store_init_value): Use
+ build_x_compound_expr_from_list.
+ (build_functional_cast): Likewise.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum tsubst_flags_t): Add tf_user.
+ * decl.c (make_typename_type): Pass it.
+ * pt.c (lookup_template_class): Use it.
+ (resolve_typename_type): Pass it.
+ * semantics.c (finish_template_type): Pass it.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11617
+ * cp-tree.h (qualified_name_lookup_error): Declare.
+ * pt.c (tsubst_qualified_id): Use qualified_name_lookup_error for
+ errors.
+ (tsubst_expr) <DECL_STMT case>: Likewise.
+ (tsubst_copy_and_build) <COMPONENT_REF case>: Likewise.
+ * semantics.c (qualified_name_lookup_error): New, broken out of ...
+ (finish_id_expression): ... here. Use it.
+
+2003-07-25 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ * cfns.gperf: Add '%%' delimiter to placate gperf 3.0.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11596
+ * pt.c (maybe_fold_nontype_arg, maybe_fold_nontype_args): Remove.
+ (tsubst_template_arg): New.
+ (tsubst_template_arg_vector): Rename to ...
+ (tsubst_template_args): ... this. Accept a TREE_LIST form. Use
+ tsubst_template_arg.
+ (coerce_template_parms): Use tsubst_template_arg for default
+ value.
+ (tsubst_template_parms): Likewise.
+ (tsubst_aggr_type): Adjust.
+ (tsubst_decl): Likewise.
+ (tsubst): Use tsubst_template_arg for a DOMAIN. Adjust.
+ (tsubst_copy) <TEMPLATE_ID_EXPR case>: Use tsubst_template_args.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp/error.o): Depend on DIAGNOSTIC_H.
+ * error.c: Use the new pretty-printer framework.
+
+2003-07-24 Per Bothner <pbothner@apple.com>
+
+ * decl.c (pushdecl_class_level): Don't use push_srcloc/pop_srcloc
+ which causes errors messages to incorrectly mention included files.
+
+2003-07-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (convert_to_base_statically): Declare.
+ * call.c (build_special_member_call): Convert INSTANCE to the base
+ type.
+ * class.c (convert_to_base_statically): New method.
+ * init.c (construct_virtual_base): Use it.
+ * method.c (do_build_assign_ref): Fix typo in comment.
+
+2003-07-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c: Just set truthvalue_* to boolean_*.
+
+2003-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (reshape_init): Remove unreachable code.
+
+2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11513
+ * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): Use current_scope.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11645
+ * cp-tree.h (accessible_base_p): Declare.
+ * call.c (build_over_call): Use it.
+ * search.c (accessible_base_p): New function, split out from ...
+ (lookup_base): ... here.
+
+ PR c++/11517
+ * call.c (build_conditional_expr): Use perform_implicit_conversion
+ and error_operand_p. Robustify.
+ * typeck.c (build_unary_op): Use perform_implicit_conversion.
+
+2003-07-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10953
+ * parser.c (cp_parser_nested_name_specifier): Reset scope on
+ failure.
+ (cp_parser_elaborated_type_specifier): Likewise.
+
+2003-07-22 Mark Mitchell <mark@codesourcery.com>
+
+ Eliminate use of POINTER_TYPE for pointers-to-members.
+ * call.c (standard_conversion): Rework pointer-to-member handling.
+ Add comments.
+ (add_builtin_candidate): Likewise.
+ (resolve_scoped_fn_name): Remove.
+ (build_conditional_expr): Rework pointer-to-member handling.
+ (compare_ics): Likewise.
+ * class.c (check_field_decls): Use TYPE_PTR_P.
+ * cp-lang.c (cp_var_mod_type_p): Rework pointer-to-member
+ handling.
+ * cp-tree.h (SCALAR_TYPE_P): Use TYPE_PTR_TO_MEMBER_P.
+ (TYPE_PTRMEM_P): Add comment.
+ (TYPE_PTR_P): Simplify.
+ (TYPE_PTROB_P): Correct definition.
+ (TYPE_PTR_TO_MEMBER_P): New macro.
+ (TYPE_PTRMEM_CLASS_TYPE): Adjust.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (resolved_scoped_fn_name): Remove declaration.
+ (build_offset_ref): Change prototype.
+ (resolve_offset_ref): Remove.
+ (comp_target_types): Remove.
+ * cvt.c (cp_convert_to_pointer): Rework pointer-to-member
+ handling.
+ (convert_to_reference): Use can_convert.
+ (ocp_convert): Improve error handling. Rework pointer-to-member
+ handling.
+ (perform_qualification_conversions): Rework pointer-to-member
+ handling.
+ * decl.c (build_ptrmem_type): Handle functions too.
+ (create_array_type_for_decl): Remove OFFSET_TYPE error message.
+ (grokdeclarator): Use OFFSET_TYPE for pointers to data members.
+ (grokparms): Remove OFFSET_TYPE error message.
+ * dump.c (cp_dump_tree): Rework pointer-to-member handling.
+ * error.c (dump_type_prefix): Likewise.
+ * expr.c (cplus_expand_constant): Use build_nop.
+ * init.c (build_offset_ref): Add address_p parameter. Fold in
+ necessary bits from resolve_offset_ref.
+ (resolve_offset_ref): Remove.
+ * parser.c (cp_parser_postfix_expression): Remove special case
+ code for OFFSET_TYPE.
+ * pt.c (convert_nontype_argument): Rework pointer-to-member
+ handling.
+ (convert_template_argument): Likewise.
+ (unify): Likewise.
+ (invalid_nontype_parm_type_p): Likewise.
+ (dependent_type_p_r): Likewise.
+ * rtti.c (get_tinfo_decl): Remove OFFSET_TYPE special case.
+ (target_incomplete_p_): Rework pointer-to-member
+ handling.
+ (get_pseudo_ti_init): Likewise.
+ (get_pseudo_ti_desc): Likewise.
+ * semantics.c (finish_qualified_id_expr): Adjust call to
+ build_offset_ref. Remove use of resolve_offset_ref.
+ * tree.c (pod_type_p): Use TYPE_PTR_TO_MEMBER_P.
+ * typeck.c (target_type): Use TYPE_PTRMEM_P.
+ (type_unknown_p): Remove obsolete code about the time before
+ non-dependent expressions were handled correctly.
+ (qualify_type_recursive): Remove.
+ (composite_pointer_type_r): New function.
+ (composite_pointer_type): Use it.
+ (merge_types): Remove dead comments.
+ (comp_cv_target_types): Remove.
+ (comp_target_types): Likewise.
+ (comp_target_parms): Likewise.
+ (cxx_sizeof_or_alignof_type): Remove OFFSET_TYPE error.
+ (build_indirect_ref): Use TYPE_PTR_TO_MEMBER_P.
+ (build_binary_op): Do not use of comp_target_types.
+ (pointer_diff): Remove OFFSET_TYPE case.
+ (build_unary_op): Adjust pointer-to-member handling.
+ (unary_complex_lvalue): Likewise.
+ (check_for_casting_away_constness): Add description parameter.
+ (build_static_cast): Pass it.
+ (build_reinterpret_cast): Use check_for_casting_away_constness.
+ (build_const_cast): Adjust pointer-to-member handling.
+ (build_c_cast): Likewise.
+ (convert_for_assignment): Remove OFFSET_TYPE error message.
+ (comp_ptr_ttypes_real): Adjust pointer-to-member handling.
+ (comp_ptr_ttypes_reinterpret): Remove.
+ (casts_away_constness_r): Adjust pointer-to-member handling.
+ (casts_away_constness): Liekwise.
+ (strip_all_pointer_quals): Remove.
+ * typeck2.c (digest_init): Adjust pointer-to-member handling.
+ (build_m_component_ref): Likewise.
+
+2003-07-22 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * lex.c (unqualified_fn_lookup_error): Mention that the error
+ message needs to be kept in synch with the manual.
+
+2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11614
+ * decl.c (grokdeclarator): An array member is only a flexible
+ array member if the field itself is the array.
+
+2003-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10793
+ * decl.c (xref_basetypes): Handle error_mark_node.
+
+2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum cp_lvalue_kind): Add clk_packed.
+ * tree.c (lvalue_p_1): Set it.
+ * class.c (check_field): Don't allow non-packed non-POD fields to
+ be packed.
+ * call.c (reference_binding): Need a temporary for all bitfield
+ and packed fields.
+ (convert_like_real): Check it is ok to make a temporary here.
+
+2003-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (hack_identifier): Remove.
+ * method.c (hack_identifier): Remove.
+ * semantics.c (finish_id_expression): Expand hack_identifier
+ here. Simplify.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c class.c decl.c decl2.c g++spec.c lex.c parser.c pt.c rtti.c
+ semantics.c typeck.c: Remove unnecessary casts.
+
+2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (hack_identifier): Remove.
+ * method.c (hack_identifier): Remove.
+ * semantics.c (finish_id_expression): Expand hack_identifier
+ here. Simplify.
+
+2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_non_static_data_member): Add object param.
+ * method.c (hack_identifier): Adjust.
+ * pt.c (tsubst_copy_and_build) <COMPONENT_REF case>: Don't search
+ again for a FIELD_DECL.
+ * semantics.c (finish_non_static_data_member): Add object
+ parameter. Always save the DECL in the COMPONENT_REF.
+ * call.c (resolve_scoped_fn_name): Adjust.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * pt.c (get_bindings): Make definition consistent with
+ forward declaration.
+
+2003-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7809
+ * friend.c (add_friend): Check access for member functions
+ and templates.
+
+2003-07-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10668
+ * typeck.c (build_class_member_access_expr): Improve diagnostic.
+
+2003-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11547
+ * cp-tree.h (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P): New
+ macro.
+ (DECL_PRETTY_FUNCTION_P): Use VAR_DECL_CHECK.
+ * decl.c (duplicate_decls): Merge
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ * parser.c (cp_parser_postfix_expression): Adjust call to
+ cp_parser_initializer_list and
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_parenthesized_expression_list): Add non_constant_p.
+ (cp_parser_new_placement): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_conditional_expression): Remove.
+ (cp_parser_constant_expression): Parse an assignment-expression,
+ not a conditional-expression.
+ (cp_parser_simple_declaration): Resolve expression/declaration
+ ambiguity more quickly.
+ (cp_parser_mem_initializer): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_init_declarator): Keep track of whether or not the
+ initializer is a constant-expression.
+ (cp_parser_initializer): Add non_constant_p parameter.
+ (cp_parser_initializer_clause): Likewise.
+ (cp_parser_initializer_list): Likewise.
+ (cp_parser_attribute_list): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_functional_cast): Likewise.
+ * pt.c (tsubst_decl): Copy
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ (tsubst_expr): Tweak use of DECL_PRETTY_FUNCTION_P.
+ * semantics.c (finish_id_expression): Use
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+
+2003-07-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-options.h: Remove.
+
+2003-07-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/10962
+ * class.c (field_decl_cmp): Remove.
+ (resort_field_decl_cmp): Remove.
+ (resort_sorted_fields): Remove.
+ (add_fields_to_vec): Rename to ...
+ (add_fields_to_record_type): this.
+ (finish_struct_1): Change to be using
+ sorted_fields_type's fields.
+ * cp-tree.h (lang_decl): In lang_decl_u3
+ change sorted_fields to be a pointer to
+ sorted_fields_type.
+ (resort_sorted_fields): Remove prototype.
+ * search.c (lookup_field_1): Change to be using
+ sorted_fields_type's fields.
+
+2003-07-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5421
+ * decl.c (grokdeclarator): Handle TEMPLATE_ID_EXPR if friend
+ is a member of other class.
+ * friend.c (do_friend): Don't build TEMPLATE_DECL if friend
+ is a specialization of function template.
+
+2003-07-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10903
+ * pt.c (convert_nontype_argument): Fix thinko in diagnostic.
+ Improve.
+
+2003-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (LOOKUP_EXPR): Remove.
+ * cp-tree.h (cp_id_kind): Add CP_ID_KIND_UNQUALIFIED_DEPENDENT.
+ (LOOKUP_EXPR_GLOBAL): Remove.
+ (get_bindings): Remove.
+ (is_aggr_type_2): Remove.
+ * call.c (resolved_scoped_fn_name): Remove support for
+ LOOKUP_EXPR.
+ * decl.c (grokfndecl): Likewise.
+ (grokdeclarator): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * lex.c (unqualified_fn_lookup_error): Use pedwarn. Do not create
+ LOOKUP_EXPRs
+ * mangle.c (write_expression): Remove support for LOOKUP_EXPR.
+ * parser.c (cp_parser_postfix_expression): Modify Koenig lookup
+ test.
+ * pt.c (get_bindings): Give it internal linkage.
+ (check_explicit_specialization): Remove support for LOOKUP_EXPR.
+ (lookup_template_function): Likewise.
+ (for_each_tempalte_parm_r): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst_qualified_id): Handle template template parameters.
+ (tsubst_copy): Remove support for LOOKUP_EXPR.
+ (tsubst_copy_and_build): Likewise.
+ (most_general_template): Likewise.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Note that IDENTIFIER_NODEs are
+ always dependent.
+ * semantics.c (perform_koenig_lookup): Do not create
+ IDENTIFIER_NODEs.
+ (finish_fname): Likewise.
+ (finish_id_expression): Likewise.
+ * tree.c (is_aggr_type_2): Remove.
+
+2003-07-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11531
+ * typeck.c (check_return_expr): Fix thinko in diagnostic.
+
+2003-07-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10108
+ * pt.c (tsubst_decl) <TEMPLATE_DECL>: Add a check for
+ error_mark_node.
+
+2003-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11509
+ * pt.c (dependent_scope_ref_p): New function.
+ (value_dependent_expression_p): Use it.
+ (type_dependent_expression_p): Likewise.
+
+ * pt.c (tsubst_friend_function): Use reregister_specialization.
+
+ PR c++/7019
+ * cp-tree.h (lookup_qualified_name): Adjust prototype.
+ * decl.c (lookup_qualified_name): Add complain parameter. Adjust
+ call to is_aggr_type.
+ * parser.c (cp_parser_lookup_name): Adjust call to
+ lookup_qualified_name.
+ * pt.c (tsubst_qualified_id): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * semantics.c (finish_qualified_id_expr): Deal with erroneous
+ expressions.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11510
+ * call.c (op_error): Properly format REALPART_EXPR and
+ IMAGPART_EXPR.
+ * error.c (dump_expr): Likewise.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Handle EMPTY_CLASS_EXPR.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/5293
+ * call.c (initialize_reference): Improve diagnostic.
+
+2003-07-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11154
+ * pt.c (more_specialized_class): Add full_args parameter.
+ (most_specialized_class): Adjust calls to more_specialized_class.
+ * cp-tree.h (more_specialized_class): Adjust declaration.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * lex.c (enum tree_node_kind): Delete.
+
+2003-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11503
+ * cp-tree.h (DECL_SELF_REFERENCE_P): New macro.
+ (SET_DECL_SELF_REFERENCE_P): Likewise.
+ * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P.
+ * pt.c (tsubst_decl): Copy it.
+ * search.c (lookup_base): Use DECL_SELF_REFERENCE_P.
+
+ * pt.c (reregister_specialization): Fix thinko in previous change.
+
+ * cp-tree.h (cp_id_kind): New type.
+ (unqualified_name_lookup_error): Change prototype.
+ (unqualified_fn_lookup_error): New function.
+ (do_identifier): Remove.
+ (do_scoped_id): Likewise.
+ (tsubst_copy_and_build): Change prototype.
+ (reregister_specialization): New function.
+ (perform_koenig_lookup): Likewise.
+ (finish_id_expression): Likewise.
+ * call.c (build_method_call): Adjust call to
+ unqualified_name_lookup_error.
+ * decl.c (duplicate_decls): Use reregister_specialization.
+ * lex.c (is_global): Remove.
+ (unqualified_name_lookup_error): Return a value.
+ (do_identifier): Remove.
+ (do_scoped_id): Likewise.
+ (identifier_typedecl_value): Remove.
+ (unqualified_fn_lookup_error): New function.
+ * parser.c (cp_parser_id_kind): Remove.
+ (cp_parser_non_constant_id_expression): Remove.
+ (cp_parser_primary_expression): Use finish_id_expression.
+ (cp_parser_class_or_namespace_name): Use cp_id_kind, not
+ cp_parser_id_kind.
+ (cp_parser_postfix_expression): Use perform_koenig_lookup.
+ (cp_parser_template_argument): Use cp_id_kind.
+ (cp_parser_fold_non_dependent_expr): Adjust call to
+ tsubst_copy_and_build.
+ * pt.c (unregister_specialization): Rename to ...
+ (reregister_specialization): This.
+ (tsubst_friend_function): Use it.
+ (maybe_fold_nontype_arg): Adjust call to tsubst_copy_and_build.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_expr): Likewise.
+ (tsubst_copy_and_build): Add function_p parameter. Use
+ finish_id_expression. Introduce RECUR macro.
+ (tsubst_non_call_postfix_expression): New function.
+ (regenerate_decl_from_template): Use reregister_specialization.
+ * semantics.c (perform_koenig_lookup): New function.
+ (finish_id_expression): Likewise.
+
+2003-07-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (push_access_scope_real): Remove.
+ (push_access_scope): Move code from push_access_scope_real.
+ (pop_access_scope): Don't check for TEMPLATE_DECL.
+ (instantiate_template): Defer access checking during template
+ substitution.
+ (regenerate_decl_from_template): Tidy.
+
+2003-07-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR c++/11437
+ * operators.def: Add definitions for __imag__, __real__.
+
+2003-07-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11050
+ * parser.c (cp_parser_expression_list): Rename to ...
+ (cp_parser_parenthesized_expression_list): ... here. Add attribute
+ parameter, parse the surounding parentheses.
+ (cp_parser_skip_to_closing_parenthesis): Add recover and or_comma
+ parameters. Return int.
+ (cp_parser_skip_to_closing_parenthesis or comma): Remove.
+ (cp_parser_postfix_expression): Adjust function call parsing.
+ (cp_parser_new_placement): Adjust.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_selection_statement): Likewise.
+ (cp_parser_mem_initializer): Likewise.
+ (cp_parser_asm_definition): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_declarator): Make
+ cdtor_or_conv_p an int ptr.
+ (cp_parser_direct_declarator): Likewise. Check for a parameter
+ list on cdtors & conv functions.
+ (cp_parser_initializer): Adjust.
+ (cp_parser_member_declaration): Adjust.
+ (cp_parser_attribute_list): Move code into
+ cp_parser_parens_expression_list.
+ (cp_parser_functional_cast): Adjust.
+ * pt.c (type_dependent_expression_p): Erroneous expressions are
+ non-dependent.
+
+2003-07-11 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (cp_finish_decl): Handle 'used' attribute.
+
+ * cp-lang.c (c_reset_state): New dummy routine.
+ * cp-tree.h (finish_file): Move prototype to c-common.h.
+ * parser.c (c_parse_file): Rename from yyparse; don't call finish_file.
+
+2003-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8327
+ * pt.c (tsubst_qualified_id): Implement suggested resolution for
+ Core Issue 2.
+ (type_dependent_expression_p): Likewise.
+
+2003-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_binary_op): Do not warn about signed
+ vs. unsigned comparisons in the bodies of templates.
+
+ PR c++/9411
+ * parser.c (cp_parser_postfix_expression): Check dependency of
+ functions.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10032
+ * decl.c (cxx_init_decl_processing): With -pedantic, pedwarns are
+ still errors.
+
+ PR c++/10527
+ * error.c (decl_to_string): Do not print default argument
+ expressions.
+
+ * cp-tree.h (break_out_calls): Remove declaration.
+ * tree.c (break_out_calls): Remove.
+ * typeck.c (build_modify_expr): Avoid invalid sharing of trees.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++ 9483
+ * class.c (check_field_decls): Pass DECL_NAME to constructor_name_p.
+ * decl2.c (constructor_name_p): Avoid repeated constructor_name
+ calls.
+ * decl.c (grokdeclarator): Refactor ctor/dtor detection.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_x_unary_op): Take note of the fact that
+ PREINCREMENT_EXPR and POSTINCREMENT_EXPR are binary operations on
+ trees.
+
+ * parser.c (cp_parser_primary_expression): Preserve the form of
+ qualified expressions in templates, even if they are not
+ dependent.
+ * pt.c (convert_nontype_argument): Handle non-dependent SCOPE_REFs.
+ (tsubst_qualified_id): Likewise.
+ * search.c (accessible_p): Treat everything in the body of a
+ template as accessible.
+
+2003-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (NON_DEPENDENT_EXPR): New node.
+ * cp-tree.h (build_call_from_tree): Remove.
+ (build_member_call): Likewise.
+ (dependent_template_arg_p): Remove.
+ (any_dependent_template_arguments_p): New function.
+ (dependent_template_id_p): Likewise.
+ (any_type_dependent_arguments_p): Likewise.
+ (build_non_dependent_expr): Likewise.
+ (build_non_dependent_args): Likewise.
+ (build_x_compound_expr): Adjust prototype.
+ * call.c (build_new_method_call): Handle non-dependent expressions
+ correctly.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_offset_ref_call_from_tree): Likewise.
+ (build_call_from_tree): Remove.
+ * error.c (dump_decl): Handle NON_DEPENDENT_EXPR.
+ (dump_expr): Likewise.
+ * init.c (build_member_call): Remove.
+ * mangle.c (write_expression): Update handling for template-ids.
+ * parser.c (cp_parser_primary_expression): Use
+ any_dependent_template_arguments_p. Update constant-expression
+ handling.
+ (cp_parser_postfix_expression): Use
+ any_type_dependent_arguments_p. Simplify call processing.
+ (cp_parser_unary_expression): Simplify.
+ (cp_parser_expression): Adjust for changes to
+ build_x_compound_expr.
+ (cp_parser_template_argument): Implement standard-conforming
+ parsing of non-type template arguments.
+ (cp_parser_direct_declarator): Use
+ cp_parser_fold_non_dependent_expr.
+ (cp_parser_fold_non_dependent_expr): New function.
+ (cp_parser_next_token_ends_template_argument_p): Likewise.
+ * pt.c (convert_template_argument): Do not call
+ maybe_fold_nontype_arg.
+ (tsubst_baselink): Likewise.
+ (tsubst_copy_and_build): Share common code. Make sizeof/alignof
+ processing work correctly for non-dependent expressions. Adjust
+ handling of COMPOUND_EXPR. Simplify call processing.
+ (value_dependent_expression_p): Deal with functional casts and
+ sizeof/alignof correctly.
+ (type_dependent_expression_p): Handle overloaded functions.
+ (any_type_dependent_arguments_p): New function.
+ (any_dependent_template_arguments_p): Likewise.
+ (dependent_template_p): Treat SCOPE_REFs as dependent.
+ (dependent_template_id_p): Simplify.
+ (build_non_dependent_expr): New function.
+ (build_non_dependent_args): Likewise.
+ * semantics.c (finish_stmt_expr): Don't make dependent
+ statement-expresions have void type.
+ (finish_call_expr): Handle non-dependent expressions
+ correctly.
+ * tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues.
+ * typeck.c (cxx_sizeof_or_alignof_type): Give the expression
+ type size_t, even in templates.
+ (expr_sizeof): Likewise.
+ (finish_class_member_access_expr): Handle non-dependent expressions
+ correctly.
+ (build_x_indirect_ref): Likewise.
+ (build_x_binary_op): Likewise.
+ (build_x_unary_op): Likewise.
+ (build_x_conditional_expr): Likewise.
+ (build_x_compound_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+ * decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
+ (start_function): Use DECL_ESTIMATED_INSNS.
+ * optimize.c (maybe_clone_body): Use DECL_ESTIMATED_INSNS.
+
+ * decl2.c (maybe_emit_vtables): Fix marking vtables as needed in
+ unit-at-a-time
+
+2003-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11030
+ * pt.c (instantiate_class_template): Don't call xref_tag to
+ inject name when the friend class is a specialization.
+
+2003-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_scoped_method_call): Remove.
+ (lookup_qualified_name): Remove parameter.
+ (tsubst_copy_and_build): Declare.
+ (finish_qualified_object_call_expr): Remove.
+ (check_accessibility_of_qualified_id): New function.
+ (finish_qualified_id_expr): Likewise.
+ (non_reference): Likewise.
+ (build_expr_from-tree): Remove.
+ * call.c (non_reference): Remove.
+ (build_scoped_method_call): Likewise.
+ (build_method_call): Use error_operand_p. Assert that we are not
+ processing a template.
+ (standard_conversion): Use non_reference.
+ * class.c (build_vtbl_entry_ref): Likewise.
+ (build_vtbl_ref_1): Likewise.
+ * cvt.c (build_expr_type_conversion): Use non_reference.
+ * decl.c (lookup_qualified_name): Remove flags parameter.
+ (grok_op_properties): Use non_reference.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_expr_from_tree): Remove.
+ (build_offset_ref_call_from_tree): Update comment.
+ * error.c (parm_to_string): Call reinit_global_formatting_buffer.
+ * except.c (prepare_eh_types): Use non_reference.
+ (can_convert_eh): Likewise.
+ * init.c (build_dtor_call): Avoid using build_method_call.
+ * mangle.c (write_template_param): Remove misleading comment.
+ * method.c (locate_copy): Use non_reference.
+ * parser.c (cp_parser_scope_through_which_access_occurs): Remove.
+ (cp_parser_primary_expression): Do not create SCOPE_REFs is
+ non-dependent contexts.
+ (cp_parser_postfix_expression): Use finish_qualified_id_expr.
+ (cp_parser_direct_declarator): Use tsubst_copy_and_build, not
+ build_expr_from_tree.
+ (cp_parser_lookup_name): Adjust call to lookup_qualified_name.
+ Use check_accessibility_of_qualified_id.
+ * pt.c (maybe_fold_nontype_arg): Use tsubst_copy_and_build, not
+ build_expr_from_tree.
+ (tsubst_baselink): New function.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_copy): Use them. Remove support for METHOD_CALL_EXPR.
+ (tsubst_expr): Adjust call to lookup_qualified_name.
+ (tsubst_copy_and_build): Handle SCOPE_REFs specially. Adjust
+ handling of CALL_EXPRs.
+ (value_dependent_expression_p): Use INTEGRAL_OR_ENUMERATION_TYPE_P.
+ * rtti.c (get_tinfo_decl_dynamic): Use non_reference.
+ * search.c (check_final_overrider): Likewise.
+ * semantics.c (check_accessibility_of_qualified_id): New function.
+ (finish_qualified_object_call_expr): Remove.
+ * typeck.c (target_type): Use non_reference.
+ (cxx_sizeof_or_alignof_type): Likewise.
+ (dubious_conversion_warnings): Likewise.
+ (convert_for_initialization): Likewise.
+ (non_reference): New function.
+
+2003-07-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (print_binding_level, print_other_binding_stack,
+ print_binding_stack): Merge uses of HOST_PTR_PRINTF with adjacent
+ stdio calls.
+ * ptree.c (cxx_print_decl, cxx_print_binding): Likewise.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * friend.c: Convert to ISO C90 prototypes.
+
+ * Make-lang.in ($(srcdir)/cp/cfns.h): Use ANSI-C as output
+ language.
+ * cfns.h: Regenerate.
+
+ * typeck.c: Convert remaining prototypes to ISO C90.
+ * search.c: Likewise.
+
+ * decl2.c (build_expr_from_tree): Convert prototype to ISO C90.
+ * semantics.c (expand_or_defer_fn): Likewise
+ * mangle.c (discriminator_for_string_literal): Likewise.
+ * g++spec.c (lang_specific_driver): Likewise.
+
+ * search.c (lookup_base_r): Remove unused variable.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c: (genrtl_try_block) Adjust emit_line_note
+ calls.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * search.c (lookup_base_r): Remove unused variable.
+
+2003-07-06 Michael Chastain <mec@shout.net>
+
+ PR debug/10055
+ * lex.c (cxx_init): Call push_srcloc and pop_srcloc rather than
+ assigning to input_filename directly.
+
+2003-07-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * method.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-07-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11345
+ * search.c (lookup_base_r): Remove is_non_public and
+ within_current_scope parameters. Remove other dead code.
+ (lookup_base): Adjust call to lookup_base_r.
+ (adjust_result_of_qualified_name_lookup): Improve comment.
+ * semantics.c (finish_call_expr): Use maybe_dummy_object.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): Override.
+
+2003-07-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11431
+ * typeck.c (build_static_cast): Check for reference conversions
+ earlier.
+
+2003-07-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (perform_integral_promotions): Declare.
+ * call.c (build_addr_func): Use decay_conversion.
+ (convert_arg_to_ellipsis): Likewise. Remove misleading comment.
+ (convert_for_arg_passing): Use perform_integral_promotions.
+ * cvt.c (build_expr_type_conversion): Use decay_conversion.
+ (type_promotes_to): Do not return a cv-qualified type.
+ * decl.c (grok_reference_init): Fix formatting.
+ (get_atexit_node): Use decay_conversion.
+ (build_enumerator): Use perform_integral_promotions.
+ * init.c (build_vec_init): Use decay_conversion.
+ * semantics.c (finish_expr_stmt): Likewise.
+ (finish_switch_cond): Use perform_integral_promotions.
+ * typeck.c (default_conversion): Likewise.
+ (perform_integral_promotions): New function.
+ (build_indirect_ref): Use decay_conversion.
+ (build_array_ref): Use perform_integral_promotions.
+ (convert_arguments): Use decay_conversion.
+ (build_unary_op): Use perform_integral_promotions.
+ (build_c_cast): Use decay_conversion.
+ (build_modify_expr): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl2.c: Likewise.
+ * decl.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * parser.c (cp_lexer_read_token): No need to handle string
+ constant concatenation.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (GCC_DIAG_STYLE, ATTRIBUTE_GCC_CXXDIAG): Define.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Mark with
+ ATTRIBUTE_GCC_CXXDIAG.
+
+2003-07-03 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_addr_func): Handle bound pointers-to-members.
+ (build_method_call): Do not call resolve_offset_ref.
+ (implicit_conversion): Likewise.
+ (resolve_scoped_fn_name): Use finish_non_static_data_member, not
+ resolve_offset_ref.
+ (resolve_args): Do not call resolve_offset_ref.
+ (build_conditional_expr): Likewise.
+ (build_new_method_call): Likewise.
+ * cp-tree.def (OFFSET_REF): Update documentation.
+ * cvt.c (cp_convert_to_pointer): Update handling of conversions from
+ pointers to members to pointers.
+ (ocp_convert): Do not call resolve_offset_ref.
+ (convert_to_void): Likewise.
+ (build_expr_type_conversion): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ * init.c (resolve_offset_ref): Simplify greatly.
+ (build_vec_delete): Do not call resolve_offset_ref.
+ * parser.c (cp_parser_postfix_expression): Call resolve_offset_ref
+ if appropriate.
+ (cp_parser_unary_expression): Use
+ cp_parser_simple_cast_expression.
+ (cp_parser_delete_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_pm_expression): Use cp_parser_binary_op.
+ (cp_parser_simple_cast_expression): New function.
+ * rtti.c (build_dynamic_cast_1): Do not call resolve_offset_ref.
+ * semantics.c (finish_increment_expr): Likewise.
+ (finish_typeof): Likewise.
+ * tree.c (lvalue_p_1): Do not handle OFFSET_REF.
+ * typeck.c (require_complete_type): Do not handle OFFSET_REFs.
+ (decay_conversion): Do not call resolve_offset_ref.
+ (finish_class_member_access_expr): Likewise.
+ (convert_arguments): Likewise.
+ (build_x_binary_op): Handle DOTSTAR_EXPR.
+ (condition_conversion): Do not call resolve_offset_ref.
+ (unary_complex_lvalue): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+ (build_m_component_ref): Simplify.
+
+ * call.c (build_scoped_method_call): Use convert_to_void.
+ (build_method_call): Likewise.
+ * class.c (check_field_decls): Remove dead code.
+ * cvt.c (convert_from_reference): Remove OFFSET_TYPE handling.
+ * decl2.c (grok_array_decl): Remove dead code.
+ (arg_assoc_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
+ as pointer-to-member representation.
+ * init.c (build_offset_ref): Tidy.
+ (build_vec_delete_1): Use convert_to_void.
+ * mangle.c (write_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
+ as pointer-to-member representation.
+
+2003-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9162
+ * decl.c (grokdeclarator): Return friend decls, not
+ void_type_node.
+ * decl2.c (grokfield): Alter friend decl check.
+ * parser.c (struct cp_parser): Document default_arg chain on
+ unparsed_functions_queue.
+ (cp_parser_save_default_args): New.
+ (cp_parser_init_declarator, cp_parser_function_definition,
+ cp_parser_member_declaration): Call it.
+ (cp_parser_class_specifier): Remove unused variable. Alter
+ processing of unparsed_functions_queue.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (add_method, check_field_decl): Fix format specifier.
+ * decl.c (duplicate_decls, pushdecl, check_goto,
+ fixup_anonymous_aggr, maybe_commonize_var, grokdeclarator,
+ start_enum): Likewise.
+ * decl2.c (ambiguous_decl): Likewise.
+ * pt.c (redeclare_class_template): Likewise.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10219
+ * pt.c (type_unification_real): Don't unify exprs of error type.
+ * tree.c (error_type): Don't die on error_type.
+
+ PR c++/9779
+ * decl2.c (arg_assoc_class): Don't die on NULL type.
+ * typeck.c (type_unknown_p): Don't die on untyped expressions.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6949
+ * decl2.c (grokfield): Create TEMPLATE_DECLs for methods in local
+ classes.
+
+2003-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (locate_error): %P takes an `int', not a `tree'.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (defer_fn): Set DECL_DEFER_OUTPUT.
+ (finish-file): Do not process function with DECL_DEFER_OUTPUT clear;
+ clear DECL_DEFER_OUTPUT once function is processed; avoid flags
+ massaging.
+
+ * cp-tree.h (DECL_NEEDED_P): Support unit-at-a-time
+ (expand_or_defer_fn): Declare.
+ (lower_function): Declare.
+ * decl.c (start_cleanup_fn): Use expand_or_defer_fn.
+ * decl2.c: Include cgraph.h and varpool.h
+ (maybe_emit_vtables): Make explicit instantations as needed.
+ (mark_member_pointers, lower_function): New functions.
+ (finish_file): Do unit-at-a-time.
+ * method.c (synthesize_method): Use expand_or_defer_fn.
+ * optimize.c (maybe_clone_body): Use expand_or_defer_fn.
+ * parser.c (cp_parser_function_definition_after_decl): Use
+ expand_or_defer_fn.
+ * pt.c (instantiate_decl): Likewise.
+ * semantics.c: Include cgraph.h
+ (expand_or_defer_fn): Break out from ...
+ (expand_body): ... here; deal with unit-at-a-time.
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION,
+ LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Define.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (resolve_scoped_fn_name): Return error_mark_node for
+ erroneous cases.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11149
+ * call.c (resolve_scoped_fn_name): Check that the qualifying scope
+ is a class type.
+
+2003-07-01 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/8046
+ * error.c (dump_decl): Handle BIT_NOT_EXPR as
+ pseudo destructor calls.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (define_label): Replace filename and lineno
+ arguments with a location_t.
+ * decl.c (pop_label): Adjust define_label call.
+ (define_label): Replace filename and lineno arguments with a
+ location_t.
+ * semantics.c (finish_label): Adjust define_label call.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9559
+ * decl2.c (grokfield): Do not build NOP_EXPRs around the
+ error_mark_node.
+
+2003-06-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+ * cp-lang.c (c_language): Define.
+ (LANG_HOOKS_INIT_OPTIONS): Use common hook.
+ * cp-tree.h (cxx_init_options): Remove.
+ * lex.c: Don't include diagnostic.h.
+ (cxx_init_options): Remove.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/4933
+ * error.c (dump_expr): Support correctly the COMPOUND_EXPR
+ tree generated within a template. Use dump_expr to dump an
+ expression sizeof.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ * mangle.c (write_expression): Exit gracefully when trying to
+ mangle a CALL_EXPR.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/10750
+ * parser.c (cp_parser_primary_expression): A VAR_DECL with a
+ (value- or type-) dependent expression as DECL_INITIAL is a
+ valid constant-expression (at parser time).
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/11106
+ * error.c (dump_decl): Call dump_decl to dump the DECL_NAME for a
+ USING_DECL, instead of print_tree_identifier.
+
+2003-06-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (language_to_string): Adjust declaration.
+ * dump.c (cp_dump_tree): Adjust usage.
+ * error.c (dump_char): Use output_formatted_scalar. Tidy.
+ (parm_to_string): Lose unused parameter. Tidy.
+ (expr_to_string): Likewise.
+ (code_to_string): Likewise.
+ (language_to_string): Likewise.
+ (op_to_string): Likewise.
+ (assop_to_string): Likewise.
+ (digit_buffer): Remove.
+ (dump_type): Format builtin vector type as __vector__.
+
+2003-06-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (print_integer): Remove.
+ (dump_type_suffix): Adjust.
+ (dump_expr): Likewise.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (print_instantiation_partial_context): Take a
+ location_t.
+ (print_instantiation_full_context): Adjust.
+ (print_instantiation_context): Adjust.
+
+ * cp-tree.h (cp_line_of, cp_file_of): Remove.
+ * error.c (cp_line_of, cp_file_of): Merge into ...
+ (location_of): ... here. Make static, return a location_t.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Adjust.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10784
+ * call.c (joust): Move warn_conversion check outwards.
+
+2003-06-27 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (build_typename_type)
+ * mangle.c (write_template_template_arg)
+ * parser.c (cp_parser_scope_through_which_access_occurs)
+ * pt.c (push_access_scope_real, push_access_scope, pop_access_scope)
+ * repo.c (get_base_filename)
+ * semantics.c (maybe_convert_cond):
+ Mark the definition static, matching the forward declaration.
+
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10468
+ * pt.c (tsubst): Handle qualified TYPEOF_TYPEs correctly.
+
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10796
+ * decl.c (finish_enum): Implement DR377.
+
+ * decl.c (cp_finish_decl): Don't make variables with reference
+ type readonly while they are being initialized.
+
+2003-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11332
+ * typeck.c (build_static_cast): Avoid returning expressions with
+ reference type.
+
+2003-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_op_delete_call): Use strip_array_call. Correct
+ error message to say 'delete' or 'delete[]'.
+
+2003-06-26 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/8266
+ * pt.c (check_explicit_specialization): When looking up a
+ template function from an identifier outside class-scope, bind
+ it to CP_DECL_CONTEXT.
+
+2003-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10990
+ * search.c (lookup_base_r): Rely on accessible_p, rather than
+ trying to emulate that logic here.
+
+ PR c++/10931
+ * call.c (convert_like): Pass issue_conversion_warnings.
+ (convert_like_with_context): Likewise.
+ (convert_like_real): Add issue_conversion_warnings parameter.
+ (perform_direct_initialization_if_possible): New function.
+ * cp-tree.h (perform_direct_initialization_if_possible): Declare it.
+ * typeck.c (check_for_casting_away_constness): New function.
+ (build_static_cast): Rewrite.
+
+2003-06-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (enforce_access): Assert we get a binfo.
+ (build_op_delete_call): Pass a binfo to
+ perform_or_defer_access_check.
+ * class.c (alter_access): Likewise.
+ * decl.c (make_typename_type): Likewise.
+ (make_unbound_class_template): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * parser.c (cp_parser_lookup_name): Likewise.
+ * search.c (lookup_member): Likewise. Move IDENTIFIER_CLASS_VALUE
+ test.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ (perform_or_defer_access_check): Expect a binfo.
+ * typeck.c (comptypes): Expect types.
+
+ * mangle.c (find_substitution): Don't pass a non-type to same_type_p
+ * friend.c (make_friend_class): Likewise.
+ * pt.c (check_default_tmpl_args): Likewise.
+ (lookup_template_class): Likewise.
+
+2003-06-24 Jan Hubicka <jh@suse.cz>
+
+ * method.c (thunk_labelno): Move outside ifdef block to make garbage
+ collector happy.
+
+2003-06-24 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtable): Make vtables.
+ * cp-tree.h (DECL_VTABLE_OR_VTT_P): New macro.
+ * decl2.c (output_vtable_inherit): Rename to ...
+ (prepare_assemble_variable): ... this one; change interface.
+ (maybe_emit_vtables): Do not call output_vtable_inherit.
+ * cp-lang.c (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): Define.
+ * cp-tree.h (prepare_assemble_variable): New.
+
+2003-06-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * method.c: add prototype for make_alias_for_thunk.
+ (thunk_labelno, make_alias_for_thunk): only define
+ if ASM_OUTPUT_DEF is defined.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (thunk_labelno): New variable.
+ (make_alias_for_thunk): New function.
+ (use_thunk): Use it if defined ASM_OUTPUT_DEF. Put the thunk
+ into the same section as the function it is calling.
+ Include gt-cp-method.h.
+ * Make-lang.in (gt-cp-method.h): Depend on s-gtype.
+ (cp/method.o): Depend on gt-cp-method.h.
+ * config-lang.in (gtfiles): Add $(srcdir)/cp/method.c.
+
+2003-06-23 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (register_dtor_fn): Mark cleanup as used.
+ * decl2.c (mark_vtable_entries): Skip nops.
+ * rtti.c (get_tinfo_ptr): Mark tinfo as used.
+ (build_dynamic_cast_1): Likewise.
+ (tinfo_base_init): Likewise.
+ (emit_tinfo_decl): Likewise.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (hash_type): Val is the TREE_LIST itself, not a pointer
+ to it.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10784
+ * call.c (joust): Warn about choosing conversion sequence only if
+ -Wconversion.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10864
+ * call.c (op_error): Tidy.
+ * error.c (dump_expr): Properly format 'T()' when T is an
+ aggregate type.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10915
+ * decl.c (grok_op_properties): Warn possible confusing conversion
+ only if -Wconversion.
+
+2003-06-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10749
+ * parser.c (cp_parser_class_head): See through dependent names
+ when parsing a class-head.
+
+ PR c++/10845
+ * pt.c (try_class_unification): Correct handling of member class
+ templates.
+
+2003-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (genrtl_finish_function): Adjust
+ expand_function_end call.
+
+2003-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10939
+ * pt.c (tsubst_decl): Do not try to substitute into non-dependent
+ functions.
+ (value_dependent_expression_p): Correct logic for FUNCTION_DECLs.
+
+ PR c++/9649
+ * cp-tree.h (pushdecl_class_level): Change prototype.
+ (push_class_level_binding): Likewise.
+ * decl.c (add_binding): Reject duplicate static data members.
+ (pushdecl_class_level): Return a value indicating whether or not
+ the binding was valid.
+ (push_class_level_binding): Likewise.
+ * semantics.c (finish_member_declaration): Don't keep invalid
+ declarations.
+
+ PR c++/11041
+ * call.c (initialize_reference): Do not use cp_finish_decl to emit
+ temporary variables.
+ * cp-tree.h (static_aggregates): Declare.
+ (pushdecl_top_level_and_finish): Likewise.
+ * decl.c (pushdecl_top_level_1): New function.
+ (pushdecl_top_level): Use it.
+ (pushdecl_top_level_and_finish): New function.
+ (initialize_local_var): Remove redundant code.
+ (cp_finish_decl): Remove support for RESULT_DECLs. Don't check
+ building_stmt_tree.
+ * decl.h (static_aggregates): Remove.
+ * decl2.c (get_guard): Use pushdecl_top_level_and_finish.
+ * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
+ (tinfo_base_init): Likewise.
+
+2003-06-19 Matt Austern <austern@apple.com>
+
+ PR c++/11228
+ * init.c (build_zero_init): Assert that number of array elements
+ is an integer constant.
+ (build_default_init) Don't use build_zero_init for arrays with
+ variable number of elements.
+
+2003-06-19 Andreas Jaeger <aj@suse.de>
+
+ * cp-tree.h: Remove duplicated declarations.
+
+2003-06-18 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * pt.c: Convert to ISO C.
+ * semantics.c: Convert to ISO C.
+
+2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (comp_except_specs, compparms, cp_has_mutable_p,
+ at_least_as_qualified_p, more_qualified_p): Return bool.
+ * typeck.c: ANSIFY function definitions.
+ (comp_array_types): Take redeclaration bool parameter.
+ (comptypes): Rearrange STRICT handling.
+ (at_least_as_qualified_p, more_qualified_p,
+ comp_cv_qualification): Cache cv quals.
+ (compparms): Rearrange loop.
+
+2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (COMPARE_RELAXED): Rename to ...
+ (COMPARE_DERIVED): ... here. Adjust comment.
+ (resolve_typename_type_in_current_instantiation): Remove.
+ (cp_tree_equal, comptypes): Return a bool.
+ * cvt.c (convert_to_reference): Adjust comptypes call.
+ * pt.c (template_args_equal, unify,): Adjust cp_tree_equal call.
+ (resolve_typename_type_in_current_instantiation): Remove.
+ * tree.c (cp_tree_equal): Return bool. Cope with TEMPLATE_DECLs and
+ IDENTIFIER_NODEs. Abort if undeciderable. Adjust recursive
+ calls. Refactor code.
+ * typeck.c (comp_array_types): Return bool. Lose callback.
+ parameter. Adjust cp_tree_equal calls.
+ (comptypes): Return bool. Adjust strict handling. Remove relaxed
+ enumeration and java type handling. Deal with typename types here.
+ Adjust recursive and cp_tree_equals calls. Adjust base and derived
+ checking.
+ (comp_target_types): Remove unreachable code. Adjust
+ same_or_base_type_p calls.
+ (ptr_reasonably_similar): Adjust base and derived check.
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Remove
+ unused calculation.
+ (check_return_expr): Adjust error messages.
+ * cp-tree.def (SCOPE_REF): Correct comment.
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
+ string again.
+
+2003-06-17 Robert Abeles <rabeles@archaelogic.com>
+
+ * optimize.c (dump_function): Form complete flag name by
+ prefixing 'fdump-' to string returned by dump_flag_name().
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
+ string.
+
+2003-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10929
+ * decl.c (grokfndecl): Don't mark a function inline for
+ -finline-functions if it isn't defined.
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10712
+ * class.c (handle_using_decl): Robustify.
+
+ PR c++/11105
+ * cp-tree.h (DECL_CONV_FN_TYPE): New method.
+ * mangle.c (struct globals): Remove internal_mangling_p.
+ (write_unqualified_name): Use DECL_CONV_FN_TYPE.
+ (write_template_parm): Don't write out the level number.
+ (conv_type_names): New variable.
+ (hash_type): New function.
+ (compare_type): Likewise.
+ (mangle_conv_op_name_for_type): Don't try to mangle conversion
+ operator names.
+ * search.c (lookup_conversion_operator): New function.
+ (lookup_fnfields_1): Use it.
+
+2003-06-17 Andreas Jaeger <aj@suse.de>
+
+ * except.c: Remove duplicate declaration of push_eh_cleanup.
+
+ * call.c: Remove extra declaration of inhibit_warnings.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ 2003-06-16 Jens-Michael Hoffmann <jensmh@gmx.de>
+ * mangle.c: Convert to ISO C.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp/decl.c, cp/pt.c, cp/search.c, cp/tree.c: Don't use the PTR
+ macro.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * tree.c: Convert to ISO C.
+
+2003-06-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Follow spelling conventions.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * parser.c: Likewise.
+
+2003-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (start_function): Adjust init_function_start call.
+ * method.c (use_thunk): Likewise.
+ * semantics.c (genrtl_start_function): Likewise.
+
+2003-06-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Remove c-options.o.
+
+2003-06-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * lex.c: Convert to ISO C.
+
+ 2003-05-19 Jens-Michael Hoffmann <jensmh@gmx.de>
+ * init.c: removes use of PARAMS macro. Use ISO style function
+ declarations. (Not copyright-significant change.)
+
+ * rtti.c: Remove PARAMS.
+
+ * typeck2.c: Convert to ISO C.
+
+2003-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10635
+ * typeck.c (build_c_cast): Check that the destination type is
+ complete.
+
+2003-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10432
+ * cp-tree.h (finish_declarator): Remove.
+ * decl.c (cp_finish_decl): Make sure to pop_nested_class even for
+ erroneous declarations.
+ * semantics.c (finish_declarator): Remove.
+
+2003-06-11 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (generate_ctor_or_dtor_function): Avoid expanding a
+ global static constructor/destructor if it will be empty, i.e.
+ either doesn't call any ctors/dtors or only calls pure or const
+ ctors/dtors.
+
+2003-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (tm_p.h): Include it.
+ * Make-lang.in (cp/mangle.o): Depend on $(TM_P_H).
+
+ PR c++/11131
+ * tree.c (cp_cannot_inline_fn): Check for "inline" before
+ instantiation.
+
+2003-06-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/10968
+ * pt.c (mark_decl_instantiated): Clear DECL_COMDAT.
+
+2003-06-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c (start_cleanup_fn): Move static 'counter' out, mark with GTY.
+ (start_cleanup_cnt): New.
+
+2003-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11131
+ * cp-tree.h (template_for_substitution): Declare.
+ * decl2.c (mark_used): Use it when figuring out whether or not a
+ function is inline.
+ * pt.c (template_for_substitution): Give it external linkage.
+ * tree.c (cp_cannot_inline_tree_fn): Instantiate as early as
+ possible.
+
+2003-06-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR 8861
+ * mangle.c (write_real_cst): New function. Implement
+ ABI-compliant mangling of floating-point literals when
+ -fabi-version>=2; provide backward compatibility with 3.3 when
+ -fabi-version=1 (with warning). Clarify commentary.
+ (write_template_arg_literal): Use write_real_cst.
+
+2003-06-07 Andreas Jaeger <aj@suse.de>
+
+ * cp/decl.c (xref_tag): Remove undefined macro NONNESTED_CLASSES.
+
+2003-06-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_DECODE_OPTON): Drop.
+ (LANG_HOOKS_HANDLE_OPTION): Override.
+ * cp-tree.h (cxx_init_options): Update.
+ * lex.c (cxx_init_options): Update.
+
+2003-06-05 Jan Hubicka <jh@suse.cz>
+
+ * Make-lang.in: Add support for stageprofile and stagefeedback
+
+2003-06-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * decl.c (grokdeclarator): Error_mark_node in, error_mark_node out.
+
+2003-06-04 Andreas Jaeger <aj@suse.de>
+
+ * g++spec.c (lang_specific_driver): Remove ALT_LIBM usage.
+
+2003-06-03 Jason Merrill <jason@redhat.com>
+
+ * cp/cp-tree.h (CP_AGGREGATE_TYPE_P): Accept vectors.
+
+ * cp/decl.c (reshape_init): Handle vectors.
+
+ * testsuite/g++.dg/init/array10.C: New.
+
+2003-06-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10940
+ * pt.c (check_explicit_specialization): Check for 'static'
+ earlier.
+
+2003-05-31 Diego Novillo <dnovillo@redhat.com>
+
+ * class.c (dump_array): Call CONSTRUCTOR_ELTS to access
+ the operand of a CONSTRUCTOR node.
+
+2003-05-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (cp_binding_level::this_entity): Rename from this_class.
+ (cxx_scope_descriptor): New function.
+ (cxx_scope_debug): Likewise.
+ (push_binding_level): Use it.
+ (pop_binding_level): Likewise.
+ (suspend_binding_level): Likewise.
+ (resume_binding_level): Likewise.
+ (pushlevel_class): Adjust use of this_class.
+ (pushtag): Likewise.
+ (lookup_name_real): Likewise.
+ (global_scope_name): New variable.
+ (initialize_predefined_identifiers): Initialize it.
+ (push_namespace): Use it.
+ (make_cxx_scope): New function.
+ (pushlevel): Use it.
+ (pushlevel_class): Likewise.
+ (push_binding_level): Simplify. Loose the last two arguments.
+ (make_binding_level): Remove.
+ (initial_push__namespace_scope): New function.
+ (push_namespace): Use it. Simplify.
+ (cxx_init_decl_processing): Likewise.
+ (declare_namespace_level): Remove.
+
+2003-05-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10956
+ * pt.c (instantiate_decl): Don't use full template arguments if
+ we are dealing with specializations.
+
+2003-05-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (ENABLE_SCOPE_CHECKING): Rename from DEBUG_BINDING_LEVELS.
+ (binding_depth): Unconditionally define.
+ (is_class_level): Likewise.
+ (indent): Likewise. Take an indenting parameter.
+ (push_binding_level): Remove conditional definittion.
+ (pop_binding_level): Likewise.
+ (suspend_binding_level): Likewise.
+ (resume_binding_level): Likewise.
+ (pushlevel): Likewise.
+ (pushlevel_class): Likewise.
+ (poplevel_class): Likewise.
+ (pop_everything): Likewise.
+
+2003-05-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (global_scope_p): New macro.
+ * decl.c (pop_binding_level): Use it. Don't refer directly to
+ global_binding_level.
+ (suspend_binding_level): Likewise.
+ (global_bindings_p): Likewise.
+ (print_other_binding_stack): Likewise.
+ (print_binding_stack): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (cxx_init_decl_processing): Likewise.
+ (start_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (start_function): Likewise.
+ (global_binding_level): Remove.
+
+2003-05-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * parser.c (cp_parser_explicit_instantiation): Restore old
+ access before template instantiation.
+
+2003-05-23 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h: Use -o to specify preprocessor's output file.
+ Make -no-integrated-cpp work when building PCH files.
+
+2003-05-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10682
+ * pt.c (instantiate_class_template): Use DECL_ARTIFICIAL to
+ check for implicitly created typedef to an enum.
+
+2003-05-21 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_vec_delete): Copy the address into a temporary
+ variable before calling build_vec_delete_1.
+ * decl2.c (delete_sanity): Don't call stabilize_reference.
+
+2003-05-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (register_specialization): Update the decl's location,
+ if necessary.
+ (check_explicit_specialization): Likewise.
+
+2003-05-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (dump_expr): Use HOST_WIDE_INT_PRINT_DOUBLE_HEX.
+
+2003-05-21 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/9738
+ * decl.c (duplicate_decls): Re-invoke make_decl_rtl
+ if the old decl had instantiated DECL_RTL.
+ (Base on Richard Henderson 2003-05-13 patch to c-decl.c).
+
+2003-05-19 Matt Austern <austern@apple.com>
+
+ * lang-options.h: Document -Wno-invalid-offsetof
+ * typeck.c (build_class_member_access_expr): Don't complain about
+ (Foo *)p->x for non-POD Foo if warn_invalid_offset is zero.
+
+2003-05-18 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * name-lookup.c (free_binding_entry): fix where the GTY markers are.
+ (binding_entry_make): Make entry->chain NULL after getting an entry.
+ fix the spelling of chain in a comment.
+ (binding_table_free): speed up by having temporary variable.
+ (binding_table_new): set table->chain to be NULL after allocating
+ a table.
+ (cxx_binding_make): use gcc_alloc instead of ggc_alloc_cleared and set
+ binding->previous to NULL after getting an binding for speed.
+
+2003-05-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (struct lang_type_class): Replace data member tags
+ with hash-table nested_udts.
+ (CLASSTYPE_NESTED_UTDS): Rename from CLASSTYPE_TAGS.
+ * class.c (unreverse_member_declarations): Don't touch
+ CLASSTYPE_TAGS.
+ (pushclass): Use cxx_remember_type_decls.
+ * decl.c (struct cp_binding_level): Replace data member tags with
+ hash-table type_decls.
+ (pop_binding_level): Handle level->type_decls.
+ (kept_level_p): Adjust.
+ (poplevel): Remove unused local variable.
+ (bt_print_entry): New function.
+ (print_binding_level): Use it.
+ (push_namespace): Build current_binding_level->type_decls.
+ (maybe_process_template_type_declaration): Adjust.
+ (pushtag): Likewise.
+ (clear_anon_tags): Use binding_table_remove_anonymous_types.
+ (gettags): Remove.
+ (cxx_remember_type_decls): Rename from storetags. Adjust.
+ (lookup_tag): Use binding_table_find_anon_type. Tidy.
+ (lookup_tag_reverse): Use binding_table_reverse_maybe_remap.
+ (cxx_init_decl_processing): Build global_binding_level->type_decls.
+ (store_parm_decls): Remove pointless code.
+ * name-lookup.c (free_binding_entry): New variable.
+ (ENTRY_INDEX): New macro.
+ (struct binding_table_s): New datatype.
+ (binding_entry_make): New function.
+ (binding_entry_free): Likewise.
+ (binding_table_construct): Likewise.
+ (binding_table_free): Likewise.
+ (binding_table_new): Likewise.
+ (binding_table_expand): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (binding_table_remove_anonymous_types): Likewise.
+ (binding_table_foreach): Likewise.
+ * name-lookup.h (binding_table): New type.
+ (binding_entry): Likewise.
+ (bt_foreach_proc): Likewise.
+ (struct binding_entry_s): New datatype.
+ (SCOPE_DEFAULT_HT_SIZE): New macro.
+ (CLASS_SCOPE_HT_SIZE): Likewise.
+ (NAMESPACE_ORDINARY_HT_SIZE): Likewise.
+ (NAMESPACE_STD_HT_SIZE): Likewise.
+ (GLOBAL_SCOPE_HT_SIZE): Likewise.
+ (binding_table_new): Declare.
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (binding_table_remove_anonymous_types): Likewise.
+ (binding_table_foreach): Likewise.
+ (binding_table_find): Likewise.
+ (cxx_remember_type_decls): Likewise.
+ * pt.c (bt_instantiate_type_proc): New function.
+ (do_type_instantiation): Use it.
+ * search.c (lookup_field_r): Use binding_table_find.
+
+2003-05-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * semantics.c (perform_deferred_access_checks): Don't discard
+ checked access.
+
+2003-05-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (cp_error_at, cp_warning_at, cp_pedwarn_at): Eliminate
+ libiberty VA_ macros, always use stdarg.
+ * rtti.c (create_pseudo_type_info): Likewise.
+ * tree.c (build_min_nt, build_min): Likewise.
+
+2003-05-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ptree.c (cxx_print_type, cxx_print_xnode): Use string
+ concatentation on HOST_WIDE_INT_PRINT_* format specifier to
+ collapse multiple function calls into one.
+ * tree.c (debug_binfo): Likewise.
+
+2003-05-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/5388
+ * call.c (conditional_conversion): Don't consider implicit
+ conversions if T2 is a base of T1.
+ * cp-tree.h (DERIVED_FROM_P, UNIQUELY_DERIVED_FROM_P): Make boolean.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P, PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+
+ * parser.c (cp_parser_primary_expression): Convert a static data
+ member from reference.
+
+2003-05-15 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Avoid creating unnecessary types.
+ * class.c (instantiate_type): Remove tests for tf_no_attributes.
+ * cp-tree.h (tsubst_flags_t): Remove tf_no_attributes.
+ (COMPARE_NO_ATTRIBUTES): Remove.
+ * typeck.c (comptypes): Do not check COMPARE_NO_ATTRIBUTES.
+
+ PR c++/8385
+ * semantics.c (finish_typeof): Refine type-dependency check.
+
+2003-05-13 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_modify_expr): Don't always stabilize the lhs and
+ rhs. Do stabilize the lhs of a MODIFY_EXPR used on the lhs.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * method.c (synthesize_method): Call push/pop_deferring_access_checks.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10230, c++/10481
+ * semantics.c (finish_non_static_data_member): Handle when the
+ non-static member is not from a base of the current class type.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10552
+ * pt.c (tsubst_copy): Handle TEMPLATE_DECL that is a member class
+ template and has dependent context.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (instantiate_decl): Call push/pop_deferring_access_checks.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9252
+ * cp-tree.h (saved_scope): Remove check_access field.
+ (tsubst_flags_t): Remove tf_parsing.
+ * decl.c (maybe_push_to_top_level): Don't initialize
+ scope_chain->check_access.
+ (make_typename_type, make_unbound_class_template): Don't use
+ tf_parsing.
+ (register_dtor_fn): Use push/pop_deferring_access_checks
+ instead of scope_chain->check_access.
+ * method.c (use_thunk): Likewise.
+ * parser.c (cp_parser_explicit_instantiation
+ (cp_parser_constructor_declarator_p): Don't call
+ push/pop_deferring_access_checks here.
+ (cp_parser_template_argument, cp_parser_class_name): Don't use
+ tf_parsing.
+ (yyparse): Check flag_access_control.
+ * pt.c (instantiate_class_template): Call
+ push/pop_deferring_access_checks.
+ * semantics.c (push_deferring_access_checks): Propagate
+ dk_no_check.
+ (perform_or_defer_access_check): Make sure basetype_path is
+ a type before comparison.
+ * call.c (build_op_delete_call, build_over_call): Use
+ perform_or_defer_access_check.
+ * class.c (alter_access): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * search.c (lookup_member): Likewise.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ (simplify_aggr_init_exprs_r): Use push/pop_deferring_access_checks
+ instead of flag_access_control.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9554
+ * parser.c (cp_parser_class_name): Remove check_access parameter.
+ All caller adjusted. Update declaration.
+ (cp_parser_lookup_name): Likewise.
+ * semantics.c (push_deferring_access_checks): Change parameter type
+ to enum deferring_kind. All caller adjusted.
+ (resume_deferring_access_checks): Adjust to use new enum.
+ (stop_deferring_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ * cp-tree.h (deferring_kind): New enum.
+ (deferred_access): Adjust field type.
+ (push_deferring_access_checks): Update declaration.
+
+2003-05-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10555, c++/10576
+ * pt.c (lookup_template_class): Handle class template with
+ multiple levels of parameters when one of the levels contain
+ errors.
+
+2003-05-08 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Don't reuse a TARGET_EXPR in an
+ expression. Undo some of the recent reorg.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ PR c++/10570
+ * cfns.gperf: Comment out POSIX thread cancellation points,
+ plus abort and raise.
+ * cfns.h: Regenerate.
+
+2003-05-07 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Don't assume that the folded
+ expression has result_type.
+
+2003-05-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck.c (build_unary_op): Deal with const qualifier in
+ invalid pointer-to-member earlier.
+
+2003-05-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/9537
+ * call.c (conditional_conversion): Build an RVALUE_CONV if
+ we're just changing the cv-quals.
+ (build_conditional_expr): Don't call convert to change
+ cv-quals.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10496
+ * typeck.c (build_unary_op): Don't output const qualifier when
+ output invalid pointer-to-member diagnostics.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c: Fix typos.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4494
+ * decl.c (start_function): Use same_type_p to check return type
+ of main.
+
+2003-05-03 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/10604
+ * cp/typeck.c (build_x_compound_expr): No need to check
+ extra_warnings as well as warn_unused_value.
+
+2003-05-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9364, c++/10553, c++/10586
+ * decl.c (make_typename_type): Don't crash on illegal code.
+
+2003-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct): Use location_t and input_location
+ directly.
+ * decl.c (make_label_decl): Likewise.
+ (use_label): Likewise.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+ (start_static_initialization_or_destruction): Likewise.
+ (generate_ctor_or_dtor_function): Likewise.
+ (finish_file): Likewise.
+ * error.c (print_instantiation_full_context): Likewise.
+ * init.c (create_temporary_var): Likewise.
+ * method.c (synthesize_method): Likewise.
+ * parser.c (cp_token): Likewise.
+ (cp_lexer_set_source_position_from_token): Likewise.
+ (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_parser_statement): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst): Likewise.
+ (instantiate_decl): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ (expand_body): Likewise.
+
+2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct): Rename lineno to input_line.
+ * decl.c (push_binding_level, pop_binding_level,
+ suspend_binding_level, resume_binding_level, make_label_decl,
+ use_label, start_function): Likewise.
+ * decl2.c (warn_if_unknown_interface,
+ start_static_initialization_or_destruction,
+ generate_ctor_or_dtor_function, finish_file): Likewise.
+ * error.c (cp_line_of, print_instantiation_full_context,
+ print_instantiation_context): Likewise.
+ * except.c (check_handlers_1, check_handlers): Likewise.
+ * init.c (create_temporary_var): Likewise.
+ * method.c (use_thunk, synthesize_method): Likewise.
+ * parser.c (cp_lexer_set_source_position_from_token,
+ cp_lexer_get_preprocessor_token): Likewise.
+ * pt.c (push_tinst_level, pop_tinst_level,
+ tsubst_friend_function, instantiate_class_template, tsubst_decl,
+ tsubst, tsubst_expr, instantiate_decl): Likewise.
+ * semantics.c (genrtl_try_block, finish_label_stmt,
+ begin_class_definition, expand_body,
+ genrtl_finish_function): Likewise.
+ * tree.c (build_min_nt, build_min): Likewise.
+
+2003-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (comdat_linkage): Don't externalize explicit
+ instantiations.
+
+2003-05-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10554
+ * decl2.c (do_class_using_decl): Check if operand 0 of SCOPE_REF
+ is not NULL.
+
+2003-05-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (struct lang_id2): Remove. Move fields from here...
+ (struct lang_identifier): ... to here.
+ (LANG_ID_FIELD): Remove.
+ (SET_LANG_ID): Remove.
+ (IDENTIFIER_LABEL_VALUE): Adjust for new lang_identifier.
+ (SET_IDENTIFIER_LABEL_VALUE): Likewise.
+ (IDENTIFIER_IMPLICIT_DECL): Likewise.
+ (SET_IDENTIFIERL_IMPLICIT_DECL): Likewise.
+ (IDENTIFIER_ERROR_LOCUS): Likewise.
+ (SET_IDENTIFIER_ERROR_LOCUS): Likewise.
+
+2003-05-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8772
+ * pt.c (convert_template_argument): Correct diagnostic.
+
+2003-04-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9432, c++/9528
+ * decl2.c (validate_nonmember_using_decl): Handle SCOPE_REF.
+
+2003-04-30 Garbiel Dos Reis <gcc@integrable-solutions.net>
+
+ * decl.c (check_previous_goto_1): Adjust prototype.
+ (check_previous_goto): Adjust use.
+ (check_switch_goto): Likewise.
+ (use_label): Adjust.
+ (check_previous_goto_1): Don't use pedwarn_with_file_and_line.
+ (struct named_label_use_list): Use location_t datatype.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10551
+ * pt.c (mark_decl_instantiated): Defer all explicit instantiations
+ that have not yet been written out.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10549
+ * class.c (layout_class_type): Mark overlong bitfields as having
+ the maximum size permitted by their type, after layout.
+
+ PR c++/10527
+ * error.c (dump_expr): Correctly handling of NEW_EXPR.4
+
+2003-04-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * call.c (build_operator_new_call): Fix typo.
+ * lang-options.h: Likewise.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10515
+ * cp-tree.h (lookup_field_1): Declare it.
+ * search.c (lookup_field_1): Make it public.
+ * decl.c (reshape_init): Handle designated initializers.
+
+ * decl.c (maybe_commonize_var): Further tweak support for systems
+ without weak symbols.
+
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (maybe_commonize_var): Fix thinko in last patch.
+
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10506
+ * method.c (use_thunk): Decrement immediate_size_expand.
+
+ PR c++/10503
+ * cp-tree.h (DECL_VAR_MARKED_P): New macro.
+ (DECL_MAYBE_TEMPLATE): Remove.
+ * class.c (fixed_type_or_null): Avoid infinite recursion.
+
+ * decl.c (maybe_commonize_var): Make the code match the comments.
+ * pt.c (instantiate_decl): Move call to import_export_decl.
+
+2003-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Fix merge botch.
+
+2003-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Don't call import_export_decl for
+ functions that are not defined.
+ (handle_class_head): Robustify.
+ * pt.c (instantiate_decl): Do not call cp_finish_decl for
+ variables that are not defined.
+
+2003-04-24 Sylvain Pion <Sylvain.Pion@mpi-sb.mpg.de>
+
+ * call.c (print_z_candidates): Fix off by one error.
+
+2003-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10337
+ * call.c (joust): Don't warn about conversion ops that are exact
+ or cv-conversions. Rearrange to avoid multiple type comparisons.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10471
+ * call.c (build_cxx_call): Robustify.
+
+2003-04-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (lex.o): Remove mbchar.h.
+ * lex.c (MULTIBYTE_CHARS): Lose.
+ * parser.c (cp_lexer_get_preprocessor_token): CPP_OTHER handled
+ in c-lex.c.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9847
+ * cp-tree.h (duplicate_tag_error): Remove.
+ * class.c (duplicate_tag_error): Remove.
+ * semantics.c (begin_class_definition): Return immediately for a
+ duplicate class definition.
+
+ PR c++/10451
+ * decl.c (grokdeclarator): Correct logic for "mutable" errors.
+
+2003-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10446
+ * search.c (lookup_fnfields_1): Handle empty slots in the method
+ vector.
+
+ PR c++/10428
+ * decl.c (check_elaborated_type_specifier): New function, split
+ out from ...
+ (xref_tag): ... here. Use the new function in more places.
+
+ * rtti.c (throw_bad_typeid): Use build_cxx_call.
+
+2003-04-21 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Use build_cxx_call.
+ (build_cxx_call): New method, split out of build_over_call.
+ * cp-tree.h (language_function): Add can_throw.
+ (build_cxx_call): Declare it.
+ * decl.c (finish_function): If a function does not contain any
+ calls to functions that can throw an exception, indicate that
+ fact.
+ * decl2.c (mark_used): Do not defer the instantiation of
+ functions, if the current function does not throw.
+ * optimize.c (maybe_clone_body): Copy TREE_NOTHROW to the clones.
+ * pt.c (instantiate_decl): Make sure import_export_decl is called
+ before emitting things.
+ * rtti.c (throw_bad_cast): Use build_cxx_call.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (build_function_call): Likewise.
+
+2003-04-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9881
+ * typeck.c (build_unary_op): Fold all COMPONENT_REF addr
+ expressions. Reverts my 2002-08-08 patch.
+
+ * typeck.c (comp_ptr_ttypes_real): Swap final && operands for
+ cheaper early exit.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp/decl2.c (start_static_storage_duration_function): Take count
+ arg, don't check if it wraps round.
+ (generate_ctor_or_dtor_function): Add locus arg, use it.
+ (generate_ctor_and_dtor_functions_for_priority): Data arg is a
+ locus.
+ (finish_file): Set line numbers to past EOF for synthesized
+ functions.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10405
+ * search.c (lookup_field_1): Final scan goes backwards for
+ types, forwards for non-types.
+
+2003-04-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c/10375
+ * decl.c (duplicate_decls): Preserve "const", "noreturn" and
+ "nothrow" function attributes.
+
+2003-04-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10347
+ * pt.c (type_dependent_expression_p): Handle array new.
+
+2003-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10381
+ * parser.c (cp_parser_primary_expression): Reorganize logic for
+ dealing with name lookup failures.
+
+2003-04-15 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (mark_used): Don't instantiate anything if
+ skip_evaluation.
+
+2003-04-14 Ziemowit Laski <zlaski@apple.com>
+
+ * tree.c (build_cplus_array_type_1): Do not call
+ uses_template_parms() on a NULL index_type.
+
+2003-04-13 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (duplicate_decls): Preserve pure and malloc attributes.
+
+2003-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10300
+ * init.c (build_new_1): Reorganize.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * class.c (initialize_array)
+ * decl.c (reshape_init)
+ * decl2.c (build_expr_from_tree)
+ * init.c (build_zero_init)
+ * pt.c (tsubst_copy, tsubst_copy_and_build)
+ * rtti.c (tinfo_base_init, generic_initializer, ptr_initializer)
+ (ptm_initializer, class_initializer, get_pseudo_ti_init)
+ * semantics.c (finish_compound_literal)
+ * typeck.c (build_ptrmemfunc1)
+ * typeck2.c (store_init_value, process_init_constructor)
+ (build_functional_cast): Use build_constructor.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c (print_z_candidates): Use gcc_gettext_width, not
+ strlen, to determine how much padding to use.
+
+2003-04-10 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c: Update all calls to shadow_warning.
+
+2003-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Correct handling for overlong
+ bit-fields whose width is the same as an integer type.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.def: Make fourth element for all 'c' and 'x' nodes zero.
+ * cp-lang.c (cp_tree_size): New function.
+ (LANG_HOOKS_TREE_SIZE): Override.
+
+ * cp-tree.h (SOURCE_LOCUS, SRCLOC_FILE, SRCLOC_LINE, struct
+ tree_srcloc, TS_CP_COMMON, TS_CP_SRCLOC): Kill.
+ (union lang_tree_node): Remove common and srcloc members.
+ (build_srcloc_here): Don't prototype.
+ * decl.c (cp_tree_node_structure): Kill SRCLOC case.
+ * pt.c (pending_templates): Correct comment.
+ * tree.c (build_srcloc, build_srcloc_here): Kill.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c: Include intl.h.
+ (print_z_candidate): Always use inform; get rid of errfn
+ argument. Reorganize so that all the strings get picked up
+ by xgettext. Note obligation of caller to pass first argument
+ through gettext.
+ (print_z_candidates): Update to match. Indent second and
+ successive candidates by strlen() of translated message.
+ (joust): Restructure ambiguous-conversion pedwarn so that
+ translators see a complete sentence. Update calls to
+ print_z_candidate.
+
+ * Make-lang.in (cp/call.o): Update dependencies.
+
+2003-04-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (set_current_binding_level): Delete, revert last change.
+ (current_binding_level): Modify to allow it as as lvalue.
+
+2003-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * name-lookup.c (find_binding): Pass appropriate pointer type to
+ POP_TIMEVAR_AND_RETURN.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp-warn): Add $(STRICT_WARN).
+ * cp-tree.h: Don't insist on having GNUC.
+
+2003-04-03 Jason Merrill <jason@redhat.com>
+
+ * cvt.c (ocp_convert): Only abort if we try to convert an object
+ of TREE_ADDRESSABLE type.
+
+ * class.c (build_vtable): Set DECL_ALIGN here.
+ (get_vtable_decl): Not here.
+ (layout_vtable_decl): Or here.
+ (create_vtable_ptr): Or here.
+ (layout_class_type): Or here.
+ (check_bitfield_decl): Don't mess with field alignment.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * operators.def (DEF_SIMPLE_OPERATOR, DEF_ASSN_OPERATOR,
+ DEF_ASSN_OPERATOR): Delete spurious semi-colon.
+ * rtti.c (dfs_class_hint_mark): Likewise.
+
+ * decl.c (push_local_name, push_class_level_binding,
+ maybe_inject_for_scope_var): Don't use POP_TIMEVAR_AND_RETURN in
+ functions returning void.
+ * decl2.c (add_using_namespace): Likewise.
+
+ * decl.c (print_binding_level, print_other_binding_stack,
+ print_binding_stack): Cast argument of %p specifier to void*.
+ * ptree.c (cxx_print_decl): Likewise.
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK,
+ VAR_FUNCTION_OR_PARM_DECL_CHECK,
+ VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK, RECORD_OR_UNION_TYPE_CHECK,
+ BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK, LANG_TYPE_CLASS_CHECK,
+ LANG_TYPE_PTRMEM_CHECK, LANG_DECL_U2_CHECK): Add __extension__.
+
+ * decl.c (set_current_binding_level): New macro. Use throughout
+ when setting the current binding level.
+
+ * cp-tree.h (cp_lvalue_kind, base_access): Delete trailing comma
+ in enum.
+ * method.c (mangling_flags): Likewise.
+
+ * cp-tree.h (lang_type_header): Add __extension__ and use
+ CHAR_BITFIELD for members.
+
+2003-04-02 Geoffrey Keating <geoffk@apple.com>
+
+ PR other/9274
+ * mangle.c: Include gt-cp-mangle.h.
+ (subst_identifiers): Mark with GTY.
+ * config-lang.in (gtfiles): Add cp/mangle.c.
+ * Make-lang.in: (gt-cp-mangle.h): New rule.
+ (cp/mangle.o): Depends on gt-cp-mangle.h.
+
+2003-04-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config-lang.in (gtfiles): Add \$(srcdir)/cp/name-lookup.c
+ after \$(srcdir)/cp/name-lookup.h.
+ * name-lookup.c: (cxx_binding_make): Use ggc_alloc_clearedinstead
+ of ggc_alloc. Include gt-cp-name-lookup.h at the end of the file.
+ * Make-lang.in: (gt-cp-name-lookup.h): Is generated by gengtype.
+ (cp/name-lookup.o): Depends on gt-cp-name-lookup.h.
+
+2003-03-31 Jason Merrill <jason@redhat.com>
+
+ PR java/10145
+ * class.c (check_field_decl): Don't set DECL_ALIGN.
+
+2003-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7647
+ * decl.c (grokdeclarator): Tidy, slightly.
+ * search.c (lookup_field_1): Add want_type parameter.
+ (lookup_field_r): Adjust call to lookup_field_1.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp/name-lookup.o): Add more dependencies.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (binding_for_name: Move to name-lookup.h Adjust
+ prototype.
+ (cxx_scope_find_binding_for_name): Likewise.
+ * decl.c (find_binding: Move to name-lookup.c.
+ (binding_for_name): Likewise.
+ (cxx_scope_find_binding_for_name): Likewise.
+ (BINDING_LEVEL): Remove.
+ (push_binding): Tidy.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_tag): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_current_level): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (namespace_binding): Move to name-lookup.c.
+ (set_namespace_binding): Likewise.
+ * decl2.c (lookup_using_namespace): Tidy.
+ (qualified_lookup_using_namespace): Likewise.
+ (do_toplevel_using_decl): Likewise.
+ * name-lookup.c: Include "timevar.h"
+ * name-lookup.h (cxx_scope): Declare.
+ (struct cxx_binding): Lose member "has_level". Adjust "scope"
+ member declaration.
+ (BINDING_SCOPE): Adjust definition.
+ (BINDING_HAS_LEVEL_P): Remove.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.c: New file.
+ * name-lookup.h: Likewise..
+ * decl.c (push_binding): Adjust use cxx_binding_make.
+ (free_bindings): Move to name-lookup.c
+ (pop_binding): Use cxx_binding_free.
+ (binding_for_name): Tidy.
+ * cp-tree.h: Include "name-lookup.h"
+ (cxx_binding_make): Move to name-lookup.h
+ (cxx_binding_clear): Likewise.
+ (struct cxx_binding): Likewise.
+ (LOCAL_BINDING_P): Likewise.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ * config-lang.in (gtfiles): Add cp/name-lookup.h
+ * Make-lang.in (cp/name-lookup.o): New rule.
+ (CXX_OBJS): Add cp/name-lookup.o
+ (CXX_TREE_H): Add cp/name-lookup.h
+
+2003-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/10245
+ * cvt.c (force_rvalue): New fn.
+ * call.c (build_conditional_expr): Use it.
+ * cp-tree.h: Declare it.
+
+2003-03-28 Mike Stump <mrs@apple.com>
+
+ * error.c (dump_expr): Add 0x to printed hex numbers to make
+ output match source code better.
+
+2003-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10218
+ * decl.c (grokfndecl): Return NULL_TREE for bogus out-of-class
+ definitions.
+
+ * decl2.c (generate_ctor_or_dtor_function): Tolerate a
+ non-existant ssdf_decls array.
+ (finish_file): Call generator_ctor_or_dtor_function when there are
+ static constructors or destructors and no other static
+ initializations.
+
+2003-03-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10047
+ * decl2.c (finish_file): Don't warn about explicitly instantiated
+ inline decls.
+
+2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10224
+ * pt.c (lookup_template_class): Only check instantiated args if
+ they do not contain template parameters.
+
+2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10158
+ * parser.c (cp_parser_function_definition): Set
+ DECL_INITIALIZED_IN_CLASS for members.
+ * pt.c (instantiate_decl): Only reduce the template args for
+ friends that are not defined in class.
+
+2003-03-25 Jason Merrill <jason@redhat.com>
+
+ * call.c (print_z_candidate): Change name of first arg to msgid.
+ (joust): Add comment for translators.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9898, PR c++/383, DR 322
+ * pt.c (maybe_adjust_types_for_deduction) <DEDUCE_CONV>: Look
+ through reference types on both PARM and ARG.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10119
+ * error.c (dump_expr) <BASELINK>: Use dump_expr.
+ * pt.c (maybe_fold_nontype_args): New function.
+ (tsubst_copy) <SCOPE_REF>: Subst any template_id args.
+ <TEMPLATE_ID_EXPR>: Break out folding code, call it.
+ (tsubst_copy_and_build) <TEMPLATE_ID_EXPR>: Call
+ maybe_fold_nontype_args.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10026
+ * decl2.c (arg_assoc_type) <ERROR_MARK>: Don't die.
+
+2003-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7086
+ * typeck.c (cxx_mark_addressable): Adjust call to
+ gen_mem_addressof or put_var_into_stack.
+
+2003-03-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9978, c++/9708
+ * cp-tree.h (instantiate_template): Add tsubst_flags parameter.
+ * call.c (add_template_candidate_real): Adjust
+ instantiate_template call.
+ * class.c (resolve_address_of_overloaded_function): Likewise.
+ * decl.c (build_enumerator): Set TREE_CONSTANT.
+ * pt.c (check_instantiated_args): New.
+ (push_inline_template_parms_recursive): Set TREE_CONSTANT,
+ TREE_READONLY.
+ (build_template_parm_index): Copy TREE_CONSTANT, TREE_READONLY.
+ (reduce_template_parm_level): Likewise.
+ (process_template_parm): Likewise.
+ (check_explicit_specialization): Adjust instantiate_template call.
+ (convert_template_argument): Don't check non-type argument here.
+ (lookup_template_class): Check them here.
+ (tsubst_friend_function): Adjust instantiate_template call.
+ (instantiate_template): Add tsubst_flags parameter, use it. Check
+ instantiated args.
+
+2003-03-21 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c: Update calls to shadow_warning.
+
+2003-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9898
+ * error.c (dump_decl) [CONST_DECL]: Print '<enumerator>'.
+ (dump_expr) [CONSTRUCTOR]: Print default ctor as a function call.
+
+2003-03-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/decl2.c (arg_assoc_class): Correct check for namespace-scope
+ friends.
+ * cp/pt.c (instantiate_class_template): Fix formatting.
+
+2003-03-14 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (unemitted_tinfo_decls): Declaration of a new varray.
+ (unemitted_tinfo_decl_p): Remove.
+ (emit_tinfo_decl): Change declaration to remove unused parameter.
+ * decl2.c (finish_file): Change tinfo emission to loop through
+ unemitted_tinfo_decls array instead of looping through all decls.
+ * rtti.c (unemitted_tinfo_decl_p): Declare as static, remove
+ unused second parameter.
+ (init_rtti_processing): initialize unemitted_tinfo_decls varray.
+ (get_tinfo_decls): push new tinfo decl on unemitted_tinfo_decls.
+ (emit_tinfo_decl): remove unused second parameter, add assertion
+ that decl hasn't already been emitted.
+
+2003-03-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * dump.c (cp_dump_tree), cp-tree.h (cp_dump_tree): Change return
+ type from 'int' to 'bool'. Replace 0 and 1 with true and false in
+ return statements.
+
+2003-03-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/8316, c++/9315, c++/10136
+ * call.c (print_z_candidate): Split out from...
+ (print_z_candidiates): ...here.
+ (joust): Use it.
+
+2003-03-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/10031
+ * decl.c (duplicate_decls): Use the new type when prototyping
+ anticipated decls, even when the types match. This defines the
+ exception list for the built-in function.
+
+2003-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10091
+ * typeck.c (build_class_member_access_expr): Compare
+ TYPE_MAIN_VARIANTs.
+
+2003-03-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9639
+ * parser.c (cp_parser_declarator_id): Clear parser->scope.
+
+2003-03-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/9993
+ * decl.c (finish_function): Only allow the NRVO to use variables
+ declared at function scope.
+
+2003-03-17 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (cp/TAGS): Remove.
+
+2003-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9629
+ * cp-tree.h (struct language_function): Add in_base_initializer.
+ (in_base_initializer): define it.
+ (expand_member_init): Remove INIT param.
+ * init.c (expand_member_init): Remove INIT param, return the member.
+ (emit_mem_initializers): Set in_base_initializer.
+ * class.c (build_base_path): Check in_base_initializer.
+ * parser.c (cp_parser_mem_initializer): Set in_base_initializer.
+ * pt.c (tsubst_initializer_list): Likewise.
+
+2003-03-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (binding_for_name): Fix initialization thinko.
+
+2003-03-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Compile-time improvement: 2/n.
+ * cp-tree.h (struct cxx_binding): New datatype;
+ (struct lang_identifier): Use it.
+ (LOCAL_BINDING_P): Adjust definition.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ (IDENTIFIER_VALUE): Likewise.
+ (struct tree_binding): Remove.
+ (TS_CP_BINDING): Likewise.
+ ((union lang_tree_node): Remove field "binding".
+ (cxx_binding_clear): New macro.
+ (binding_for_name): Adjust return type.
+ (qualified_lookup_using_namespace): Adjust prototype.
+ (lookup_using_namespace): Adjust prototype.
+ (cxx_scope_find_binding_for_name): Declare.
+ * cp-tree.def: Remove CPLUS_BINDING definition.
+ * decl.c (push_binding): Adjust local variable type.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (free_bindings): Adjust type.
+ (find_binding): Adjust return type, add a third parameter. Remove
+ non-useful assertion now that we use static typing.
+ (cxx_scope_find_binding_for_name): New function.
+ (binding_for_name): Use it. Adjust local variable type. Simplify.
+ (namespace_binding): Simplify.
+ (set_namespace_binding): Likewise.
+ (set_identifier_type_value_with_scope): Adjust local variable type.
+ (lookup_tag): Don't type-abuse of local variable 'old'.
+ (lookup_namespace_name): Likewise. Allocate binding on stack.
+ (select_decl): Adjust prototype.
+ (unqualified_namespace_lookup): Allocate binding on stack.
+ Don't type-abuse of local variable 'val'.
+ (lookup_name_real): Likewise.
+ (maybe_inject_for_scope_var): Adjust local variable type.
+ (cp_tree_node_structure): Remove CPLUS_BINDING case label.
+ (namespace_binding): Adjust logic, simplify.
+ (BINDING_LEVEL): Adjust definition.
+ (push_class_level_binding): Adjust local variable type.
+ (struct cxx_saved_binding): Adjust field 'binding' type.
+ * decl2.c (ambiguous_decl): Adjust prototype.
+ (lookup_using_namespace): Adjust local variable type.
+ (qualified_lookup_using_namespace): Catch type error and correct
+ ensueing logic error.
+ (do_nonmember_using_decl): Adjust local variable type. Allocate
+ temporary cxx_binding on stack.
+ (do_toplevel_using_decl): Adjust local variable type.
+ * ptree.c (cxx_print_cxx_binding): New function.
+ (cxx_print_identifier): Use it.
+ (cxx_print_xnode): Delete CPLUS_BINDING case label.
+
+2003-03-15 Roger Sayle <roger@eyesopen.com>
+
+ * tree.c (count_functions): Fix whitespace.
+
+2003-03-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+
+2003-03-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6440
+ * pt.c (maybe_process_partial_specialization): Handle
+ member class template when enclosing class template is
+ explicit specialized.
+ (most_general_template): Stop looking when DECL is already
+ specialized.
+
+2003-03-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/9420
+ * search.c (lookup_conversions): Call complete_type here.
+ * call.c (implicit_conversion): Not here.
+
+2003-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Correct handling of
+ simultaneous type/non-type bindings.
+
+ * call.c (initialize_reference): Remove bogus assertion.
+ * decl.c (build_ptrmemfunc_type): Revert change of 2003-03-09.
+
+2003-03-12 Andrew Lewycky <andrew@mxc.ca>
+
+ PR c++/7050
+ * expr.c (cxx_expand_expr): Return const0_rtx for throw
+ expressions.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9474
+ * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
+ to merge old and new declarations.
+
+2003-03-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * g++.1: Remove.
+ * Make-lang.in (c++.generated-manpages): Build cp/g++.1.
+ (cp/g++.1): Build it from scratch in the build tree.
+ (c++.install-man): Depend on it. Install it from the build tree.
+ (c++.mostlyclean): Clean it.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9474
+ * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
+ to merge old and new declarations.
+
+ PR c++/9924
+ * decl2.c (do_nonmember_using_decl): Ignore anticipated builtins.
+
+2003-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/9820
+ * search.c (lookup_member): Fix handling of functions in a class
+ being defined.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8700
+ * call.c (convert_class_to_reference): Adjust usage of
+ splice_viable.
+ (any_viable): Remove.
+ (splice_viable): Combine with any_viable.
+ (print_z_candidates): Avoid printing duplicates.
+ (build_user_type_conversion_1): Adjust usage of splice_viable.
+ (build_new_function_call): Likewise.
+ (build_operator_new_call): Likewise.
+ (build_object_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ (joust): Remove spurious comment.
+ * cp-tree.h (DECL_FRIENDLIST): Correct documentation.
+ * decl2.c (arg_assoc_class): Simplify.
+ * friend.c (add_friend): Likewise.
+
+2003-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/8660
+ * decl2.c (check_classfn): A member template only matches a
+ member template.
+
+2003-03-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+ * lang-specs.h: Don't define __GNUG__ here.
+
+2003-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (perform_overload_resolution): New function.
+ (build_new_function_call): Use it.
+ (build_operator_new_call): Likewise.
+ (add_candidates): Add explicit_targs and template_only parameters.
+ (build_new_op): Adjust accordingly.
+ * cp-tree.h (build_operator_new_call): New function.
+ (build_function_call_real): Remove.
+ (build_function_call_maybe): Likewise.
+ * init.c (build_new_1): Use build_operator_new_call.
+ * typeck.c (build_function_call_real): Rename to ...
+ (build_function_call): ... this.
+
+2003-03-10 Devang Patel <dpatel@apple.com>
+
+ PR c++/9394
+ * g++spec.c (lang_specific_driver): Use DEFAULT_WORD_SWTCH_TAKES_ARG.
+
+2003-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/9798
+ * decl.c (push_using_directive): Push before recursing.
+
+ PR c++/9868, c++/9524
+ * call.c (resolve_scoped_fn_name): Handle the case of a function
+ pointer member.
+
+ * decl2.c (build_offset_ref_call_from_tree): Only mess with 'this'
+ argument in the pointer-to-member case.
+
+2003-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9373
+ * cp-lang.c (cxx_get_alias_set): Use alias set zero for
+ pointers to member functions.
+
+ PR c++/8534
+ * decl.c (build_ptrmemfunc_type): Do not allow default arguments
+ in pointer-to-member-function types.
+
+2003-03-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * expr.c (cplus_expand_constant): Use C90 prototype style.
+ (cxx_expand_expr): Likewise.
+
+2003-03-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9970
+ * decl.c (duplicate_decls): Only copy DECL_THUNKS for virtual
+ functions.
+
+2003-03-08 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h (c++-header): Change .pch to .gch.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (cxx_init): Update prototype.
+ * lex.c (cxx_init): Similarly.
+
+2003-03-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9823
+ * cp-tree.h (begin_mem_initializers): Remove.
+ * parser.c (cp_parser_mem_initializer_list): Inline it here.
+ Do not call finish_mem_initializers if not in a constructor.
+ (cp_parser_class_head): Fix typo in error message.
+ * semantics.c (begin_mem_initializers): Remove.
+ * testsuite/g++.dg/parser/constructor1.C: New test.
+
+ PR c++/9809
+ * call.c (add_function_candidate): Skip builtin fuctions that have
+ not yet been declared.
+
+ PR c++/9982
+ * init.c (build_new_1): Correct logic for determining whether or
+ not to use an array cookie.
+
+ PR c++/9524
+ * parser.c (cp_parser_postfix_expression): Call
+ finish_non_static_data_member, even when processing_template_decl.
+
+ PR c++/9912
+ * cp-tree.h (is_ancestor): New function.
+ (handle_class_head): Change prototype.
+ * decl2.c (is_namespace_ancestor): Rename to ...
+ (namespace_anecestor): ... this.
+ (set_decl_namespace): Adjust accordingly.
+ (handle_class_head): Remove unnecessary parameters.
+ * parser.c (cp_parser_class_head): Check that
+ nested-name-specifiers are used appropriately.
+
+2003-03-07 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (reference_binding): Remove REF_IS_VAR parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (make_temporary_var_for_ref_to_type): Add TYPE parameter.
+ (initialize_reference): Adjust handling for references bound to
+ rvalues.
+ * cp-tree.h (make_temporary_var_for_ref_to_temp): Change
+ prototype.
+ (real_non_cast_lvalue_p): New method.
+ * cvt.c (build_up_reference): Adjust use of
+ make_temporary_var_for_ref_to_temp.
+ * tree.c (real_non_cast_lvalue_p): New method.
+
+2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * except.c (init_exception_processing): Use C90 prototype style.
+ (cp_protect_cleanup_actions): Likewise.
+ (prepare_eh_type): Likewise.
+ (build_eh_type_type): Likewise.
+ (build_exc_ptr): Likewise.
+ (do_begin_catch): Likewise.
+ (dtor_nothrow): Likewise.
+ (do_end_catch): Likewise.
+ (push_eh_cleanup): Likewise.
+ (decl_is_java_type): Likewise.
+ (choose_personality_routine): Likewise.
+ (initialize_handler_parm): Likewise.
+ (expand_start_catch_block): Likewise.
+ (expand_end_catch_block): Likewise.
+ (begin_eh_spec_block): Likewise.
+ (finish_eh_spec_block): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (wrap_cleanups_r): Likewise.
+ (stabilize_throw_expr): Likewise.
+ (build_throw): Likewise.
+ (complete_ptr_ref_or_void_ptr_p): Likewise.
+ (is_admissible_throw_operand): Likewise.
+ (nothrow_libfn_p): Likewise.
+ (can_convert_eh): Likewise.
+ (check_handlers_1): Likewise.
+ (check_handlers): Likewise.
+
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (merge_conversion_sequences): New function.
+ (build_conv): Set ICS_USER_FLAG for USER_CONVs.
+ (convert_class_to_reference): Correct handling of second
+ standard conversion sequence in a user-defined conversion
+ sequence.
+ (build_user_type_conversion_1): Use merge_conversion_sequences.
+ * cp-tree.def: Add comments for CONV nodes.
+ * rtti.c (get_tinfo_decl): Use build_address/build_nop.
+
+2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (init_error): Use C90 prototype style.
+ (dump_scope): Likewise.
+ (dump_qualifiers): Likewise.
+ (dump_template_argument): Likewise.
+ (dump_template_argument_list): Likewise.
+ (dump_template_parameter): Likewise.
+ (dump_template_bindings): Likewise.
+ (dump_type): Likewise.
+ (dump_typename): Likewise.
+ (class_key_or_enum): Likewise.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_simple_decl): Likewise.
+ (dump_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_parameters): Likewise.
+ (dump_exception_spec): Likewise.
+ (dump_function_name): Likewise.
+ (dump_template_parms): Likewise.
+ (dump_char): Likewise.
+ (dump_expr_list): Likewise.
+ (dump_expr): Likewise.
+ (dump_binary_op): Likewise.
+ (dump_unary_op): Likewise.
+ (type_as_string): Likewise.
+ (expr_as_string): Likewise.
+ (decl_as_string): Likewise.
+ (context_as_string): Likewise.
+ (lang_decl_name): Likewise.
+ (cp_file_of): Likewise.
+ (cp_line_of): Likewise.
+ (decl_to_string): Likewise.
+ (expr_to_string): Likewise.
+ (fndecl_to_string): Likewise.
+ (code_to_string): Likewise.
+ (language_to_string): Likewise.
+ (parm_to_string): Likewise.
+ (op_to_string): Likewise.
+ (type_to_string): Likewise.
+ (assop_to_string): Likewise.
+ (args_to_string): Likewise.
+ (cv_to_string): Likewise.
+ (cxx_print_error_function): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (function_category): Likewise.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (maybe_print_instantiation_context): Likewise.
+ (print_instantiation_context): Likewise.
+ (cp_printer): Likewise.
+ (print_integer): Likewise.
+ (print_non_consecutive_character): Likewise.
+ (locate_error): Likewise.
+
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9965
+ * call.c (reference_binding): Add ref_is_var parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (initialize_reference): Likewise.
+
+ PR c++/9400
+ * decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL
+ PARM_DECLs.
+
+ PR c++/9791
+ * class.c (get_basefndecls): Use lookup_fnfields_1.
+
+2003-03-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9188
+ * parser.c (cp_parser_type_parameter): Remove redundant `expect'
+ in error message.
+ (cp_parser_single_declaration): Likewise.
+
+2003-03-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/9440
+ * call.c (build_conditional_expr): Use convert rather than an
+ explicit NOP_EXPR.
+
+2003-03-02 Matt Austern <austern@apple.com>
+
+ * decl.c (cp_binding_level): Add static_decls varray member.
+ (add_decl_to_level): Add static/inline namespace scope
+ declarations to static_decls array.
+ (wrapup_global_for_namespace): Pass static_decls only, instead of
+ all decls, to wrapup_global_declarations/check_global_declarations.
+ (push_namespace): Initialize static_decls for ordinary namespaces.
+ (cxx_init_decl_processing): Initialize static_decls for global
+ namespace.
+
+2003-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (end_of_class): Correct thinko.
+
+2003-03-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config-lang.in: Replace ${libstdcxx_version} by its value.
+
+2003-03-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (cxx_saved_binding): Declare.
+ (struct saved_scope): Adjust type of field 'old_binding'.
+ * decl.c (cxx_saved_binding_make): New macro.
+ (struct cxx_saved_binding): Define.
+ (store_bindings): Adjust prototype. Use cxx_saved_binding to save
+ C++ bindings.
+ (maybe_push_to_top_level): Adjust local variable type.
+ (pop_from_top_level): Likewise.
+
+2003-03-04 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (c++.tags): New target.
+
+2003-03-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_enum): Do set the type in a template. Simplify.
+ * pt.c (tsubst_enum, tsubst_copy): Revert last patch.
+
+2003-03-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9878
+ * call.c (convert_class_to_reference): Correct conversion
+ sequences.
+ (reference_binding): Add ref_bound_directly_to_rvalue_p parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (add_candidate): Change type of candidates parameter.
+ (add_function_candidate): Likewise.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_builtin_candidate): Likewise.
+ (add_builtin_candidates): Likewise.
+ (add_template_candidate_real): Likewise.
+ (add_template_candidate): Likewise.
+ (add_template_conv_candidate): Likewise.
+ (build_user_type_conversion_1): Adjust accordingly.
+ (build_object_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (add_candidates): Likewise.
+ (build_new_op): Likewise.
+ (convert_like_real): Use USER_CONV_CAND. Use build_nop.
+ (build_new_method_call): Adjust calls to add_function_candidate.
+ (make_temporary_var_for_ref_to_temp): New function.
+ (initialize_reference): Add decl parameter.
+ * class.c (build_rtti_vtbl_entries): Use build_address and
+ build_nop.
+ * cp-tree.h (initialize_reference): Change prototype.
+ (make_temporary_var_for_ref_to_temp): New function.
+ (build_type_conversion): Change prototype.
+ (build_address): New function.
+ (build_nop): Likewise.
+ * cvt.c (cp_convert_to_pointer): Adjust call to
+ build_type_conversion. Avoid indicating redundant NOP_EXPRs.
+ Use build_nop.
+ (convert_to_pointer_force): Use build_nop.
+ (build_up_reference): Use make_temporary_var_for_ref_to_temp.
+ (convert_to_reference): Adjust call to build_type_conversion.
+ (ocp_convert): Likewise.
+ (build_type_conversion): Remove for_sure parameter.
+ * decl.c (grok_reference_init): Use initialize_reference.
+ * typeck.c (build_address): New function.
+ (build_nop): Likewise.
+ (build_unary_op): Use them.
+ (build_ptrmemfunc): Tidy slightly.
+ (convert_for_initialization): Adjust call to
+ initialize_reference.
+ * typeck2.c (store_init_value): Remove #if 0'd code.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * decl.c (start_function): Clear DECL_NUM_STMTS.
+
+ * class.c (get_vtable_decl): Use vtbl_type_node.
+ (build_primary_vtable): Check for it.
+
+2003-03-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (check_initializer): Check for vector_opaque_p.
+
+2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
+
+ * lang-specs.h (default_compilers): Add -no-integrated-cpp flag to
+ invoke an external cpp during compilation.
+
+2003-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (duplicate_decls): Convert use of warning_with_decl() to
+ that of warning().
+ (start_decl): Likewise.
+ (start_function): Likewise.
+
+2003-03-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+
+2003-02-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9892
+ * pt.c (instantiate_decl): Clear DECL_RTL for a VAR_DECL when
+ instantiating it.
+
+2003-02-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * parser.c (cp_parser_init_declarator): Revert opaque
+ vector_opaque_p change.
+ Do not include target.h.
+
+2003-02-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9879
+ * cp-tree.h (build_zero_init): Add parameter.
+ * decl.c (cp_finish_decl): Adjust call.
+ * init.c (build_zero_init): Add nelts parameter. Adjust recursive
+ calls.
+ (build_default_init): Add nelts parameter. Adjust calls to
+ build_zero_init.
+ (build_new_1): Adjust call to build_default_init.
+ * typeck2.c (process_init_constructor): Adjust call to build_zero_init.
+
+2003-02-26 Devang Patel <dpatel@apple.com>
+
+ * decl.c (finish_enum): Merge two 'for' loops. Copy value node if
+ required. Postpone enum setting for template decls.
+ (build_enumerator): Delay copying value node until finish_enum
+ (). Remove #if 0'ed code.
+ * pt.c (tsubst_enum): Set TREE_TYPE and copy value node.
+ (tsubst_copy): Add check for enum type.
+
+2003-02-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9683
+ * decl2.c (prune_vars_needing_no_initialization): Do not throw
+ away initializations for DECL_EXTERNAL VAR_DECLs.
+ (finish_file): Adjust accordingly.
+ * pt.c (instantiate_decl): Do not defer VAR_DECLs.
+
+2003-02-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (add_binding): Time TV_NAME_LOOKUP.
+ (push_class_binding): Likewise.
+ (set_namespace_binding): Likewise.
+
+2003-02-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9836
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): Do not skip from
+ specializations back to the main template.
+ * parser.c (cp_parser_diagnose_invalid_type_name):Adjust use.
+ * pt.c (resolve_typename_type): Likewise.
+
+2003-02-24 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ PR c++/9778
+ * pt.c (tsubst_copy_and_build): For a templated function inside a
+ scope, process template arguments.
+
+2003-02-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9602
+ * typeck2.c (abstract_virtuals_error): Don't check when
+ TYPE is still template parameter dependent.
+
+2003-02-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5333
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): New macro.
+ * parser.c (cp_parser_diagnose_invalid_type_name): Use it.
+ * pt.c (instantiate_class_template): Don't try to instantiate
+ dependent types.
+ (resolve_typename_type): Use CLASSTYPE_PRIMARY_TEMPLATE.
+
+2003-02-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9749
+ * decl.c (grokdeclarator): Do not allow parameters with variably
+ modified types.
+
+2003-02-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (grow_bfs_bases): Remove. Fold into ...
+ (bfs_walk): ... here, fix fencepost error. Fix merge lossage
+ in previous patch.
+
+2003-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9729
+ * mangle.c (mangle_conv_op_name_for_type): Issue an error message
+ when the G++ 3.2 ABI prevents correct compilation.
+
+2003-02-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Change base class access representation. Share virtual base
+ binfos.
+ * cp/call.c (build_special_member_call): Remove binfo_for_vbase
+ call.
+ * cp/class.c (build_base_path): Likewise.
+ (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use.
+ (build_secondary_vtable): Remove FOR_TYPE arg. Adjust.
+ (make_new_vtable): Adjust.
+ (force_canonical_binfo_r): Delete.
+ (force_canonical_binfo): Delete.
+ (mark_primary_virtual_base): Delete.
+ (dfs_unshared_virtual_bases): Delete.
+ (mark_primary_bases): Adjust.
+ (maybe_warn_about_overly_private_class): Adjust.
+ (dfs_base_derived_from): Delete.
+ (base_derived_from): Follow the inheritance chain.
+ (struct find_final_overrider_data): Add vpath member.
+ (dfs_find_final_overrider): Adjust.
+ (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New.
+ (find_final_overrider): Adjust.
+ (update_vtable_entry_for_fn): Adjust.
+ (modify_all_vtables): Adjust.
+ (walk_subobject_offsets): Adjust.
+ (layout_nonempty_base_or_field): Adjust.
+ (layout_empty_base): Remove last parameter. Adjust.
+ (build_base_field): Adjust.
+ (build_base_fields): Adjust.
+ (propagate_binfo_offsets): Remove last parameter. Adjust.
+ (dfs_set_offset_for_unshared_vbases): Delete.
+ (layout_virtual_bases): Adjust.
+ (finish_struct_1): Adjust.
+ (init_class_processing): Don't init access nodes.
+ (dfs_get_primary_binfo): Delete.
+ (get_primary_binfo): Adjust.
+ (dump_class_hierarchy_r): Remove most derived arg, add IGO
+ parameter. Adjust.
+ (dump_class_hierarchy): Adjust.
+ (finish_vtbls): Adjust.
+ (get_original_base): Delete.
+ (build_vtt_inits): Adjust.
+ (dfs_build_secondary_vptr_vtt_inits): Adjust.
+ (dfs_ctor_vtable_bases_queue_p): Adjust.
+ (build_ctor_vtbl_group): Adjust.
+ (dfs_accumulate_vtbl_inits): Adjust.
+ (build_vtbl_initializer): Adjust.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (add_vcall_offset_vtbl_entries_1): Adjust.
+ * cp/cp-tree.h (CPTI_ACCESS_*): Remove.
+ (access_*_node): Remove.
+ (CANONICAL_BINFO): Delete.
+ (BINFO_UNSHARED_MARKED): Remove.
+ (BINFO_MARKED): Set LANG_FLAG_0 directly.
+ (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete.
+ (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly.
+ (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED):
+ Delete.
+ (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust.
+ (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED):
+ Delete.
+ (BINFO_DEPENDENT_BASE_P): New.
+ (dfs_walk, dfs_walk_real): Queue function takes derived binfo and
+ index.
+ (markedp, unmarkedp): Adjust.
+ (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p,
+ dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp,
+ find_vbase_instance, binfo_for_vbase): Delete.
+ (copied_binfo, original_binfo): Declare.
+ (finish_base_specifier): Add virtual_p arg.
+ (unshare_base_binfos): Delete.
+ (copy_base_binfos): Declare.
+ (reverse_path): Delete.
+ * cp/decl.c (xref_basetypes): Access and virtuality passed
+ differently. Don't copy direct base binfos here. Call
+ copy_base_binfos.
+ * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust.
+ (initialize_vtbl_ptrs): Adjust.
+ (expand_member_init): Adjust.
+ * cp/parser.c (cp_parser_base_specifier): Adjust.
+ * cp/pt.c (instantiate_class_template): Adjust.
+ (get_template_base_recursive): Adjust.
+ * cp/rtti.c (get_pseudo_ti_init): Adjust.
+ (get_pseudo_ti_desc): Adjust.
+ * cp/tree.c (unshare_base_binfos): Rename to ...
+ (copy_base_binfos): ... here, reimplement.
+ (make_binfo): Set BINFO_DEPENDENT_BASE_P.
+ (reverse_path): Remove.
+ * cp/typeck.c (get_delta_difference): Adjust error messages.
+ * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust.
+ * cp/search.c (lookup_base_r): Adjust.
+ (dynamic_cast_base_recurse): Adjust.
+ (canonical_binfo): Remove.
+ (dfs_canonical_queue): Remove.
+ (dfs_assert_unmarked_p): Remove.
+ (assert_canonical_unmarked): Remove.
+ (shared_marked_p, shared_unmarked_p): Remove.
+ (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE.
+ (dfs_access_in_type): Adjust.
+ (access_in_type): Adjust.
+ (dfs_accessible_queue_p): Adjust.
+ (dfs_accessible_p): Adjust.
+ (is_subobject_of_p_1, is_subobject_of_p): Remove.
+ (struct lookup_field_info): Remove from_dep_base_p field.
+ (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P.
+ (lookup_field_r): Remove dependent base code.
+ (lookup_member): Likewise.
+ (dfs_walk, dfs_walk_real): Add access arg to queue fn.
+ (dfs_unmarked_real_bases_queue_p): Remove.
+ (dfs_marked_real_bases_queue_p): Remove.
+ (dfs_skip_vbases): Remove.
+ (dfs_get_pure_virtuals): Adjust.
+ (markedp, unmarkedp): Adjust.
+ (marked_vtable_pathp, unmarked_vtable_pathp): Remove.
+ (marked_pushdecls_p, unmarked_pushdecls_p): Adjust.
+ (dfs_unmark): Adjust.
+ (dfs_get_vbase_types):Remove.
+ (dfs_build_inheritance_graph_order): Remove.
+ (get_vbase_types): Remove
+ (dfs_find_vbase_instance): Remove.
+ (find_vbase_instance): Remove.
+ (dfs_debug_unmarkedp): Adjust.
+ (dependent_base_p): Remove.
+ (dfs_push_type_decls): Adjust.
+ (dfs_push_decls): Adjust.
+ (dfs_no_overlap_yet): Adjust.
+ (copied_binfo): New function.
+ (original_binfo): New function.
+ (binfo_for_vbase): Remove.
+
+2003-02-18 Zack Weinberg <zack@codesourcery.com>
+
+ * cp/search.c (grow_bfs_bases): New subroutine of bfs_walk.
+ (bfs_walk): Rewritten using circular queue of BINFO_BASETYPES
+ vectors, for speed.
+
+2003-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9704
+ * class.c (layout_class_type): In the 3.2 ABI, take into account
+ trailing bit fields when computing CLASSTYPE_SIZE_UNIT.
+
+2003-02-18 Matt Austern <austern@apple.com>
+
+ * cp/cp-lang.c: Change lang hooks so that final_write_globals does
+ nothing for C++.
+ * cp/decl.c (wrapup_globals_for_namespace): Remove special
+ handling of global namespace.
+
+2003-02-18 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (rid_to_yy): Delete.
+ (C_RID_YYCODE): Delete.
+ (finish_file): Delete redundant declaration.
+
+2003-02-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/9623
+ * decl.c (reshape_init): Don't mess with initializer labels.
+
+ PR c++/9485
+ * parser.c (cp_parser_postfix_expression): Set idk properly for
+ object->scope::member.
+
+2003-02-18 Ben Elliston <bje@redhat.com>
+
+ PR other/7350
+ * decl.c (duplicate_decls): Fix typo in comment.
+
+2003-02-17 Michael Elizabeth Chastain <mec@shout.net>
+
+ PR debug/9717
+ * class.c (build_base_field): Mark fields for base classes with
+ DECL_IGNORED_P.
+
+2003-02-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9457
+ * pt.c (tsubst_copy_and_build) [CONSTRUCTOR]: Substitute
+ CONSTRUCTOR_ELTS only once.
+
+2003-02-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9459
+ * error.c (dump_type_prefix): Handle TYPEOF_TYPE.
+ (dump_type_suffix): Likewise.
+
+2003-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c: ANSIfy function declarations and definitions.
+ * cp-tree.h (lookup_field, lookup_member): Last parameter is a bool.
+ * call.c (build_method_call, resolve_scoped_fn_name,
+ build_java_interface_fn_ref): Adjust lookup_field, lookup_member
+ calls.
+ * class.c (handle_using_decl): Likewise.
+ * decl.c (make_typename_type, make_unmound_class_template,
+ start_decl, compute_array_index_type): Likewise.
+ * decl2.c (build_expr_from_tree, build_call_from_tree): Likewise.
+ * init.c (expand_member_init, build_member_call): Likewise.
+ * pt.c (tsubst_copy, tsubst_copy_and_build, do_decl_instantiation,
+ resolve_typename_type): Likewise.
+ * typeck.c (lookup_destructor, finish_class_member_access_exprm
+ build_prememfunc_access_expr): Likewise.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl2.c: Include "timevar.h".
+ (namespace_ancestor): Time name lookup.
+ (add_using_namespace): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (decl_namespace): Likewise.
+ (lookup_arg_dependent): Likewise.
+ * lex.c (do_identifier): Likewise.
+ (do_scoped_id): Likewise.
+ * pt.c (lookup_template_class): Likewise.
+
+2003-02-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c: (define_label): Fix warning for return 0 instead of NULL.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c: Include "timevar.h".
+ (poplevel): Time name lookup.
+ (find_binding): Likewise.
+ (push_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (store_bindings): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (push_local_name): Likewise.
+ (pushtag): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (pushdecl_top_level): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_using_decl): Likewise.
+ (push_using_directive): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_label): Likewise.
+ (define_label): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_tag_reverse): Likewise.
+ (lookup_namespace_name): Likewise.
+ (select_decl): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (xref_tag): Likewise.
+
+ * Make-lang.in (cp/decl.o): Add dependency on timevar.h
+
+2003-02-12 Phil Edwards <pme@gcc.gnu.org>
+
+ * decl.c (build_enumerator): Remove unneeded test.
+
+2003-02-09 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * cp-tree.h (struct lang_type_header): Make all fields unsigned
+ char.
+
+2003-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7129
+ * call.c (z_candidate): Add args.
+ (convert_class_to_reference): Set it.
+ (implicit_conversion): Tidy.
+ (add_candidate): Add args parameter.
+ (add_function_candidate): Adjust call to add_candidate.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (build_user_type_conversion_1): Eliminate wasteful tree_cons
+ usage.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (add_candidates): New function.
+ (build_new_op): Use it.
+ (covert_like_real): Adjust call to build_over_call.
+ (build_over_call): Remove args parameter.
+ * operators.def: Add <?= and >?=.
+
+2003-02-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * typeck.c (build_indirect_ref): Don't check flag_volatile.
+
+2003-01-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8849
+ * pt.c (resolve_overloaded_unification): Handle FUNCTION_DECL.
+
+2003-01-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX,
+ BINFO_PRIMARY_BASE_OF): Use BINFO_ELTS.
+ (BINFO_LANG_ELTS): New #define.
+ * tree.c (make_binfo): Use BINFO_LANG_ELTS.
+
+2003-01-30 Geoffrey Keating <geoffk@apple.com>
+
+ * cp/Make-lang.in: Remove -Wno-error from cp/decl.o.
+
+2003-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Only check C_TYPE_FIELDS_READONLY
+ for class types.
+ * cp-tree.h (C_TYPE_FIELDS_READONLY): Use a lang-specific bit
+ rather than TYPE_LANG_FLAG_0.
+ (TYPE_BUILT_IN): Remove.
+ (TYPE_DEPENDENT_P): New macro.
+ (TYPE_DEPENDENT_P_VALID): Likewise.
+ (lang_type_class): Add fields_readonly.
+ * decl.c (record_builtin_type): Don't set TYPE_BUILT_IN.
+ * pt.c (dependent_type_p_r): New function, split out from ...
+ (dependent_type_p): ... here. Memoize results.
+ * search.c (dependent_base_p): Use dependent_type_p, not
+ uses_template_parms.
+ * typeck.c (build_modify_expr): Only check C_TYPE_FIELDS_READONLY
+ for class types.
+
+2003-01-29 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_field_call): Use build_new_op, not build_opfncall.
+ (prep_operand): New function.
+ (build_new_op): Use it. Remove dead code.
+ * class.c (pushclass): Change "modify" parameter type from int to
+ bool.
+ (currently_open_class): Use same_type_p, not pointer equality.
+ (push_nested_class): Adjust calls to pushclass, remove modify
+ parameter.
+ * cp-tree.h (INTEGRAL_OR_ENUMERATION_TYPE_P): New macro.
+ (pushclass): Change prototype.
+ (push_nested_class): Likewise.
+ (grokoptypename): Remove.
+ (build_opfncall): Remove.
+ (value_dependent_expression_p): Declare.
+ (resolve_typename_type): Likewise.
+ (resolve_typename_type_in_current_instantiation): Likewise.
+ (enter_scope_of): Remove.
+ (tsubst): Remove.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * decl.c (warn_about_implicit_typename_lookup): Remove.
+ (finish_case_label): Return error_mark_node for erroneous labels.
+ (start_decl): Adjust calls to push_nested_class.
+ (grokfndecl): Call push_scope/pop_scope around call to
+ duplicate_decls.
+ (grokdeclarator): Do not call tsubst.
+ (start_function): Adjust calls to push_nested_class.
+ * decl2.c (grok_array_decl): Use build_new_op, not build_opfncall.
+ (check_classfn): Use push_scope/pop_scope around type comparisions.
+ (grokoptypename): Remove.
+ (push_sscope): Adjust call to push_nested_class.
+ * error.c (dump_type): Show cv-qualification of typename types.
+ * init.c (build_member_call): Use build_new_op, not
+ build_opfncall.
+ * method.c (build_opfncall): Remove.
+ * parser.c (cp_parser): Add allow_non_constant_expression_p and
+ non_constant_expression_p.
+ (cp_parser_constant_expression): Adjust prototype.
+ (cp_parser_resolve_typename_type): Remove.
+ (cp_parser_non_constant_expression): New function.
+ (cp_parser_non_constant_id_expression): Likewise.
+ (cp_parser_new): Set allow_non_constant_expression_p and
+ non_constant_expression_p.
+ (cp_parser_primary_expression): Reject `this' and `va_arg' in
+ constant-expressions. Note that dependent names aren't really
+ constant.
+ (cp_parser_postfix_expression): Reject conversions to non-integral
+ types in constant-expressions. Neither are increments or
+ decrements.
+ (cp_parser_unary_expression): Reject increments and decrements in
+ constant-expressions.
+ (cp_parser_direct_new_declarator): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_cast_expression): Reject conversions to non-integral
+ types in constant-expressions.
+ (cp_parser_assignment_expression): Rejects assignments in
+ constant-expressions.
+ (cp_parser_expression): Reject commas in constant-expressions.
+ (cp_parser_labeled_statement): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_direct_declarator): Simplify array bounds, even in
+ templates, when they are non-dependent. Use
+ resolve_typename_type, not cp_parser_resolve_typename_type.
+ (cp_parser_class_head): Use resolve_typename_type, not
+ cp_parser_resolve_typename_type.
+ (cp_parser_member_declaration): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_constant_initializer): Likewise.
+ (cp_parser_constructor_declarator): Use resolve_typename_type, not
+ cp_parser_resolve_typename_type.
+ (cp_parser_late_parsing_default_args): Adjust call to
+ push_nested_class.
+ * pt.c (tsubst): Give it internal linkage.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ (push_access_scope_real): Likewise.
+ (tsubst_friend_class): Likewise.
+ (instantiate_class_template): Adjust call to pushclass.
+ (value_dependent_expression_p): Give it external linkage.
+ Robustify.
+ (resolve_typename_type): New function.
+ * semantics.c (finish_call_expr): Use build_new_op, not
+ build_opfncall.
+ (begin_constructor_declarator): Remove.
+ (begin_class_definition): Adjust call to pushclass.
+ (enter_scope_of): Remove.
+ * typeck.c (comptypes): Resolve typename types as appropriate.
+ (build_x_indirect_ref): Use build_new_op, not build_opfncall.
+ (build_x_compound_expr): Likewise.
+ (build_modify_expr): Likewise.
+ (build_x_modify_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-01-29 Fariborz Jahanian <fjahanian@apple.com>
+
+ * pt.c (last_pending_template) Declare GTY().
+
+2003-01-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8591
+ * parser.c (cp_parser_elaborated_type_specifier): Convert
+ TEMPLATE_DECL to TYPE_DECL only when processing template friends.
+ (cp_parser_maybe_treat_template_as_class): Remove redundant tests.
+
+2003-01-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9437
+ * pt.c (unify): Don't unify '*T' with 'U C::*'.
+
+ PR c++/3902
+ * parser.c (cp_parser_decl_specifier_seq): Cannot have constructor
+ inside a declarator.
+
+2003-01-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (update_vtable_entry_for_fn): Add index parameter.
+ Generate vcall thunk for covariant overriding from a virtual
+ primary base.
+ (dfs_modify_vtables): Adjust.
+
+2003-01-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9403
+ * parser.c (cp_parser_class_or_namespace_name): Reject duplicate
+ template keyword.
+ (cp_parser_base_specifier): Look for and consume a
+ TEMPLATE keyword. Replace switch with array index.
+
+ PR c++/795
+ * semantics.c (finish_non_static_data_member): Remember the
+ field's type even in a template.
+
+ PR c++/9415
+ * pt.c (tsubst_copy_and_build, CALL_EXPR): BASELINK exprs are
+ already scoped.
+
+ PR c++/8545
+ * parser.c (cp_parser_cast_expression): Be more tentative.
+
+2003-01-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (flagged_type_tree_s): Remove.
+ (check_for_new_type): Likewise.
+ * typeck2.c (check_for_new_type): Likewise.
+
+2003-01-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * dump.c: ANSIfy function declarations and definitions.
+
+ * cp-tree.h, decl.h: Get rid of PARAMS. Again.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9354
+ * init.c (build_new): Set the type of the new-expression, even
+ when processing_templte_decl.
+
+ PR c++/9216
+ * parser.c (cp_parser_primary_expression): Improve error message
+ for templates used in an expression context.
+
+ PR c++/8696
+ * parser.c (cp_parser_decl_specifier_seq): Commit to tentative
+ parse when encountering "typedef".
+
+2003-01-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * class.c, parser.c: ANSIfy function definitions and declarations.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9328
+ * error.c (dump_decl): For an OVERLOAD, just print the name of the
+ function; it doesn't make sense to try to print its type.
+ * semantics.c (finish_typeof): Issue errors about invalid uses.
+
+ PR c++/9298
+ * parser.c (cp_parser_consume_semicolon_at_end_of_statement): New
+ function.
+ (cp_parser_expression_statement): Use it.
+ (cp_parser_explicit_instantiation): Likewise.
+ * pt.c (do_decl_instantiation): Improve error handling logic.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9384
+ * parser.c (cp_parser_using_declaration): Issue error messages
+ about name resolution failures here.
+
+ PR c++/9388
+ * class.c (currently_open_derived_class): Use dependent_type_p.
+ * cp-tree.h (dependent_type_p): New function.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ * parser.c (cp_parser_dependent_type_p): Remove.
+ (cp_parser_value_dependent_type_p): Likewise.
+ (cp_parser_type_dependent_expression_p): Likewise.
+ (cp_parser_dependent_template_arg_p): Likewise.
+ (cp_parser_dependent_template_id_p): Likewise.
+ (cp_parser_dependent_template_p): Likewise.
+ (cp_parser_diagnose_invalid_type_name): Replace
+ cp_parser_dependent_type_p with dependent_type_p, etc.
+ (cp_parser_primary_expresion): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ * pt.c (dependent_type_p): New function.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_id_p): Likewise.
+ (dependent_template_p): Likewise.
+
+ PR c++/9285
+ PR c++/9294
+ * parser.c (cp_parser_simple_declaration): Return quickly when
+ encountering errors.
+
+2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ Make-lang.in (cp/decl.o-warn): Add -Wno-error.
+
+2003-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/9167, c++/9358
+ * decl.c (require_complete_types_for_parms): Also update DECL_ARG_TYPE.
+
+2003-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/9342
+ * call.c (build_conditional_expr): Always do lvalue-rvalue
+ conversion.
+
+2003-01-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9294
+ * cp-tree.def (BASELINK): Make it class 'x', not class 'e'.
+ * cp-tree.h (BASELINK_BINFO): Adjust.
+ (BASELINK_FUNCTIONS): Likewise.
+ (BASELINK_ACCESS_BINFO): Likewise.
+ (tree_baselink): New structure.
+ (cp_tree_node_structure_enum): Add TS_CP_BASELINK.
+ (lang_tree_node): Add baselink.
+ * decl.c (cp_tree_node_structure): Add BASELINK case.
+ * search.c (build_baselink): Adjust.
+ * tree.c (cp_walk_subtrees): Add BASELINK case. Remove BASELINK_P
+ test from TREE_LIST case.
+
+ PR c++/9272
+ * parser.c (cp_parser_constructor_declarator_p): Do not assume
+ that a constructor cannot be declared outside of its own class.
+
+ * parser.c (cp_parser_resolve_typename_type): If the scope cannot
+ be resolved, neither can the qualified name.
+
+ * rtti.c (get_pseudo_ti_desc): Fix thinko.
+
+2003-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/8564
+ * init.c (build_vec_init): Re-add maxindex parm.
+ (perform_member_init, build_aggr_init): Pass it.
+ (build_new_1): Pass it. Use an incomplete array type for full_type.
+ * typeck.c (build_modify_expr): Pass it.
+ * cp-tree.h: Adjust.
+
+2003-01-16 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ * cp-tree.h (tsubst_copy_and_build): New declaration.
+ * pt.c (tsubst_copy): Remove 'build_expr_from_tree' from comment.
+ (tsubst_expr): Use 'tsubst_copy_and_build'. Update initial comment.
+ (tsubst_copy_and_build): New function.
+
+2003-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type_class): Remove is_partial_instantiation.
+ (PARTIAL_INSTANTIATION_P): Remove.
+ (IMPLICIT_TYPENAME_P): Likewise.
+ (IMPLICIT_TYPENAME_TYPE_DECL_P): Likewise.
+ (build_typename_type): Remove declaration.
+ (parmlist_is_exprlist): Likewise.
+ * decl.c (build_typename_type): Make it static, remove third
+ parameter.
+ (push_class_binding): Don't do implicit typename stuff.
+ (make_typename_type): Likewise.
+ (lookup_name_real): Likewise.
+ (grokdeclarator): Don't try to convert declarations into
+ initializations. Don't do implicit typename stuff.
+ (parmlist_is_exprlist): Remove.
+ (xref_basetypes): Simplify.
+ * decl2.c (grokfield): Don't try to convert declarations into
+ initializations.
+ (build_anon_union_vars): Do this while processing templates, too.
+ (finish_anon_union): Likewise.
+ * error.c (dump_type): Remove implicit typename handling.
+ * parser.c (cp_parser_diagnose_invalid_type_name): New method.
+ (cp_parser_primary_expression): Correct handling of names not
+ found by unqualified name lookup in templates.
+ (cp_parser_nested_name_specifier_opt): Avoid checking dependency
+ of types when possible.
+ (cp_parser_simple_declaration): Complain intelligently about some
+ invalid declarations.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_constructor_declarator_p): Don't check when we're in a
+ function scope.
+ * pt.c (instantiate_class_template): Remove
+ PARTIAL_INSTANTIATION_P gunk.
+ * search.c (lookup_field_r): Don't build implicit typenames.
+ (marked_pushdecls_p): Don't enter dependent base types.
+ (unmarked_pushdecls_p): Likewise.
+ * semantics.c (begin_class_definition): Remove implicit typename
+ stuff.
+
+2003-01-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9212
+ * parser.c (cp_parser_direct_declarator): If accepting either
+ abstract or named, the name must be an unqualified-id.
+
+2003-01-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (layout_virtual_bases): Avoid signed/unsigned warning.
+
+2003-01-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (check_classfn): Fix uninitialized warning.
+ (build_anon_union_vars): Likewise.
+ * pt.c (tsubst_copy): Likewise.
+
+2003-01-14 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ Further conform g++'s __vmi_class_type_info to the C++ ABI
+ specification.
+ * rtti.c (dfs_class_hint_mark): Do not set hints not specified by
+ the specification.
+ (class_hint_flags): Likewise.
+
+2003-01-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * config-lang.in: Add semantics.c to gtfiles.
+ * cp-tree.h (flagged_type_tree_s): Remove lookups field.
+ (saved_scope): Likewise.
+ (type_lookups): Remove.
+ (deferred_access): New structure.
+ (type_access_control): Remove.
+ (save_type_access_control): Likewise.
+ (reset_type_access_control): Likewise.
+ (decl_type_access_control): Likewise.
+ (push_deferring_access_checks): Declare.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ * decl.c (make_typename_type): Use perform_or_defer_access_check.
+ (make_unbound_class_template): Likewise.
+ (grokdeclarator): Don't call decl_type_access_control.
+ * parser.c (cp_parser_context): Remove deferred_access_checks
+ and deferring_access_checks_p fields.
+ (cp_parser_context_new): Adjust.
+ (cp_parser): Remove access_checks_lists.
+ (cp_parser_defer_access_check): Remove.
+ (cp_parser_start_deferring_access_checks): Remove.
+ (cp_parser_stop_deferring_access_checks): Remove.
+ (cp_parser_perform_deferred_access_checks): Remove.
+ (cp_parser_nested_name_specifier_opt): Use new deferred access
+ functions.
+ (cp_parser_simple_declaration): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_class_specifier): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ (cp_parser_parse_tentatively): Likewise.
+ (cp_parser_parse_definitely): Likewise.
+ (yyparse): Likewise.
+ (cp_parser_init_declarator): Remove access_checks parameter.
+ Use new deferred access functions.
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Likewise.
+ (cp_parser_class_head): Remove deferring_access_checks_p and
+ saved_access_checks parameters. Use new deferred access functions.
+ (cp_parser_member_specification_opt): Don't call
+ reset_type_access_control.
+ * search.c (type_access_control): Remove.
+ * semantics.c: Include "gt-cp-semantics.h".
+ (deferred_type_access_control): Remove.
+ (deferred_access_stack): New variable.
+ (deferred_access_free_list): Likewise.
+ (push_deferring_access_checks): New function.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): New function, adapted from
+ cp_parser_perform_deferred_access_checks.
+ (perform_or_defer_access_check): New function, adapted from
+ cp_parser_defer_access_check.
+ (current_type_lookups): Remove.
+ (deferred_type_access_control): Likewise.
+ (decl_type_access_control): Likewise.
+ (save_type_access_control): Likewise.
+ (reset_type_access_control): Likewise.
+ (begin_function_definition): Adjust.
+ (begin_class_definiton): Likewise.
+
+2003-01-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/8748
+ * class.c (build_base_path): Take the address before calling save_expr.
+
+ * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
+ all the ambiguous conversions are bad.
+
+ * class.c (maybe_warn_about_overly_private_class): Don't stop
+ searching when we find a nonprivate method.
+
+ * typeck.c (build_class_member_access_expr): Use unary_complex_lvalue.
+
+2003-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (get_arglist_len_in_bytes): Remove.
+
+ PR c++/9264
+ * parser.c (cp_parser_elaborated_type_specifier): Handle erroneous
+ typeame types more robustly.
+
+2003-01-11 Phil Edwards <pme@gcc.gnu.org>
+
+ * parser.c: Fix comment typos.
+
+2003-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9099
+ * parser.c (cp_parser_scope_through_which_access_occurs): Handle
+ an object_type which is not a class type.
+
+2003-01-10 Geoffrey Keating <geoffk@apple.com>
+
+ * parser.c (cp_parser_late_parsing_for_member): Don't cast to void.
+ (cp_parser_late_parsing_default_args): Likewise.
+
+2003-01-10 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cfns.gperf: ANSIfy function declarations.
+ * cfns.h: Regenerate.
+ * cp-tree.h: ANSIfy function declarations.
+
+2003-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (reparse_absdcl_as_expr): Remove.
+ (reparse_absdcl_as_casts): Likewise.
+ (reparse_decl_as_expr): Likewise.
+ (finish_decl_parsing): Likewise.
+ * decl2.c (reparse_absdcl_as_expr): Remove.
+ (reparse_absdcl_as_casts): Likewise.
+ (repase_decl_as_expr): Likewise.
+ (finish_decl_parsing): Likewise.
+
+ PR c++/9128
+ PR c++/9153
+ PR c++/9171
+ * parser.c (cp_parser_pre_parsed_nested_name_specifier): New
+ function.
+ (cp_parser_nested_name_specifier_opt): Correct the
+ check_dependency_p false.
+ (cp_parser_postfix_expression): Fix formatting.
+ (cp_parser_decl_specifier_seq): Avoid looking for constructor
+ declarators when possible.
+ (cp_parser_template_id): Avoid performing name-lookup when
+ possible.
+ (cp_parser_class_head): Do not count specializations when counting
+ levels of templates.
+ (cp_parser_constructor_declarator_p): Return immediately if
+ there's no chance that the tokens form a constructor declarator.
+ * rtti.c (throw_bad_typeid): Add comment. Do not return an
+ expression with reference type.
+ (get_tinfo_decl_dynamic): Do not return an expression with
+ reference type.
+ (build_typeid): Add comment. Do not return an expression with
+ reference type.
+ * typeck.c (build_class_member_access_expr): Improve handling of
+ conditionals and comma-expressions as objects.
+
+2003-01-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cfns.gperf: ANSIfy function declarations.
+ * cfns.h: Regenerate.
+ * cp-tree.h: ANSIfy function declarations.
+ * parser.c: ANSIfy function declarations & definitions.
+
+ * decl.c (bad_specifiers): Fix parameter order error I introduced.
+
+2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge from pch-branch:
+
+ 2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge to tag pch-merge-20030102:
+
+ * semantics.c (finish_translation_unit): Don't call finish_file.
+ * parser.c: Don't include ggc.h.
+ (cp_lexer_new_main): Rename from cp_lexer_new, only create main lexer,
+ read first token here. Don't allow PCH files after the first
+ token is read.
+ (cp_lexer_new_from_tokens): Duplicate functionality from cp_lexer_new.
+ (cp_lexer_get_preprocessor_token): Allow LEXER to be NULL.
+ (cp_parser_new): Call cp_lexer_new_main before allocating GCed memory.
+ (cp_parser_late_parsing_for_member): Don't duplicate call to
+ cp_lexer_set_source_position_from_token.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (yyparse): Call finish_file after clearing the_parser.
+
+ 2002-12-11 Geoffrey Keating <geoffk@apple.com>
+
+ * Make-lang.in: Remove $(GGC_H) from all dependencies.
+ (CXX_TREE_H): Add $(GGC_H).
+ * class.c: Don't include ggc.h.
+ (field_decl_cmp): Make parameters be 'const void *' to match qsort.
+ (method_name_cmp): Likewise.
+ (resort_data): New variable.
+ (resort_field_decl_cmp): New.
+ (resort_method_name_cmp): New.
+ (resort_sorted_fields): New.
+ (resort_type_method_vec): New.
+ (finish_struct_methods): Delete cast.
+ (finish_struct_1): Delete cast.
+ * cp-tree.h: Include ggc.h.
+ (struct lang_type_class): Add reorder attribute to field `methods'.
+ (union lang_decl_u3): Add reorder attribute to field `sorted_fields'.
+ (resort_sorted_fields): New prototype.
+ (resort_type_method_vec): New prototype.
+ * call.c: Don't include ggc.h.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+
+ * lang-specs.h: Remove comment.
+
+ 2002-12-03 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (struct operator_name_info_t): Mark for GTY machinery.
+ (operator_name_info): Mark to be saved for PCH, specify size.
+ (assignment_operator_name_info): Likewise.
+
+ 2002-11-19 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (anon_cnt): Mark to be saved for PCH.
+
+ 2002-10-25 Geoffrey Keating <geoffk@apple.com>
+
+ * lex.c (init_reswords): Delete now-untrue comment.
+ Allocate ridpointers using GGC.
+
+ 2002-10-04 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (union lang_decl_u2): Add tags to all fields.
+
+ * g++spec.c (lang_specific_driver): Don't include standard
+ libraries in `added'.
+
+ 2002-08-27 Geoffrey Keating <geoffk@redhat.com>
+
+ * decl2.c (finish_file): Call c_common_write_pch.
+ * Make-lang.in (CXX_C_OBJS): Add c-pch.o.
+
+ 2002-08-17 Geoffrey Keating <geoffk@redhat.com>
+
+ * g++spec.c (lang_specific_driver): Treat .h files as C++ header
+ files when using g++.
+ * lang-specs.h: Handle compiling C++ header files.
+
+2003-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl): Only check DECL_THREAD_LOCAL for VAR_DECLs.
+
+2003-01-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (push_access_scope_real): Call push_to_top_level for
+ function in namespace scope.
+ (pop_access_scope): Call pop_from_top_level for function in
+ namespace scope.
+
+2003-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl): Don't set DECL_COMMON for __thread variables.
+
+2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+
+ * Make-lang.in (c++.install-common, c++.install-man,
+ c++.uninstall): Prepend $(DESTDIR) to destination paths in
+ all (un)installation commands.
+ (c++.install-common): Rewrite $(LN) commands to support
+ DESTDIR with "ln" as well as with "ln -s".
+
+2003-01-08 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_primary_expression): See through explicitly
+ scoped ALIAS_DECLs, too.
+
+2003-01-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * decl.c: Remove some #if 0 code.
+
+ * decl.c: ANSIfy function declarations.
+
+2003-01-07 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_asm_definition): Correct handling of omitted
+ operands.
+
+2003-01-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9030
+ * decl.c (make_typename_type): Check access only when tf_error.
+ (make_unbound_class_template): Likewise.
+ * pt.c (saved_access_scope): New variable.
+ (push_access_scope_real): New function.
+ (push_access_scope): Likewise.
+ (pop_access_scope): Likewise.
+ (tsubst_default_argument): Use them.
+ (instantiate_template): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ (instantiate_decl): Likewise.
+ (get_mostly_instantiated_function_type): Likewise.
+
+2003-01-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * tree.c: Delete bogus #if 0 code.
+
+2003-01-07 Andreas Schwab <schwab@suse.de>
+
+ * class.c (layout_class_type): Don't use
+ PCC_BITFIELD_TYPE_MATTERS if not defined.
+
+2003-01-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9165
+ * decl2.c (build_cleanup): Mark the object as used.
+
+ * pt.c (retrieve_local_specialization): Revert 2003-01-05 change.
+ (hash_local_specialization): New function.
+ (register_local_specialization): Revert 2003-01-05 change.
+ (instantiate_decl): Use hash_local_specialization when creating
+ the local_specializations table.
+
+ * decl2.c (mark_used): Do not synthesize thunks.
+
+ * class.c (layout_class_type): Correct handling of unnamed
+ bitfields wider than their types.
+
+ PR c++/9189
+ * parser.c (cp_parser): Remove default_arg_types. Update
+ documentation for unparsed_functions_queues.
+ (cp_parser_late_parsing_default_args): Take a FUNCTION_DECL as the
+ parameter.
+ (cp_parser_new): Don't set parser->default_arg_types.
+ (cp_parser_function_definition): Adjust usage of
+ unparsed_funtions_queues.
+ (cp_parser_class_specifier): Don't mess with
+ parser->default_arg_types. Handle default argument processing in
+ a separate phase from function body processing.
+ (cp_parser_template_declaration_after_export): Adjust usage of
+ unparsed_functions_queues.
+ (cp_parser_late_parsing_for_member): Do not handle default
+ arguments.
+
+2003-01-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9109
+ * parser.c (cp_parser_declarator_kind): New enum.
+ (cp_parser_declarator): Adjust.
+ (cp_parser_direct_declarator): Adjust. Allow for either named or
+ abstract declarator. Prefer abstract, if possible. Allow
+ parenthesized function name.
+ (cp_parser_condition): Adjust cp_parser_declarator call.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_type_id): Likewise.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_parameter_declaration): Use cp_parser_declarator to do
+ the tentative parsing.
+ (cp_parser_exception_declaration): Likewise.
+
+2003-01-05 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_template_parameter): Adjust call to
+ cp_parser_parameter_declaration.
+ (cp_parser_parameter_declaration_list): Likewise.
+ (cp_parser_parameter_declaration): Replace
+ greater_than_is_operator_p with template_parm_p parameter. Do not
+ cache tokens for template default arguments.
+
+ * pt.c (retrieve_local_specialization): Use htab_find, not
+ htab_find_with_hash.
+ (register_local_specialization): Use htab_find_slot, not
+ htab_find_slot_with_hash.
+ (instantiate_decl): Pass a hash function to htab_create.
+
+2003-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * parser.c (cp_parser_binary_expression,
+ cp_parser_multiplicative_expression,
+ cp_parser_additive_expression, cp_parser_shift_expression,
+ cp_parser_relational_expression, cp_parser_equality_expression,
+ cp_parser_and_expression, cp_parser_exclusive_or_expression,
+ cp_parser_inclusive_or_expression,
+ cp_parser_logical_and_expression, cp_parser_logical_or_expression,
+ cp_parser_binary_expression): Const-ify.
+
+2003-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Disable access control while building the
+ body of the thunk.
+
+2003-01-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cvt.c, decl.c, decl2.c: This is the C++ front end, not the C
+ front end.
+
+2003-01-03 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (struct lang_type_class): add field for key method
+ (cp_global_trees): rename dynamic_classes to keyed_classes
+ (key_method): add definition
+ * class.c (finish_struct_1): compute class's key method, and add
+ the class to keyed_classes list if there is no key method.
+ * decl.c (finish_function): add class to keyed_classes list if we
+ see a definition of the class's key method.
+ * pt.c (instantiate_class_template): add template specialization
+ of a dynamic class to keyed_classes list.
+ * decl2.c (key_method): remove
+ (finish_file): iterate only through keyed_classes list when
+ deciding whether to emit vtables, remove class from its list after
+ we do the emission.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Stabilize lvalues properly.
+ * cvt.c (ocp_convert): Don't build NOP_EXPRs of class type.
+ * tree.c (lvalue_p_1): Don't allow sloppy NOP_EXPRs as lvalues.
+ Don't allow CALL_EXPR or VA_ARG_EXPR, either.
+
+ * call.c (convert_like_real): Call decl_constant_value for an
+ IDENTITY_CONV even if there are no more conversions.
+
+ * cvt.c (build_up_reference): Don't push unnamed temps.
+
+ * decl2.c (do_namespace_alias): Namespace aliases are DECL_EXTERNAL.
+
+ * dump.c (cp_dump_tree): Don't try to dump class-specific fields
+ for a backend struct.
+
+ * except.c (wrap_cleanups_r, build_throw): Make
+ MUST_NOT_THROW_EXPRs void.
+ * init.c (expand_default_init): Update to handle MUST_NOT_THROW_EXPR.
+
+ * init.c (build_vec_delete_1): Pre-evaluate the base address.
+
+ * init.c (get_temp_regvar): Simplify logic.
+
+ * tree.c (cp_copy_res_decl_for_inlining): Only do debug tweaks if
+ our replacement is a decl.
+
+ * decl.c (cp_make_fname_decl): Push the decls inside the
+ outermost scope.
+
+2003-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/45, c++/3784
+ * tree.c (cp_tree_equal, TEMPLATE_PARM_INDEX): The types must be
+ the same too.
+
+2003-01-03 Graham Stott <graham.stott@btinternet.com>
+
+ * parser.c (struct cp_parser): Add access_checks_lists field
+ (cp_parser_simple_declaration): Use.
+ (cp_parser_init_declarator): Likewise.
+
+2003-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_declaration): Accept the __extension__
+ keyword before the declaration.
+
+ PR c++/2843
+ * parser.c (cp_parser_parameter_declaration): Allow attributes to
+ appear after the declarator.
+
+ * call.c (build_new_method_call): Fix typo in message format
+ string.
+
+2003-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_lexer_next_token_is): Declare it inline.
+ (cp_lexer_set_source_position_from_token): Likewise.
+ (cp_lexer_debugging_p): Likewise.
+ (cp_parser_parsing_tentatively): Likewise.
+ (cp_parser_nested_name_specifier_opt): Reduce the number of calls
+ to the cp_lexer_peek_token.
+
+ * parser.c (cp_parser_sizeof_operand): Do not evaluate the
+ expression.
+
+2003-01-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * cp/except.c, cp/expr.c, cp/friend.c, cp/g++spec.c,
+ cp/lang-options.h, cp/lang-specs.h, cp/lex.h, cp/ptree.c,
+ cp/repo.c: Fix copyright years.
+
+2003-01-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * lex.c: Remove superfluous include of cpplib.h.
+ (CONSTRAINT): Define without conditions.
+ (init_cp_pragma): Use c_register_pragma.
+
+2002-12-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * .cvsignore: Remove.
+
+2002-12-31 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * call.c, class.c, cp-lang.c, cp-tree.h, cvt.c, dump.c, error.c,
+ except.c, expr.c friend.c, g++spec.c, init.c, lang-options.h,
+ lang-specs.h, lex.c, mangle.c, method.c, optimize.c, parser.c,
+ pt.c, ptree.c, repo.c, rtti.c, search.c, semantics.c, tree.c,
+ typeck.c, typeck2.c: Replace "GNU CC" with "GCC" in the
+ copyright header.
+ * lex.h: parse.y is dead, so don't mention it. Also replace the
+ copyright header with the default GNU copyright header.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (LOOKUP_TEMPLATES_EXPECTED): Remove.
+ (lookup_name_namespace_only): Likewise.
+ (begin_only_namespace_names): Likewise.
+ (end_only_namespace_names): Likewise.
+ * decl.c (only_namespace_names): Remove.
+ (qualify_lookup): Do not check LOOKUP_TEMPLATES_EXPECTED.
+ (lookup_name_real): Do not check only_namespace_names.
+ (lookup_name_namespace_only): Remove.
+ (begin_only_namespace_names): Likewise.
+ (end_only_namespace_names): Likewise.
+ * parser.c (cp_parser_nested_name_specifier_opt): Handle erroneous
+ nested-name-specifiers more gracefully.
+ (cp_parser_class_or_namespace_name): Avoid looking up namespace
+ names when they cannot possibly appear.
+ (cp_parser_template_name): Adjust call to cp_parser_lookup_name.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_namespace_name): Only look for namespace names.
+ (cp_parser_lookup_name): Add is_namespace parameter.
+ (cp_parser_lookup_name_simple): Adjust call to
+ cp_parser_lookup_name.
+
+ * parser.c (cp_parser_dependent_type_p): Fix thinko.
+
+2002-12-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * .cvsignore: Update.
+
+2002-12-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (modify_vtable_entry): Remove unused variable.
+ (get_vcall_index): Always expect a non-thunk.
+ (update_vtable_entry_for_fn): Combine covariant adjustments, when
+ overriding a thunk. Pass get_vcall_index a non-thunk.
+
+ * decl2.c (finish_file): Mark undefined inlines as extern.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (RETURN_INIT): Remove.
+ * cp-tree.h (DECL_IN_MEMORY_P): Remove.
+ (scope_kind): Add sk_block, sk_try, sk_catch, sk_for.
+ (note_level_for_for): Remove.
+ (note_level_for_try): Likewise.
+ (note_level_for_catch): Likewise.
+ (finish_named_return_value): Likewise.
+ (do_pushlevel): Change prototype.
+ (pending_lang_change): Remove.
+ * decl.c (begin_scope): Handle sk_block, sk_try, sk_catch,
+ sk_for.
+ (note_level_for_for): Remove.
+ (note_level_for_try): Likewise.
+ (note_level_for_catch): Likewise.
+ (maybe_inject_for_scope_var): Remove use of DECL_IN_MEMORY_P.
+ * parser.c (cp_parser_context_free_list): Make it "deletable".
+ (cp_parser_template_argument): Remove misleading comment.
+ * pt.c (tsubst_expr): Remove RETURN_INIT code.
+ * semantics.c (genrtl_named_return_value): Remove.
+ (do_pushlevel): Take a scope kind as an argument.
+ (begin_if_stmt): Adjust.
+ (begin_while_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_init_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (begin_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_named_return_value): Remove.
+ (cp_expand_stmt): Remove RETURN_INIT case.
+ * tree.c (cp_statement_code_p): Remove RETURN_INIT case.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9112
+ * parser.c (cp_parser_direct_declarator): Handle erroneous
+ parenthesized declarators correctly.
+
+2002-12-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (pending_lang_change): Declare.
+
+2002-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_context_free_list): New variable.
+ (cp_parser_context_new): Use it.
+ (cp_parser_error): Check return code from
+ cp_parser_simulate_error.
+ (cp_parser_simulate_error): Return a value.
+ (cp_parser_id_expression): Optimize common case.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_class_specifier): Adjust call to
+ cp_parser_late_parsing_default_args.
+ (cp_parser_lookup_name): Optimize common case.
+ (cp_parser_late_parsing_for_member): Adjust call to
+ cp_parser_late_parsing_default_args.
+ (cp_parser_late_parsing_default_args): Add scope parameter.
+ (cp_parser_require): Avoid creating the error message unless it's
+ needed.
+ (cp_parser_parse_definitely): Place free'd contexts on the free
+ list.
+
+ * parser.c (cp_parser_declaration_seq_opt): Handle pending_lang_change.
+
+2002-12-30 David Edelsohn <edelsohn@gnu.org>
+
+ * parser.c (cp_parser_parameter_declaration_clause): Treat system
+ header as extern "C" if NO_IMPLICIT_EXTERN_C undefined.
+
+2002-12-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config-lang.in, Make-lang.in, operators.def, cp-tree.def:
+ GCC, not GNU CC.
+
+2002-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y: Remove.
+ * spew.c: Likewise.
+ * Make-lang.in (gt-cp-spew.h): Remove.
+ * cp-tree.h (do_pending_lang_change): Remove.
+ (do_identifier): Change prototype.
+ (finish_id_expr): Remove.
+ * decl.c (lookup_name_real): Remove yylex variable.
+ * decl2.c (build_expr_from_tree): Adjust call to do_identifier.
+ * lex.c (init_cpp_parse): Remove.
+ (reduce_cmp): Likewise.
+ (token_cmp): Likewise.
+ (yychar): Likewise.
+ (lastiddecl): Likewise.
+ (token_count): Likewise.
+ (reduce_count): Likewise.
+ (yyhook): Likewise.
+ (print_parse_statistics): Likewise.
+ (do_pending_lang_change): Likewise.
+ (do_identifier): Remove parsing parameter.
+ * lex.h (lastiddecl): Remove.
+ (looking_for_typename): Remove.
+ (looking_for_template): Likewise.
+ (pending_lang_change): Likewise.
+ (yylex): Likewise.
+ * semantics.c (finish_id_expr): Remove.
+
+ * decl.c (grokdeclarator): Diagnost "extern thread" and "static
+ thread" correctly.
+
+2002-12-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * decl.c, decl2.c, decl.h: GCC, not GNU CC. This is the C++ front
+ end, not the C front end.
+
+2002-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (THUNK_TARGET): New macro.
+ (THUNK_VIRTUAL_OFFSET): For result thunks it is always a binfo.
+ (finish_thunk): Remove offset parms.
+ * class.c (find_final_overrider): Look through thunks.
+ (get_vcall_index): Use THUNK_TARGET.
+ (update_vtable_entry_for_fn): Look through thunks. Set covariant
+ fixed offset here. Adjust finish_thunk call.
+ (build_vtbl_initializer): Adjust finish_thunk calls.
+ * mangle.c (mangle_call_offset): Remove superfluous if.
+ (mangle_thunk): Adjust.
+ * method.c (make_thunk): Adjust.
+ (finish_thunk): Adjust.
+ (thunk_adjust): Remove assert.
+ (use_thunk): Use THUNK_TARGET
+ * dump1.c (cp_dump_tree): Adjust thunk dumping.
+
+ PR c++/9054
+ * class.c (layout_class_type): Set TYPE_CONTEXT of type for base.
+ * dump.c (cp_dump_tree, RECORD_TYPE): Deal with type for base types.
+
+2002-12-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 4/n.
+ * decl2.c (grok_method_quals, warn_if_unknown_interface,
+ grok_x_components, cp_build_parm_decl, build_artificial_parm,
+ maybe_retrofit_in_chrg, grokclassfn, grok_array_decl,
+ delete_sanity, check_member_template, check_java_method,
+ check_classfn, finish_static_data_member_decl, grokfield,
+ grokbitfield, grokoptypename, grok_function_init,
+ cplus_decl_attributes, constructor_name, defer_fn,
+ build_anon_union_vars, finish_anon_union, coerce_new_type,
+ coerce_delete_type, comdat_linkage, maybe_make_one_only,
+ key_method, import_export_vtable, import_export_class,
+ output_vtable_inherit, import_export_decl, import_export_tinfo,
+ build_cleanup, get_guard, get_guard_bits, get_guard_cond,
+ set_guard, start_objects, finish_objects,
+ start_static_storage_duration_function,
+ finish_static_storage_duration_function, get_priority_info,
+ start_static_initialization_or_destruction,
+ finish_static_initialization_or_destruction,
+ do_static_initialization, do_static_destruction,
+ prune_vars_needing_no_initialization, write_out_vars,
+ reparse_decl_as_expr, finish_decl_parsing, namespace_ancestor,
+ add_using_namespace, merge_functions, ambiguous_decl,
+ lookup_using_namespace, lookup_using_namespace,
+ qualified_lookup_using_namespace, set_decl_namespace,
+ decl_namespace, current_decl_namespace, push_decl_namespace,
+ pop_decl_namespace, push_scope, pop_scope, add_function,
+ arg_assoc_namespace, arg_assoc_template_arg, arg_assoc,
+ lookup_arg_dependent, do_namespace_alias,
+ validate_nonmember_using_decl, do_nonmember_using_decl,
+ do_toplevel_using_decl, do_local_using_decl,
+ do_class_using_decl, do_using_directive, check_default_args,
+ mark_used, handle_class_head): Use C90 prototypings. Use booleans.
+ * parser.c (cp_parser_class_head): Use booleanss.
+ * decl.c (walk_globals, walk_vtables): Likewise.
+ * cp-tree.h (walk_globals_pred, walk_globals_fn, walk_vtables,
+ walk_globals): Change return type from 'int' to 'bool'.
+ * rtti.c (init_rtti_processing, build_headof, throw_bad_cast
+ throw_bad_typeid, get_tinfo_decl_dynamic, typeid_ok_p,
+ build_typeid, tinfo_name, get_tinfo_decl, get_tinfo_ptr,
+ get_typeid, ifnonnull, build_dynamic_cast_1, build_dynamic_cast,
+ qualifier_flags, tinfo_base_init, generic_initializer,
+ ptr_initializer, dfs_class_hint_mark, ptm_initializer,
+ dfs_class_hint_unmark, class_hint_flags, class_initializer,
+ typeinfo_in_lib_p, get_pseudo_ti_init, create_pseudo_type_info,
+ get_pseudo_ti_desc, create_tinfo_types, emit_support_tinfos,
+ unemitted_tinfo_decl_p, emit_tinfo_decl): Likewise.
+ * repo.c (repo_compile_flags, repo_template_declared,
+ repo_template_defined, repo_class_defined, repo_get_id,
+ repo_template_used, repo_vtable_used, repo_inline_used,
+ repo_tinfo_used, repo_template_instantiated, extract_string,
+ open_repo_file, afgets, init_repo, reopen_repo_file_for_write,
+ finish_repo): Likewise.
+ * ptree.c (cxx_print_decl, cxx_print_type, cxx_print_identifier,
+ cxx_print_xnode): Likewise..
+ * cp-lang.c (ok_to_generate_alias_set_for_type, cxx_get_alias_set,
+ cxx_warn_unused_global_decl, cp_expr_size): Likewise.
+ * cxxfilt.c (demangle_it, print_demangler_list, usage,
+ standard_symbol_characters, hp_symbol_characters, main, fatal):
+ Likewise.
+ (strip_underscore): Change type from 'int' to 'bool'.
+ (main): Use boolean constants.
+
+2002-12-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 3/n.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference, warn_ref_binding, convert_to_reference,
+ convert_from_reference, convert_lvalue, cp_convert, ocp_convert,
+ convert_to_void, convert, convert_force, build_type_conversion,
+ build_expr_type_conversion, type_promotes_to,
+ perform_qualification_conversions): Use C90 prototyping style.
+ * decl2.c (grok_array_decl): Use boolean constant.
+ (delete_sanity): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ * semantics.c (finish_switch_cond): Likewise.
+ * parser.c (cp_parser_direct_new_declarator): Likewise.
+ * init.c (build_new): Likewise.
+
+2002-12-27 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (po-generated): Remove parse.c.
+ (CXX_OBJS): Remove parse.o and spew.o. Add parser.o.
+ ($(srcdir)/cp/parse.h): Remove target.
+ ($(srcdir)/cp/parse.c): Likewise.
+ (gt-cp-parse.h): Likewise.
+ (gt-cp-parser.h): New target.
+ (c++.distclean): Do not remove parse.output.
+ (c++.maintainer-clean): Do not remove parse.c or parse.h.
+ (cp/spew.o): Remove target.
+ (cp/lex.o): Adjust dependencies.
+ (cp/pt.o): Likewise.
+ (cp/parse.o): Likewise.
+ (cp/TAGS): Do not mention parse.c.
+ (cp/parser.o): New target.
+ * NEWS: Mention the new parser.
+ * call.c (build_scoped_method_call): Simplify.
+ (build_method_call): Likewise.
+ (build_new_function_call): Adjust calls to add_function_candidate
+ and add_template_candidate.
+ (build_new_op): Improve handling of erroroneous operands.
+ (convert_default_arg): Remove circular argument processing.
+ (name_as_c_string): New function.
+ (build_new_method_call): Use it.
+ (perform_implicit_conversion): Use error_operand_p.
+ * class.c (finish_struct_anon): Use constructor_name_p.
+ (check_field_decls): Likewise.
+ (pop_nested_class): Use OVL_NEXT, not OVL_CHAIN.
+ (resolve_address_of_overloaded_function): Likewise.
+ (instantiate_type): Tweak pointer-to-member handling.
+ (get_primary_binfo): Remove incorrect assertion.
+ * config-lang.in (gtfiles): Add parser.c, remove parse.c.
+ * cp-tree.h (DEFARG_TOKENS): New macro.
+ (default_arg): New structure.
+ (cp_tree_node_structure_enum): Add TS_CP_DEFAULT_ARG.
+ (lang_tree_node): Add default_arg.
+ (cp_tree_index): Add CPTI_TYPE_INFO_REF_TYPE.
+ (type_info_ref_type): New macro.
+ (saved_scope): Make processing_explicit_instantiation a boolean.
+ (check_access): New field.
+ (unparsed_text): Remove.
+ (language_function): Remove unparsed_inlines.
+ (error_operand_p): New macro.
+ (lang_decl): Adjust pending_inline_info.
+ (DEFARG_POINTER): Remove.
+ (tag_types): Add typenames.
+ (lookup_ualified_name): Declare.
+ (lookup_name_real): Likewise.
+ (shadow_tag): Adjust prototype.
+ (get_scope_of_declarator): Declare it.
+ (process_next_inline): Remove it.
+ (check_for_missing_semicolon): Likewise.
+ (maybe_get_template_decl_from_type_decl): Declare it.
+ (finish_label_stmt): Adjust prototype.
+ (finish_non_static_data_meber): Declare it.
+ (finish_pseudo_destructor_call_expr): Rename to ...
+ (finish_pseudo_destructor_expr): ... this.
+ (finish_compound_literal): Declare it.
+ (begin_inline_definitions): Remove it.
+ (init_spew): Remove.
+ (peekyylex): Likewise.
+ (arbitrate_lookup): Likewise.
+ (frob_opname): Likewise.
+ (maybe_snarf_defarg): Likewise.
+ (add_defarg_fn): Likewise.
+ (do_pending_defargs): Likewise.
+ (done_pending_defargs): Likewise.
+ (unprocessed_defarg_fn): Likewise.
+ (replace_defarg): Likewise.
+ (end_input): Likewise.
+ (get_overloaded_fn): Likewise.
+ * cvt.c (convert_to_reference): Improve error handling.
+ * decl.c (lookup_name_real): Do not declare it static.
+ (maybe_push_to_top_level): Set check_access.
+ (identifier_type_value): Adjust call to lookup_name_real.
+ (lookup_qualified_name): New method.
+ (lookup_name_real): Remove special-case parsing code.
+ (lookup_name-nonclass): Adjust call to lookup_name_real.
+ (lookup_name_namespace_only): Likewise.
+ (lookup_name): Likewise.
+ (check_tag_decl): Return the type declared.
+ (shadow_tag): Likewise.
+ (register_dtor_fn): Tweak check_access.
+ (grokfndecl): Use constructor_name_p.
+ (get_scope_of_declarator): New function.
+ (grokdeclarator): Obscure tweaks for slightly different declarator
+ representations.
+ (start_method): Return error_mark_node to indicate failure.
+ (cp_tree_node_structure_enum): Use TS_CP_DEFAULT_ARG for DEFAULT_ARGs.
+ * decl2.c (constructor_name_full): Simplify.
+ (constructor_name): Use it.
+ (build_expr_from_tree): Adjust for changes to do new parser.
+ (push_scope): Improve robustness.
+ (validate_nonmember_using_decl): Process declarations, not names.
+ (do_class_using_decl): Likewise.
+ (handle_class_head): Do not mess with CLASSTYPE_DECLARED_CLASS
+ here.
+ * error.c (dump_expr): Handle IDENTIFIER_NODEs and BASELINKs.
+ * expr.c (cxx_expand_expr): Handle BASELINKs.
+ * init.c (member_init_ok_or_else): Issue more errors.
+ (build_offset_ref): Tweak handling of FUNCTION_DECLs.
+ * lex.c: Do not include parse.h.
+ (yypring): Do not declare.
+ (yylval): Likewise.
+ (make_reference_declarator): Remove error-generating code.
+ (rid_to_yy): Remove.
+ (cxx_init): Do not call init_spew.
+ (yypring): Remove.
+ (check_for_missing_semicolon): Remove.
+ * lex.h (got_scope): Remove.
+ (got_object): Remove.
+ * method.c (hack_identifier): Use finish_non_static_data_member.
+ (implicitly_declare_fn): Adjust use of constructor_name.
+ * parser.c: New file.
+ * pt.c (parse.h): Do not include it.
+ (maybe_get_template_decl_from_template): Do not declare it.
+ (finish_member_template_decl): Tweak.
+ (begin_explicit_instantiation): Adjust for
+ processing_explicit_instantiation being boolean.
+ (end_explicit_instantiation): Likewise.
+ (maybe_process_partial_specialization): Tighten specialization
+ test.
+ (retrieve_local_specialization): Adjust ue of hash table.
+ (eq_local_specializations): New function.
+ (register_local_specialization): Likewise.
+ (push_template_decl_real): Remove unnecessary test.
+ (maybe_get_template_decl_from_type_decl): Don't make it static.
+ (for_each_template_parm_r): Handle TYPEOF_TYPE.
+ (tsubst_copy): Use retrieive_local_specialization to handle
+ PARM_DECL. Adjust handling of CONST_DECLs. Handle BASELINKs.
+ Handle COMPONENT_REFs with pseudo-destructor-expressions.
+ Simplify handling of CALL_EXPR and METHOD_CALL_EXPR.
+ (tsubst_expr): Pass decls, not names, to do_local_using_decl.
+ (unify): Tweak handling of CONST_DECLs.
+ (regenerate_decl_from_template): Use push_nested_class.
+ (template_for_substitution): New funciton.
+ (instantiate_decl): Use it. Register parameters as local
+ specializations.
+ * rtti.c (init_rtti_processing): Set type_info_ref_type.
+ (build_typeid): Use it.
+ (get_typeid): Likeise.
+ * search.c (accessible_p): Use check_access, not
+ flag_access_control.
+ (adjust_result_of_qualified_name_lookup): Pay attention to the
+ context_class.
+ * semantics.c (finish_asm_stmt): Adjust error handling.
+ (finish_label_stmt): Return the statement.
+ (finish_non_static_data_member): New function.
+ (finish_class_expr): Handle BASELINKs.
+ (finish_call_expr): Handle PSEUDO_DTOR_EXPR.
+ (finish_object_call_expr): Simplify handling during templates.
+ (finish_pseudo_destructor_call_expr): Rename to ...
+ (finish_pseudo_dtor_expr): ... this.
+ (finish_compound_literal): New function.
+ (begin_inline_definitions): Remove.
+ (finish_sizeof): Remove special template handling.
+ * spew.c: Do not include parse.h.
+ * tree.c (get_overloaded_fn): Remove.
+ * typeck.c (build_class_member_access_expr): Handle
+ PSEUDO_DTOR_EXPR. Adjust handling of static member functions.
+ (lookup_destructor): New function.
+ (finish_class_member_access_expr): Use it.
+ (convert_arguments): Simplify.
+ (build_unary_op): Handle BASELINKs.
+
+2002-12-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4803
+ * decl2.c (mark_used): Defer inline functions.
+ (finish_file): Merge deferred_fns loops. Check all used
+ inline functions have a definition.
+ * method.c (make_thunk): Thunks are not inline.
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated.
+
+2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR C++/7964
+ * cp-tree.h (resolve_scoped_fn_name): Prototype.
+ * call.c (resolve_scoped_fn_name): New function. Deal with
+ more template expansion. Broken out of ...
+ * parse.y (parse_finish_call_expr): ... here. Call it.
+ * decl2.c (build_expr_from_tree, CALL_EXPR): Use
+ resolve_scoped_fn_name and build_call_from_tree.
+
+ PR c++/9053
+ * decl.c (duplicate_decls): Templates may be disambiguated by
+ return type.
+
+ PR c++/8702
+ * decl2.c (check_classfn): Use lookup_fnfield_1. List all
+ conversion operators on failure.
+
+2002-12-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 2/n.
+ * call.c (tourney, build_field_call, equal_functions, joust,
+ compare_ics, build_over_call, build_java_interface_fn_ref,
+ convert_like_real, op_error, build_object_call, resolve_args,
+ build_vfield_ref, check_dtor_name, build_scoped_method_call,
+ build_addr_func, build_call, build_method_call, null_ptr_cst_p,
+ sufficient_parms_p, build_conv, non_reference, strip_top_quals,
+ standard_conversion, reference_related_p,
+ reference_compatible_p, convert_class_to_reference,
+ direct_reference_binding, reference_binding,
+ ,implicit_conversion, is_complete, promoted_arithmetic_type_p,
+ add_template_conv_candidate, any_viable, any_strictly_viable,
+ build_this, splice_viable, print_z_candidates,
+ build_user_type_conversion, build_new_function_call,
+ conditional_conversion, build_conditional_expr, build_new_op,
+ build_op_delete_call, enforce_access, call_builtin_trap,
+ convert_arg_to_ellipsis, build_x_va_arg, cxx_type_promotes_to,
+ convert_default_arg, type_passed_as, convert_for_arg_passing,
+ in_charge_arg_for_name, is_properly_derived_from,
+ maybe_handle_implicit_object, maybe_handle_ref_bind,
+ source_type, add_warning, can_convert, can_convert_arg,
+ perform_implicit_conversion, can_convert_arg_bad,
+ initialize_reference, add_conv_candidate,
+ add_template_candidate_real, add_template_candidate): Ansify.
+
+2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/8572
+ * cp-tree.h (grokoptypename): Add SCOPE parameter.
+ * decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type
+ if in a template scope.
+ * parse.y (unoperator): Return the scope.
+ (operator_name): Adjust grokoptypename call.
+
+2002-12-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t.
+ * decl.c (make_unbound_class_template): Adjust. Check for tf_error.
+ * pt.c (tsubst) [OFFSET_TYPE]: Check for tf_error.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix a typo.
+ * class.c: Fix comment typos.
+ * cp-tree.h: Likewise.
+
+2002-12-18 Jason Merrill <jason@redhat.com>
+
+ Handle anonymous unions at the tree level.
+ C++ ABI change: Mangle anonymous unions using the name of their
+ first named field (by depth-first search). Should not cause
+ binary compatibility problems, though, as the compiler previously
+ didn't emit anything for affected unions.
+ * cp-tree.def (ALIAS_DECL): New tree code.
+ * decl2.c (build_anon_union_vars): Build ALIAS_DECLs. Return the
+ first field, not the largest.
+ (finish_anon_union): Don't mess with RTL. Do set DECL_ASSEMBLER_NAME,
+ push the decl, and write it out at namespace scope.
+ * decl.c (lookup_name_real): See through an ALIAS_DECL.
+ (pushdecl): Add namespace bindings for ALIAS_DECLs.
+ * rtti.c (unemitted_tinfo_decl_p): Don't try to look at the name
+ of a decl which doesn't have one.
+ * typeck.c (build_class_member_access_expr): Don't recurse if
+ we already have the type we want.
+
+2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8099
+ * friend.c (make_friend_class): Allow partial specialization
+ when declaration is not a template friend.
+
+2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3663
+ * pt.c (lookup_template_class): Copy TREE_PRIVATE and
+ TREE_PROTECTED to created decl nodes.
+
+2002-12-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_base_field): Do not set DECL_PACKED on the
+ FIELD_DECL.
+
+2002-12-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (struct tree_srcloc): Use location_t.
+ (SOURCE_LOCUS): New.
+ (SRCLOC_FILE, SRCLOC_LINE): Adjust.
+
+2002-12-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_function): Also complain about no return in
+ templates.
+ * semantics.c (finish_return_stmt): Also call check_return_expr in
+ templates.
+ * typeck.c (check_return_expr): In a template, just remember that we
+ saw a return.
+
+2002-12-16 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Don't change the type
+ of the CALL_EXPR.
+
+ * semantics.c (do_pushlevel): Call pushlevel after adding the
+ SCOPE_STMT.
+ (do_poplevel): Call poplevel before adding the SCOPE_STMT.
+ * parse.y (function_body): Go back to using compstmt.
+ * decl.c (pushdecl): Skip another level to get to the parms level.
+
+ * call.c (build_new_method_call): Use is_dummy_object to determine
+ whether or not to evaluate the object parameter to a static member
+ function.
+
+2002-12-14 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Also prepend the
+ return slot for normal functions. Set CALL_EXPR_HAS_RETURN_SLOT_ADDR.
+ * tree.c (build_cplus_new): If the type isn't TREE_ADDRESSABLE,
+ don't bother with an AGGR_INIT_EXPR.
+ (cp_copy_res_decl_for_inlining): If the type isn't TREE_ADDRESSABLE,
+ just generate a new decl normally. Take return slot parm.
+ * cp-tree.h: Adjust prototype.
+
+2002-12-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/8031
+ * cvt.c (convert_to_pointer_force): Don't try comparing against
+ erronous type.
+
+2002-12-13 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h: Have the multiple-include guards around
+ the entire file.
+
+2002-12-10 David Edelsohn <edelsohn@gnu.org>
+
+ * cp/spew.c (feed_input): Change limit to last_pos and pos to cur_pos
+ for SPEW_DEBUG.
+ (snarf_method): Same.
+ (snarf_defarg): Same.
+
+2002-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8372
+ * pt.c (tsubst_copy): Handle destructor names more correctly.
+
+2002-12-10 Matt Austern <austern@apple.com>
+
+ * cp-tree.h: get rid of needs_virtual_reinit bit.
+
+2002-12-09 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Document removal of in-class initialization extension for
+ static data members of non-arithmetic, non-enumeration type.
+ * decl.c (check_static_variable_definition): Do not allow that
+ extension.
+ * decl2.c (grokfield): Do not call digest_init when processing
+ templates.
+
+2002-12-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (dump_expr): Fix format specifier warning.
+
+2002-12-04 Geoffrey Keating <geoffk@apple.com>
+
+ * class.c (finish_struct_1): Correct comment.
+ * cp-tree.c (DECL_SORTED_FIELDS): Likewise.
+
+2002-12-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/8799
+ * error.c (dump_expr): Don't ever try to dump a non-existent
+ expression.
+
+2002-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement covariant returns.
+ * cp-tree.h (IS_AGGR_TYPE_2): Remove.
+ (struct lang_decl_flags): Add this_thunk_p flag.
+ Rename vcall_offset to virtual_offset.
+ (struct lang_decl): Rename delta to fixed_offset.
+ (DECL_THIS_THUNK_P, DECL_RESULT_THUNK_P): New #defines.
+ (SET_DECL_THUNK_P): Add THIS_ADJUSTING arg.
+ (THUNK_DELTA, THUNK_VCALL_OFFSET): Rename to ...
+ (THUNK_FIXED_OFFSET, THUNK_VIRTUAL_OFFSET): ... here.
+ (make_thunk): Add this_adjusting arg.
+ (finish_thunk): Declare.
+ (mangle_thunk): Add this_adjusting arg.
+ * class.c (get_vcall_index): Use base function for lookup.
+ (update_vtable_entry_for_fn): Generate covariant thunk.
+ (finish_struct_1): Set DECL_VINDEX to NULL for thunks.
+ (build_vtbl_initializer): Use base function for lookup.
+ Finish covariant thunk here. Adjust thunk generation.
+ * dump.c (cp_dump_tree): Simplify DECL_GLOBAL_[CD]TOR_P handling.
+ Adjust thunk dumping.
+ * mangle.c (mangle_call_offset): New function.
+ (mangle_thunk): Adjust for covariant thunks.
+ * method.c (make_thunk): Adjust. Do not set name here.
+ (finish_thunk): New function. Set name here.
+ (use_thunk): Generate covariant thunks too.
+ (thunk_adjust): New function.
+ * search.c (covariant_return_p): Remove. Fold into ...
+ (check_final_overrider): ... here. Simplify.
+ * semantics.c (emit_associated_thunks): Walk covariant thunk lists.
+
+2002-12-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/8674
+ * call.c (build_over_call): Check specifically for TARGET_EXPR
+ when eliding.
+
+ PR c++/8461, c++/8625
+ * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
+ (cp_convert_parm_for_inlining): Remove.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+ Remove.
+ * cp-tree.h (ADDR_IS_INVISIREF): Remove.
+ * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.
+
+ * call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on
+ an ambiguous conversion.
+
+2002-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8688
+ * decl.c (reshape_init): Handle erroneous initializers.
+
+2002-12-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8720
+ * spew.c (remove_last_token): Make sure that last_chunk is set
+ correctly.
+
+ PR c++/8615
+ * error.c (dump_expr): Handle character constants with
+ TREE_OVERFLOW set.
+
+2002-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ DR 180
+ * decl.c (grokdeclarator): Require class-key for all friend class.
+ Output the correct type and context in the error message.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5919
+ * pt.c (unify): Use variably_modified_type_p to test validity of
+ template argument types.
+
+ PR c++/8727
+ * cp-tree.h (lang_type_class): Add typeinfo_var.
+ (CLASSTYPE_TYPEINFO_VAR): New macro.
+ * rtti.c (get_tinfo_decl): Use it.
+
+ PR c++/8663
+ * init.c (expand_member_init): Always get the main variant of a
+ base class.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8332
+ PR c++/8493
+ * decl.c (cxx_init_decl_processing): Use size_type_node, not
+ c_size_type_node.
+ * decl2.c (coerce_new_type): Likewise.
+ * except.c (do_allocate_exception): Likewise.
+
+2002-11-30 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c, class.c, cp-lang.c, cvt.c, cxxfilt.c, decl.c, decl2.c,
+ dump.c, error.c, except.c, expr.c, friend.c, g++spec.c, init.c,
+ lex.c, mangle.c, method.c, optimize.c, parse.y, pt.c, ptree.c,
+ repo.c, rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
+ typeck2.c: Include coretypes.h and tm.h.
+ * Make-lang.in: Update dependencies.
+
+2002-11-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8227
+ * decl.c (layout_var_decl): Deal gracefully with erroneous types.
+ (check_initializer): Validate the type of the initialized
+ variable, even if the initializer is absent.
+ * typeck.c (cp_type_quals): Deal gracefully with erroneous types.
+
+ PR c++/8214
+ * typeck.c (convert_for_assignment): Do not use
+ decl_constant_value on the operand.
+
+ PR c++/8511
+ * pt.c (instantiate_decl): Handle template friends defined outside
+ of the class correctly.
+
+2002-11-29 Joe Buck <jbuck@synopsys.com>
+
+ * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for
+ anonymous structs.
+
+2002-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (walk_subobject_offsets): Recur on binfos as well as on
+ types.
+ (layout_nonempty_base_or_field): Pass it a binfo when processing a
+ base class.
+ (layout_empty_base): Likewise.
+ (build_base_field): Likewise.
+
+2002-11-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_base_field): Make sure we get the canonical base
+ when descending through primary bases.
+
+2002-11-26 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (check_initializer): Don't error on initialisation of
+ a scalar with a brace-enclosed expression.
+
+2002-11-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (DECL_LANG_FLAG_4): Document more uses.
+ (template_parms_equal): Remove prototype.
+ * typeck.c (buuld_indirect_ref): Reformat.
+
+2002-11-25 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_vec_init): Use a FOR_STMT instead of an IF_STMT
+ and a DO_STMT.
+
+2002-11-25 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type_real): Correct handling of
+ array types.
+ * class.c (walk_subobject_offsets): Fix thinko.
+ (build_base_field): Record offsets of empty bases in primary
+ virtual bases.
+ (layout_class_type): Record offsets of empty bases in fields.
+
+ * search.c (is_subobject_of_p_1): Fix thinko.
+ (lookup_field_queue_p): Likewise.
+
+2002-11-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Reuse tail padding when laying out
+ virtual bases.
+
+2002-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * rtti.c (qualifier_flags): Fix thinko.
+
+2002-11-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 1/n.
+ * cp-tree.h (init_method, set_mangled_name_for_decl,
+ build_opfncall, hack_identifier, make_thunk, use_thunk,
+ synthesize_method, implicitly_declare_fn,
+ skip_artificial_parms_for, optimize_function, calls_setjmp_p,
+ maybe_clone_body): Remove use of PARAMS.
+
+ * method.c (do_build_assign_ref, do_build_copy_constructor,
+ synthesize_exception_spec, locate_dtor, locate_ctor, locate_copy):
+ Likewise.
+ (synthesize_method): Use 'bool' type and constants instead of
+ 'int'.
+ (locate_copy): Likewise.
+ (implicitly_declare_fn): Likewise.
+
+ * optimize.c (calls_setjmp_r, update_cloned_parm, dump_function):
+ Remove old-style declaration.
+ (maybe_clone_body): Use 'bool' type and constants.
+
+2002-11-21 Glen Nakamura <glen@imodulo.com>
+
+ PR c++/8342
+ * typeck.c (get_member_function_from_ptrfunc): Make sure that a
+ SAVE_EXPR for instance_ptr doesn't get evaluated first inside one
+ of the branches of a COND_EXPR.
+
+2002-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (for_each_template_parm): Free allocated memory.
+ * search.c (is_subobject_of_p_1): New function.
+ (is_subobject_of_p): Avoid walking virtual bases multiple times.
+
+2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * g++spec.c (lang_specific_spec_functions): New.
+
+2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * class.c: Likewise.
+ * decl2.c: Likewise.
+
+2002-11-14 Zack Weinberg <zack@codesourcery.com>
+
+ * search.c (dfs_push_decls): Do not try to reorder elements
+ 3..n of method_vec if method_vec has only two elements.
+ Reverse order of two tests to avoid accessing unallocated
+ memory.
+
+2002-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (dfs_find_final_overrider): Adjust so that the most
+ derived object is a binfo, rather than a class type.
+ (find_final_overrider): Likewise.
+ (add_vcall_offset_vtbl_entries_1): Simplify accordingly.
+ (add_vcall_offset): Likewise.
+
+2002-11-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8389
+ * pt.c (instantiate_template): Push class scope for member
+ functions.
+ (get_mostly_instantiated_function_type): Likewise. Don't call
+ tsubst on context. Remove CONTEXTP and TPARMSP parameters.
+ * cp-tree.h (get_mostly_instantiated_function_type): Adjust.
+ * mangle.c (write_encoding, write_unqualified_name): Adjust.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_vcall_offset_vtbl_entries_1): Correct ordering of
+ vcall offfsets. Split out ...
+ (add_vcall_offset): ... new function.
+
+ PR c++/8338
+ * pt.c (for_each_template_parm): Add htab parameter.
+ (process_partial_specialization): Adjust call.
+ (push_template_decl_real): Likewise.
+ (pair_fn_data): Add visited.
+ (for_each_template_parm_r): Avoid walking duplicates more than
+ once.
+ (uses_template_parms): Adjust call to for_each_template_parm.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_implicitly_declared_members): Put implicitly
+ declared functions at the end of TYPE_METHODs when -fabi-version
+ is at least 2.
+
+2002-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (finish_file): Correct spelling.
+
+2002-11-03 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_special_member_call): Do not try to lookup VTTs by
+ name.
+ * class.c (vtbl_init_data): Add generate_vcall_entries.
+ (get_vtable_decl): Do not look up virtual tables by name.
+ (copy_virtuals): Do not use BV_USE_VCALL_INDEX_P.
+ (set_primary_base): Do not set CLASSTYPE_RTTI.
+ (determine_primary_base): Likewise.
+ (get_matching_virtual): Remove.
+ (get_vcall_index): New function.
+ (update_vtable_entry_for_fn): Do not try to use virtual thunks
+ when they are not required. Assign vcall indices at this point.
+ (finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT.
+ Do update dynamic_classes.
+ (build_vtt): Do not add VTTs to the symbol table.
+ (build_ctor_vtbl_group): Likewise.
+ (build_vtbl_initializer): Simplify handling of vcall indices.
+ (build_vcall_offset_vtbl_entries): Pretend to build vcall offsets
+ for the most derived class.
+ (add_vcall_offset_vtbl_entries_1): But do not actually add them to
+ the vtable.
+ * cp-tree.h (dynamic_classes): New macro.
+ (lang_type_class): Remove rtti. Add vtables. Add vcall_indices.
+ (CLASSTYPE_RTTI): Remove.
+ (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove.
+ (CLASSTYPE_VCALL_INDICES): New macro.
+ (CLASSTYPE_VTABLES): Likewise.
+ (BV_USE_VCALL_INDEX_P): Remove.
+ (build_vtable_path): Remove.
+ * decl2.c (finish_vtable_vardecl): Remove.
+ (key_method): Remove #if 0'd code.
+ (finish_vtable_vardecl): Rename to ...
+ (maybe_emit_vtables): ... this.
+ (finish_file): Use it.
+ * search.c (look_for_overrides_here): Update comment.
+
+2002-11-01 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353 redux
+ * decl2.c (grokfield): Reject TYPE_DECLs with initializers.
+
+2002-10-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/8186
+ * cp-tree.h (ADDR_IS_INVISIREF): New macro.
+ * call.c (convert_for_arg_passing): Set it.
+ * except.c (stabilize_throw_expr): Recurse for such an arg.
+
+2002-10-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove init_priority.
+ (lang_decl): Add delta.
+ (GLOBAL_INIT_PRIORITY): Remove.
+ (THUNK_DELTA): Revise definition.
+ * decl2.c (start_objects): Don't set GLOBAL_INIT_PRIORITY.
+ * dump.c (cp_dump_tree): Don't dump it.
+
+2002-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8160
+ * typeck2.c (process_init_constructor): Call complete_array_type.
+
+ PR c++/8149
+ * decl.c (make_typename_type): Issue errors about invalid results.
+
+2002-10-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Core issue 287, PR c++/7639
+ * cp-tree.h (lang_type_class): Add decl_list field.
+ (CLASSTYPE_DECL_LIST): New macro.
+ (maybe_add_class_template_decl_list): Add declaration.
+ * class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST.
+ (unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST.
+ (maybe_add_class_template_decl_list): New function.
+ (add_implicitly_declared_members): Use it.
+ * decl.c (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ * friend.c (add_friend): Likewise.
+ (make_friend_class): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ (begin_class_definition): Initialize CLASSTYPE_DECL_LIST.
+ * pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST
+ to process members and friends in the order of declaration.
+
+2002-10-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8287
+ * decl.c (finish_destructor_body): Create the label to jump to
+ when returning from a destructor here.
+ (finish_function_body): Rather than here.
+
+2002-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ PR c++/7266
+ * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
+ SCOPE_REF is not null before dereferencing it.
+
+2002-10-25 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Use DECL_CONTEXT, not
+ DECL_VIRTUAL_CONTEXT.
+ * class.c (modify_vtable_entry): Don't mess with
+ DECL_VIRTUAL_CONTEXT.
+ (set_vindex): Remove.
+ (set_primary_base): Remove vfuns_p parameter.
+ (determine_primary_base): Likewise.
+ (modify_all_vtables): Likewise.
+ (layout_class_type): Likewise. Adjust calls to other functions
+ accordingly.
+ (finish_struct_1): Adjust calls to modified functions. Set
+ DECL_VINDEX here.
+ * cp-tree.h (lang_type_class): Remove vsize.
+ (CLASSTYPE_VSIZE): Remove.
+ (lang_decl): Remove thunks.
+ (DECL_THUNKS): Adjust.
+ (DECL_VIRTUAL_CONTEXT): Remove.
+ (duplicate_decls): Don't copy it.
+ * pt.c (build_template_decl): Don't set it.
+ (tsubst_decl): Likewise.
+ * typeck.c (expand_ptrmemfunc_cst): Don't use it.
+
+ * class.c (build_vtbl_initializer): Don't use build_vtable_entry.
+ (build_vtable_entry): Remove.
+ * cp-tree.h (BINFO_VIRTUALS): Expand documentation.
+ (lang_decl): Add thunks.
+ (DECL_THUNKS): New macro.
+ * decl.c (duplicate_decls): Copy it.
+ * method.c (make_thunk): Simplify, and add thunks to DECL_THUNKS.
+ * semantics.c (emit_associated_thunks): Simplify.
+
+2002-10-24 David Edelsohn <edelsohn@gnu.org>
+
+ PR c++/7228
+ * cp-tree.h (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Check that
+ lang_type structure exists before accessing field.
+ (SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT): New macro.
+ (CLASSTYPE_REF_FIELDS_NEED_INIT): Similar.
+ (SET_CLASSTYPE_REF_FIELDS_NEED_INIT): New macro.
+ * class.c (check_field_decls): Use new macros.
+ * typeck2.c (process_init_constructor): Remove redundant check for
+ existence of lang_type structure.
+
+2002-10-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (end_of_base): New method.
+ (end_of_class): Use it. Check indirect virtual bases.
+
+ * class.c (check_field_decls): Fix typo.
+
+2002-10-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8067
+ * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and
+ related variables.
+
+ PR c++/7679
+ * spew.c (next_token): Do not return an endless stream of
+ END_OF_SAVED_INPUT tokens.
+ (snarf_method): Add three END_OF_SAVED_INPUT tokens to the end of
+ the cached token stream.
+ (snarf_defarg): Likewise.
+
+2002-10-23 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c (cp_var_mod_type_p): New: C++ hook for
+ variably_modified_type_p.
+ * cp-tree.h: Remove prototype of variably_modified_type_p.
+ * tree.c (variably_modified_type_p): Remove; now implemented
+ in language-independent code.
+
+2002-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6579
+ * spew.c (snarf_parenthesized_expression): New function.
+ (snarf_block): Use it.
+
+2002-10-22 Richard Henderson <rth@redhat.com>
+
+ * method.c (use_thunk): Always compute vcall_value; assert that
+ it is not zero. Use can_output_mi_thunk; use output_mi_thunk
+ for vcall thunks as well.
+
+2002-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (empty_base_at_nonzero_offset_p): New function.
+ (layout_nonempty_base_or_field): Do not check for conflicts when
+ laying out a virtual base using the GCC 3.2 ABI.
+ (build_base_field): Correct checking for presence of empty classes
+ at nonzero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.
+
+ * class.c (include_empty_classes): Use normalize_rli.
+ (layout_class_type): Likewise.
+
+ * decl.c (reshape_init): Tweak handling of character arrays.
+
+ PR c++/8218
+ * cp-tree.h (lang_type_class): Add contains_empty_class_p.
+ (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
+ * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
+ (check_field_decls): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Initialize it.
+ (walk_subobject_offsets): Use it to prune searches.
+
+2002-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Compute the vcall index as a HOST_WIDE_INT.
+ * optimize.c (optimize_function): Replace ASM_OUTPUT_MI_THUNK with
+ TARGET_ASM_OUTPUT_MI_THUNK in comments.
+
+2002-10-18 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (start_decl): Point users of the old initialized-
+ typedef extension at __typeof__.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (method.o): Depend on TARGET_H.
+ * method.c (target.h): Include it.
+ (use_thunk): Use target hooks. Use vcall thunks, if available.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (base_derived_from): Make sure return value is a bool.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (find_final_overrider_data_s): Remove overriding_fn and
+ overriding_base.
+ (dfs_base_derived_from): New function.
+ (base_derived_from): Likewise.
+ (dfs_find_final_overrider): Use base_derived_from.
+ (find_final_overrider): Adjust.
+
+2002-10-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/8080
+ * semantics.c (finish_for_cond, finish_while_cond): Don't mess
+ with condition decls in a template.
+
+2002-10-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Compare template parms too.
+
+2002-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7584
+ * class.c (handle_using_decl): Allow the declaration used to be
+ from an ambiguous base.
+
+ * pt.c (convert_template_argument): Revert this change:
+ 2002-10-16 Mark Mitchell <mark@codesourcery.com>
+ * pt.c (convert_template_argument): Do not fold non-type
+ template rguments when inside a template.
+
+ * init.c (expand_default_init): Handle brace-enclosed initializers
+ correctly.
+
+2002-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_expression): Correct handling of enumeration
+ constants.
+ (write_template_arg): Likewise.
+ * pt.c (convert_template_argument): Do not fold non-type template
+ arguments when inside a template.
+
+ PR c++/7478
+ * cvt.c (convert_to_reference): Allow references as the incoming
+ type.
+
+2002-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7524
+ * method.c (do_build_assign_ref): Use cp_build_qualified_type, not
+ build_qualified_type.
+
+2002-10-15 Richard Henderson <rth@redhat.com>
+
+ * error.c (dump_expr): Use real_to_decimal directly, and with
+ the new arguments.
+
+2002-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (reshape_init): Fix typo.
+
+ * cp-tree.h (operator_name_info_t): Add arity.
+ * lex.c (init_operators): Initialize it.
+ * mangle.c (write_conversion_operator_name): New function.
+ (write_unqualified_name): Use it.
+ (write_template_args): Accept template arguments as a TREE_LIST.
+ (write_expression): Adjust handling of qualified names to match
+ specification.
+
+2002-10-15 Jason Merrill <jason@redhat.com>
+
+ * call.c (call_builtin_trap): New fn.
+ (convert_arg_to_ellipsis): Use it. Downgrade error to warning.
+ (build_call): Don't set current_function_returns_abnormally outside
+ a function.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Remove empty_p parameter. Instead,
+ clear CLASSTYPE_EMPTY_P.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (check_bases_and_members): Likewise.
+ (create_vtbl_ptr): Likewise.
+ (layout_class_type): Likewise. Ensure that empty classes have
+ size zero when used as base classes in the 3.2 ABI.
+ (finish_struct_1): Initialize CLASSTYPE_EMPTY_P and
+ CLASSTYPE_NEARLY_EMPTY_P. Adjust calls to avoid passing empty_p
+ parameter.
+ (is_empty_class): Correct definition when using post-3.2 ABI.
+ * cp-tree.h (lang_type_class): Add empty_p.
+ (CLASSTYPE_EMPTY_P): New macro.
+
+2002-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_delete): Do not apply save_expr for arrays.
+ (build_vec_delete): Likewise.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (layout_var_decl): Call layout_decl even for variables
+ whose type is an array with unspecified bounds.
+
+ PR c++/7176
+ * lex.c (do_identifier): Add another option for the parsing
+ parameter.
+ * parse.y (do_id): Use it.
+
+2002-10-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PRs C++/6803, C++/7721 and C++/7803
+ * decl.c (grokdeclarator): Gracefully handle template-name as
+ decl-specifier.
+
+2002-10-11 Jason Molenda <jmolenda@apple.com>
+
+ * init.c (build_field_list): Provide uses_unions_p with a default
+ value.
+
+2002-10-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5661
+ * cp-tree.h (variably_modified_type_p): New function.
+ (grokdeclarator) Tighten check for variably modified types as
+ fields.
+ * pt.c (convert_template_argument): Do not allow variably modified
+ types as template arguments.
+ * tree.c (variably_modified_type_p): New function.
+
+ * NEWS: Document removal of "new X = ..." extension.
+ * class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
+ brace-enclosed initializers.
+ * cp-tree.h (CP_AGGREGATE_TYPE_P): New macro.
+ (initialize_local_var): Remove declaration.
+ (expand_static_init): Likewise.
+ * decl.c (next_initializable_field): New function.
+ (reshape_init): Likewise.
+ (check_initializer): Use them. Build dynamic initializer for
+ aggregates here too.
+ (initialize_local_var): Simplify, and incorporate cleanup
+ insertion code as well.
+ (destroy_local_var): Remove.
+ (cp_finish_decl): Tidy.
+ (expand_static_init): Fold checks for whether or not a variable
+ needs initialization into this function. Simplify.
+ * decl2.c (do_static_initialization): Simplify.
+ * init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will
+ be done for us automatically.
+ (expand_default_init): Handle brace-enclosed initializers
+ correctly.
+ (expand_aggr_init_1): Remove RTL-generation code.
+ (build_vec_init): Remove "new X = ..." support.
+ * parse.y (new_initializer): Likewise.
+ * rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on
+ brace-enclosed initializer.
+ (create_pseudo_type_info): Likewise.
+ * typeck2.c (store_init_value): Don't try to handle digest_init
+ being called more than once.
+ (digest_init): Tidy handling of brace-enclosed initializers.
+
+2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (typename_hash): Use htab_hash_pointer.
+
+2002-10-10 Jim Wilson <wilson@redhat.com>
+
+ * decl.c (duplicate_decls): Don't call decl_attributes.
+
+2002-10-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353
+ * decl.c (start_decl): Unconditionally issue error for
+ 'typedef foo = bar'.
+ (cp_finish_decl): Remove special case for TYPE_DECL with initializer.
+ (grokdeclarator): Remove redundant error for 'typedef foo = bar'.
+
+2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (prune_vtable_vardecl): Delete unused function.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * decl2.c, pt.c: Revert c++/7754 fix.
+
+2002-10-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7804
+ * error.c (dump_expr) [REAL_CST]: Output in decimal format.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7931
+ * pt.c (for_each_template_parm_r): Handle BASELINKs.
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8006
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template
+ template parameters.
+ (globals): Add entity and need_abi_warning.
+ (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not
+ CLASSTYPE_TEMPLATE_INFO.
+ (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not
+ TYPE_TI_TEMPLATE.
+ (write_prefix): Handle typename types correctly.
+ (write_template_prefix): Handle template template parameters
+ correctly.
+ (start_mangling): Add entity parameter.
+ (finish_mangling): Warn about names whose mangling will change.
+ (mangle_decl_string): Adjust.
+ (mangle_type_string): Likewise.
+ (mangle_special_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_guard_variable): Likewise.
+ (mangle_ref_init_variable): Likewise.
+
+2002-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7188.
+ * cp-tree.def (CTOR_INITIALIZER): Use one slot, not two.
+ * cp-tree.h (emit_base_init): Rename to ....
+ (emit_mem_initializers): ... this.
+ (expand_member_init): Change prototype.
+ * init.c (perform_member_init): Compute explicit, rather than
+ requiring it as a parameter.
+ (sort_member_init): Rename to ...
+ (sort_mem_initializers): ... this. Process bases and data members
+ together.
+ (sort_base_init): Remove.
+ (emit_base_init): Rename to ...
+ (emit_mem_initializers): ... this.
+ (expand_aggr_vbase_init_1): Remove.
+ (construct_virtual_bases): Rename to ...
+ (construct_virtual_base): ... this.
+ (expand_member_init): Rework handling of base initializers.
+ * method.c (do_build_copy_constructor): Use
+ finish_mem_initializers.
+ * parse.y (member_init): Adjust calls to expand_member_init.
+ * pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case.
+ (tsubst_initializer_list): Use expand_member_init.
+ * semantics.c (finish_mem_intiailizers): Simplify.
+
+2002-10-02 Matt Austern <austern@apple.com>
+ * decl.c (walk_vtables_r): Fixed typo that caused result to
+ never get a nonzero value.
+
+2002-10-02 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6627
+ * cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition
+ from here, and move it to tree.h.
+ * decl.c (cxx_init_decl_processing): If storing the vbit
+ in function pointers, ensure that force_align_functions_log
+ is atleast one.
+
+2002-10-02 Matt Austern <austern@apple.com>
+
+ * class.c (check_field_decls): Changed warning about const member
+ variables so that it doesn't get issued for a class aggregate.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Make sure array types are laid out,
+ even if the array bounds are unknown.
+
+2002-10-01 Steve Ellcey <sje@cup.hp.com>
+
+ * class.c (build_vtbl_initializer): Change build_c_cast
+ to build1.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Make sure array types are laid out,
+ even if the array bounds are unknown.
+
+ * decl.c (cp_finish_decl): Correct check for dynamic
+ initialization of thread-local storage.
+
+2002-09-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (really_overloaded_fn): TEMPLATE_ID_EXPRs are also
+ overloaded.
+
+2002-09-30 Steve Ellcey <sje@cup.hp.com>
+
+ * class.c (build_vtbl_initializer): Add cast.
+ (add_vcall_offset_vtbl_entries_1):
+ Use TARGET_VTABLE_DATA_ENTRY_DISTANCE for offset.
+
+2002-09-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (walk_subobject_offsets): Correct the calculation of
+ offsets for virtual bases. Correct the counting of array
+ elements.
+ (layout_nonempty_base_or_field): Simplify. Correct the
+ calculation of offsets to be propagated through the binfo
+ hierarchy.
+ (build_base_field): Avoid creating a FIELD_DECL for empty bases.
+ Add the FIELD_DECL to TYPE_FIELDS.
+ (build_base_fields): Adjust accordingly.
+ (layout_virtual_bases): Use build_base_field.
+ (end_of_class): Return a tree, not an integer.
+ (warn_about_ambiguous_direct_bases): Rename to ...
+ (warn_about_ambiguous_bases): ... this.
+ (include_empty_classes): New function.
+ (layout_class_type): Create an alternative version of the type to
+ be used when as a base class type. Do not call
+ finish_record_layout until we are done laying out the class.
+ * cp-tree.h (lang_type_class): Remove size, size_unit. Add
+ as_base.
+ (CLASSTYPE_SIZE): Reimplement.
+ (CLASSTYPE_SIZE_UNIT): Likewise.
+ (CLASSTYPE_ALIGN): Likweise.
+ (CLASSTYPE_USER_ALIGN): Likewise.
+ (CLASSTYPE_AS_BASE): New macro.
+ (DECL_INITIALIZED_P): Likewise.
+ (extract_init): Remove prototype.
+ (build_forced_zero_init): Rename to ...
+ (build_zero_init): ... this.
+ (force_store_init_value): Remove.
+ * decl.c (obscure_complex_init): Remove.
+ (duplicate_decls): Copy DECL_INITIALIZED_P.
+ (check_initializer): Do not leave junk in DECL_INITIAL.
+ (cp_finish_decl): Handle zero-initialization of entities with
+ static storage duration.
+ * expr.c (extract_init): Remove.
+ * init.c (build_forced_zero_init): Remove.
+ (build_zero_init): New function.
+ (build_default_init): Use it.
+ (build_field_list): Skip FIELD_DECLs for base subobjects.
+ (push_base_cleanups): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ (synthesize_exception_spec): Likewise.
+ * pt.c (tsubst_decl): Clear DECL_INITIALIZED_P.
+ (regenerate_decl_from_template): To not set DECL_INITIAL for a
+ static data member whose initialization took place in its class.
+ (instantiate_decl): Do not pass an initializer to cp_finish_decl
+ in that situation.
+ * search.c (dfs_push_decls): Skip FIELD_DECLs for base subobjects.
+ (dfs_unuse_fields): Likewise.
+ * tree.c (pod_type_p): Handle error_mark_node.
+ (zero_init_p): Likewise.
+ * typeck.c (lookup_anon_field): Skip FIELD_DECLs for base
+ subobjects.
+ * typeck2.c (store_init_value): Remove #if 0'd code.
+ (force_store_init_value): Remove.
+ (process_init_constructor): Use build_zero_init.
+
+2002-09-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7788
+ * rtti.c (unemitted_tinfo_decl_p): Check it has a field.
+
+2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Fix comment typos.
+ * decl.c: Likewise.
+ * pt.c: Likewise.
+
+2002-09-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (contains_empty_class_p): New method.
+ (walk_subobject_offsets): Correct computation of field offset.
+ (layout_empty_base): Correct placement of emtpy base classes.
+ (layout_class_type): Warn about ABI changes.
+
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (layout_virtual_bases): Do not round the size of the
+ type to a multiple of the alignment before laying out virtual bases.
+ (layout_class_type): Correct handling of bit-fields that are wider
+ than their type inside unions. Round the size of the type to a
+ even number of bytes when computing the size without virtual
+ bases.
+ * cp/cp-tree.h (abi_version_at_least): New macro.
+
+2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.2: Likewise.
+ * call.c: Likewise.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * friend.c: Likewise.
+ * g++spec.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * operators.def: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2002-09-18 Devang Patel <dpatel@apple.com>
+
+ * cp/cp-tree.h: New prototype for walk_vtabls().
+ * cp/decl.c (walk_vtables_r): New function.
+ (struct cp_binding_level): Add new members, namespaces,
+ names_size and vtables.
+ (add_decl_to_level): Add decl in namespaces or vtables
+ chain, if conditions match.
+ (walk_vtables): New function.
+ (walk_namespaces_r): Travers separate namespace chain
+ for namespace decls.
+ (wrapup_globals_for_namespace): Use names_size instead
+ of list_length().
+ * cp/decl2.c (finish_file): Use walk_vtables() instead of
+ walk_globals() to walk vtable decls.
+
+2002-09-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Use assert, not internal_error. Don't
+ ICE with invalid pointers & references.
+
+2002-09-17 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Remove all references to the demangler.
+ * cxxfilt.c: Moved to binutils.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7718
+ * pt.c (tsubst_decl): Remove assert.
+
+ Remove DR 295 implementation.
+ * pt.c (check_cv_quals_for_unify): Disable function & method cases.
+ * tree.c (cp_build_qualified_type_real): Likewise. Don't warn
+ about ignoring volatile qualifiers.
+
+ * search.c (lookup_member): Correct documentation.
+
+2002-09-16 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (union lang_tree_node): Add chain_next option.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (parse_finish_call_expr): Check lookup_member result.
+
+ PR c++/7015
+ * semantic.c (finish_asm_stmt): Fix operand/output_operands
+ thinko.
+ * typeck.c (c_expand_asm_operands): Protect from error_mark_node.
+
+2002-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7919
+ * call.c (build_over_call): Convert this pointer for fns found by
+ using decls.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.1: Likewise.
+
+2002-09-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7768
+ * pt.c (build_template_decl): Copy DECL_DESTRUCTOR_P.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * error.c: Fix comment formatting.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * friend.c: Likewise.
+ * g++spec.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2002-09-13 Matt Austern <austern@apple.com>
+
+ PR C++/7828
+ * cp/cp-tree.h, cp/tree.c: New function non_cast_lvalue_p.
+ * cp/call.c: Change call-by-const-reference mechanism to use
+ non_cast_lvalue_p when deciding whether the create a temporary.
+ We need a temporary when passing, e.g. (long) x by const ref.
+
+2002-09-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify, ARRAY_TYPE): Element type can be more qualified.
+
+2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c: Fix comment formatting.
+ * decl2.c: Likewise.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-lang.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+
+2002-09-11 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Build cp/cxxfilt.o from $(srcdir)/cp/cxxfilt.c,
+ and c++filt from cxxfilt.o + version.o + $(LIBDEPS).
+ * cxxfilt.c: New file: split from libiberty/cplus-dem.c, with
+ minor adjustments (use version_string, eliminate yet another
+ duplicate of xmalloc)
+
+2002-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (require_complete_eh_spec_types): Add prototype.
+
+2002-09-05 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (add_exception_specifier): Only pedwarn for an
+ incomplete type.
+ (require_complete_eh_spec_types): New fn.
+ (cxx_incomplete_type_diagnostic): Also support pedwarning.
+ * typeck.c (complete_type_or_diagnostic): Likewise.
+ * call.c (build_call): Call require_complete_eh_spec_types.
+ * rtti.c (get_pseudo_ti_desc): Give an error rather than aborting
+ on an incomplete type.
+
+2002-09-04 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_cleanup_fn): Clear interface_only before
+ start_function, restore it afterwards.
+
+2002-09-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_builtin_type): Remove.
+ * decl2.c (finish_builtin_type): Move to common code.
+ * decl.c (build_ptrmemfunc_type): Adjust.
+ * rtti.c (create_pseudo_type_info): Adjust.
+ (create_tinfo_types): Adjust.
+
+2002-08-31 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (cp_expr_size): Allow initialization from a
+ CONSTRUCTOR.
+
+2002-08-30 Richard Henderson <rth@redhat.com>
+
+ PR opt/7515
+ * tree.c: Include target.h.
+ (cp_cannot_inline_tree_fn): Don't auto-inline functions that
+ don't bind locally.
+ * Makefile.in (tree.o): Update.
+
+2002-08-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_virtual_bases): Warn about bugs in G++ that
+ result in incorrect object layouts.
+ (layout_class_type): Likewise.
+
+2002-08-24 Matt Austern <austern@apple.com>
+
+ * tree.c (lvalue_p_1): Add argument for whether casts of lvalues
+ are allowable.
+ (real_lvalue_p): Update caller.
+ (lvalue_p): Ditto.
+ (non_cast_lvalue_or_else): New.
+ * tree.h: Declare it.
+ * typeck.c (build_unary_op): Use non_cast_lvalue_or_else.
+
+2002-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR
+ and COND_EXPR specially; fix error message output.
+
+2002-08-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_expr): RETURN_EXPR is now RETURN_STMT_EXPR.
+ * semantics.c (nullify_returns_r): Likewise.
+
+2002-08-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Fix PR/7621
+ * typeck.c (finish_class_member_access_expr): Diagnose cases where
+ name lookup finds nothing.
+
+2002-08-15 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_then_clause): Remove redundant assignment.
+ (finish_if_stmt, begin_switch_stmt, finish_switch_stmt): Move the
+ extra binding level outside the if/switch statement.
+ (finish_while_cond, finish_for_cond): Rewrite complex condition
+ into the loop body.
+
+2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * parse.y (sizeof, alignof, typeof): New non-terminals to
+ increment skip_evaluation. Replace terminals with them and
+ decrement skip_evaluation at the end of rules using them.
+ * decl2.c (mark_used): Don't assemble_external if
+ skipping evaluation.
+
+2002-08-15 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7504
+ * parse.y (parse_finish_call_expr): Handle incomplete
+ type used to name a scope.
+
+2002-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7598
+ * typeck.c (build_unary_op): Fold offsetof idiom. Fixes
+ regression caused by my 2002-08-08 patch.
+
+2002-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl_class_level): Honor requests to bind names to
+ OVERLOADs.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (build_call_from_tree): Fix uninitialized variable.
+ * parse.y (parse_finish_call_expr): Likewise.
+ * repo.c (old_args, old_dir, old_main): Const-ify.
+
+2002-08-11 Gabriel Dos Reis <gdr@nerim.net>
+
+ * decl.c (duplicate_decls): Replace DECL_SOURCE_FILE
+ DECL_SOURCE_LINE with DECL_SOURCE_LOCATION.
+ * optimize.c (maybe_clone_body): Likewise.
+ * pt.c (tsubst_enum): Likewise.
+ (lookup_template_class): Likewise.
+ * tree.c (cp_copy_res_decl_for_inlining): Likewise.
+
+2002-08-10 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-specs.h: Remove -ansi.
+
+2002-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (maybe_dummy_object): Replace // with /* */
+
+2002-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Use build_ptrmem_type.
+ * cp-tree.h (build_ptrmem_type): New function.
+ (adjust_result_of_qualified_name_lookup): Likewise.
+ * decl.c (grokvardecl): Do not look for OFFSET_TYPEs to indicate
+ static data members.
+ (build_ptrmem_type): New function.
+ (grokdeclarator): Do not use build_offset_type when encountering a
+ qualified name.
+ * parse.y (parse_finish_call_expr): Use
+ adjust_result_of_qualified_name_lookup.
+ * search.c (adjust_result_of_qualified_name_lookup): New function.
+ * typeck.c (qualify_type_recursive): Use TYPE_PTRMEM_* rather than
+ accessing OFFSET_TYPEs directly.
+
+2002-08-08 Mike Stump <mrs@apple.com>
+
+ * call.c (add_builtin_candidate): legal -> valid, illegal -> invalid.
+ (type_decays_to): Likewise.
+ * class.c (find_final_overrider): Likewise.
+ (maybe_note_name_used_in_class): Likewise.
+ * decl.c (current_tmpl_spec_kind): Likewise.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (duplicate_decls): Likewise.
+ (layout_var_decl): Likewise.
+ (grokfndecl): Likewise.
+ (grokdeclarator): Likewise.
+ (check_default_argument): Likewise.
+ * decl2.c (handle_class_head): Likewise.
+ * error.c (dump_template_decl): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * pt.c (check_specialization_scope): Likewise.
+ (determine_specialization): Likewise.
+ (check_explicit_specialization): Likewise.
+ (maybe_check_template_type): Likewise.
+ (process_partial_specialization): Likewise.
+ (check_default_tmpl_args): Likewise.
+ (push_template_decl_real): Likewise.
+ (convert_template_argument): Likewise.
+ (try_class_unification): Likewise.
+ (get_bindings_real): Likewise.
+ (do_decl_instantiation): Likewise.
+ * semantics.c (begin_function_definition): Likewise.
+ (finish_member_declaration): Likewise.
+ (check_multiple_declarators): Likewise.
+ * typeck.c (comp_array_types): Likewise.
+ (comptypes): Likewise.
+ (expr_sizeof): Likewise.
+ (build_binary_op): Likewise.
+ (dubious_conversion_warnings): Likewise.
+ (check_return_expr): Likewise.
+
+2002-08-08 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_class_member_access_expr): Do not return
+ error_mark_node when no error has occurred.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_component_addr): Remove.
+ (build_unary_op): Just check it's not a bitfield, and then build
+ an ADDR_EXPR.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (convert_to_base): Correct check for error_mark_node.
+ (create_vtable_ptr): Remove unused VFUNS_P parm.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp/Make-lang.in (c++.mostlyclean): Remove coverage files.
+
+2002-08-07 Mark Mitchell <mark@codesourcery.com>
+
+ Rework build_component_ref.
+ * call.c (build_vfield_ref): Do not go through build_component_ref.
+ (build_field_call): Use build_class_member_access_expr.
+ (build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
+ (build_object_call): Likewise.
+ * class.c (convert_to_base): New function.
+ (type_requires_array_cookie): Use BASELINK_FUNCTIONS.
+ (instantiate_type): Handle BASELINKs.
+ * cp-tree.def (BASELINK): New tree code.
+ * cp-tree.h (BASELINK_P): Reimplement.
+ (SET_BASELINK_P): Remove.
+ (BASELINK_BINFO): Reimplement.
+ (BASELINK_FUNCTIONS): Likewise.
+ (BASELINK_ACCESS_BINFO): Likewise.
+ (BASELINK_OPTYPE): Likewise.
+ (convert_to_base): New function.
+ (name_p): Likewise.
+ (build_object_ref): Remove.
+ (build_component_ref_1): Likewise.
+ (build_component_ref): Likewise.
+ (build_x_component_ref): Likewise.
+ (build_class_member_access_expr): New function.
+ (finish_class_member_access_expr): Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ * decl.c (grokdeclarator): Handle BASELINKs.
+ * decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
+ finish_class_member_access_expr.
+ (arg_assoc): Handle BASELINKs.
+ (do_class_using_decl): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Use build_ptrmemfunc_access_expr.
+ * except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
+ destructors.
+ (build_throw): Use BASELINK_FUNCTIONS.
+ * init.c (perform_member_init): Use
+ build_class_member_access_expr.
+ (build_offset_ref): Handle BASELINKs. Use
+ build_class_member_access_expr.
+ * method.c (hack_identifier): Likewise.
+ * parse.y (do_id): Use BASELINK, not TREE_LIST.
+ (primary): Remove uses of build_object_ref.
+ * pt.c (lookup_template_function): Handle BASELINKs.
+ (resolve_overloaded_unification): Likewise.
+ * search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
+ (lookup_field): Use BASELINK, not TREE_LIST.
+ (lookup_fnfiels): Likewise.
+ (setup_class_bindings): Likewise.
+ * semantics.c (finish_object_call_expr): Do not use
+ build_method_call when we already know what function is being
+ called.
+ * spew.c (identifier_type): Use BASELINK, not TREE_LIST.
+ * tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
+ TREE_CHAIN.
+ (name_p): New function.
+ * typeck.c (build_object_ref): Remove.
+ (build_component_ref_1): Likewise.
+ (build_x_component_ref): Likewise.
+ (build_class_member_access_expr): New function.
+ (finish_class_member_access_expr): Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ (get_member_function_from_ptrfunc): Use
+ build_ptrmemfunc_access_expr.
+ (build_binary_op): Likewise.
+ (build_unary_op): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+ * typeck2.c (build_m_component_ref): Adjust comment.
+
+2002-08-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+ * cp-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option.
+ * cp-tree.h (cxx_decode_option): Remove.
+ * decl2.c (compare_options, lang_f_options, unsupported_options,
+ cxx_decode_option): Remove.
+
+2002-08-06 Gabriel Dos Reis <gdr@nerim.net>
+
+ * typeck.c (build_x_unary_op): Handle pointer-to-member.
+
+2002-08-05 Geoffrey Keating <geoffk@redhat.com>
+
+ * class.c: Don't include obstack.h.
+ (popclass):
+ * decl2.c: Delete bogus comment.
+ * error.c: Don't include obstack.h.
+ * except.c: Likewise.
+ (dump_type): Correct comment.
+ * method.c: Don't include obstack.h.
+ * tree.c: Likewise.
+
+2002-08-04 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/2213
+ * cvt.c (cp_convert_to_pointer): Reject conversions from integral
+ expressions to pointer-to-data-member of pointer-to-member-functions.
+
+2002-08-04 Geoffrey Keating <geoffk@redhat.com>
+
+ * cvt.c (ocp_convert): Delete obsolete code.
+ * parse.y (permanent_obstack): Delete declaration.
+ * pt.c (permanent_obstack): Delete declaration.
+ * repo.c (permanent_obstack): Delete declaration.
+ (open_repo_file): Use xmalloc instead of permanent_obstack.
+ (init_repo): Use xstrdup instead of permanent_obstack.
+
+2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (VF_DERIVED_VALUE): Remove.
+ * class.c (finish_struct_1): Use VF_BINFO_VALUE not VF_DERIVED_VALUE.
+
+2002-08-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR 7470.
+ C++ ABI change - vfunc ordering.
+ * class.c (add_virtual_function): Remove.
+ (dfs_modify_all_vtables): Take list of all declared
+ virtuals. Assign all that are not in primary base.
+ (check_for_override): Adjust comments.
+ (create_vtable_ptr): Take single list of virtuals. Build chain
+ of declared virtuals here.
+ (layout_class_type): Take single list of virtuals. Adjust.
+ (finish_struct_1): Keep virtuals on single list. Adjust.
+
+2002-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_member_call): Use build_new_method_call, not
+ build_method_call.
+
+2002-08-02 Krister Walfridsson <cato@df.lth.se>
+
+ * Make-lang.in (spew.o, lex.o, pt.o): Add path to parse.h dependencies.
+
+2002-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_method_call): Issue a more helpful error message
+ about ambiguous method names.
+
+2002-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (build_shared_int_cst): Make cache file scope, and
+ GTY it.
+
+2002-08-02 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
+ (cp_expr_size): New fn.
+ * call.c (build_over_call): Lose empty class hackery.
+ (convert_arg_to_ellipsis): Promote non-POD warning to error.
+ * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
+
+ * semantics.c (expand_body): Do tree optimization in the function
+ context, too.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h: Move all warning and flag declarations to c-common.h.
+ * decl.c: Move all warning and flag variables to c-common.c.
+ * decl2.c: Move all warning and flag variables to c-common.c.
+ * lex.c (flag_digraphs): Remove.
+ (warn_traditional): Now in c-common.c.
+
+2002-07-31 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_field_call): Do not look up the field by name.
+ (build_method_call): Simplify.
+ (struct z_candidate): Add access_path and conversion_path. Remove
+ basetype_path.
+ (convert_class_to_reference): Adjust use of
+ add_function_candidate.
+ (add_candidate): Add conversion_path argument.
+ (add_function_candidate): Use it.
+ (add_conv_dndidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_template_candidate_real): Add conversion_path argument.
+ (add_template_conv_candidate): Likewise.
+ (add_template_candidate): Likewise.
+ (build_user_type_conversion_1): Use it.
+ (build_new_function_call): Remove name lookup code. Adjust use of
+ add_template_candidate and add_function_candidate.
+ (build_new_op): Likewise.
+ (convert_like_real): Use build_special_member_call.
+ (build_over_call): Use cand->conversion_path.
+ (build_special_member_call): New method.
+ (build_new_method_call): Remove name lookup code.
+ * cp-tree.def (OFFSET_REF): Update documentation.
+ (TEMPLATE_ID_EXPR): Likewise.
+ * cp-tree.h (BASELINK_ACCESS_BINFO): New macro.
+ (BASELINK_OPTYPE): Likewise.
+ (build_new_method_call): Adjust prototype.
+ (build_special_member_call): New method.
+ (build_baselink): New method.
+ (build_offset_ref_call_from_tree): Likewise.
+ (build_call_from_tree): Likewise.
+ (finish_qualified_call_expr): Remove.
+ (finish_call_expr): Adjust prototype.
+ (build_x_function_call): Remove.
+ * cvt.c (ocp_convert): Use build_special_member_call.
+ * decl2.c (reparse_absdcl_as_expr): Use finish_call_expr.
+ (build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and
+ CALL_EXPR.
+ (build_offset_ref_call_from_tree): New function.
+ (build_call_from_tree): Likewise.
+ * init.c (expand_cleanup): Use build_special_member_call.
+ (expand_default_init): Likewise.
+ (build_member_call): Use finish_call_expr.
+ (build_new_1): Use build_special_member_call.
+ (push_base_cleanups): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ * parse.y (template_id): Do not pass a COMPONENT_REF to
+ lookup_template_function.
+ (primary): Use parse_finish_call_epxr, not finish_call_expr.
+ (parse_finish_call_expr): New function.
+ * pt.c (lookup_template_function): Add assertions.
+ * search.c (lookup_base): Allow T to be a binfo.
+ (build_baselink): New function.
+ (lookup_member): Use it.
+ * semantics.c (finish_call_expr): Do not do name lookup.
+ (finish_object_call_expr): Remove #if 0'd code.
+ (finish_qualified_call_expr): Remove.
+ * typeck.c (build_x_function_call): Remove.
+ (build_static_case): Use build_special_member_call.
+ * typeck2.c (build_functional_cast): Likewise.
+
+2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
+
+2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
+
+ * cp-tree.h (VF_DERIVED_VALUE): Restore from previous deletion.
+
+2002-07-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELDS, VF_*, BV_*): Add more
+ documentation.
+
+2002-07-29 Alan Modra <amodra@bigpond.net.au>
+
+ * cp-tree.h: Comment typo fix.
+
+2002-07-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * spew.c (space_for_token): Allocate zeroed memory for a new token
+ chunk.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (builtin_function_1): No need to explicitly mark
+ BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (cxx_decode_option): Support -fno-builtin-foo.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_over_call): Likewise.
+ (cp_convert_parm_for_inlining): New fn.
+ (convert_for_arg_passing): New fn.
+ (convert_default_arg, build_over_call): Use it.
+ (type_passed_as): New fn.
+ * pt.c (tsubst_decl): Use it.
+ * decl2.c (cp_build_parm_decl): New fn.
+ (build_artificial_parm): Use it.
+ (start_static_storage_duration_function): Likewise.
+ * decl.c (start_cleanup_fn, grokdeclarater): Likewise.
+ (grokparms): Don't mess with DECL_ARG_TYPE.
+ * typeck.c (convert_arguments): Use convert_for_arg_passing.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+ Define.
+ * cp-tree.h: Declare new fns.
+
+2002-07-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (flag_operator_names): Remove.
+ * decl2.c (flag_operator_names): Remove.
+ (lang_f_options): Remove operator-names.
+ * lex.c (D_OPNAME): Remove.
+ (reswords): Remove operator names.
+ (rid_to_yy): Remove operator names.
+ (init_reswords): No need to handle D_OPNAME.
+ * spew.c (read_process_identifier): There are no operator
+ names.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * dump.c (cp_dump_tree): Call c_dump_tree.
+ * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * error.c (print_whitespace): Remove.
+ * g++spec.c (LIBUNWIND): Move.
+ * mangle.c (mangled_position, write_signed_number): Remove.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * decl2.c (cxx_decode_option): Similarly.
+
+2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
+
+ * cp-tree.h (cxx_sizeof_nowarn): Now a macro.
+ (cxx_sizeof_or_alignof_type): Take a third argument.
+ (cxx_sizeof): Adjust definition.
+ (cxx_alignof): Likewise.
+ * init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality.
+ * typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for
+ complaining.
+ (c_sizeof_nowarn): Remove definition.
+ (build_unary_op): Use cxx_sizeof_nowarn.
+
+2002-07-24 Geoffrey Keating <geoffk@redhat.com>
+
+ * tree.c (cp_build_qualified_type_real): When copying
+ pointer-to-method types, unshare the record that holds
+ the cached pointer-to-member-function type.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (FILE_FUNCTION_PREFIX_LEN): Remove.
+
+2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7363:
+ * typeck.c (cxx_sizeof_or_alignof_type): New function.
+ (c_sizeof): Remove definition.
+ (expr_sizeof): Use cxx_sizeof.
+ * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type.
+ * decl.c (finish_destructor_body): Use cxx_sizeof.
+ * semantics.c (finish_alignof): Likewise.
+ (finish_alignof): Use cxx_alignof.
+ * cp-tree.h (cxx_sizeof, cxx_alignof): New macros.
+ (cxx_sizeof_or_alignof_type): Declare.
+ (my_friendly_assert): Move to ../c-common.h.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * class.c, method.c, pt.c, search.c: Don't define obstack macros.
+
+2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7347, c++/7348
+ * cp-tree.h (tsubst_flags_t): Add tf_parsing.
+ * decl.c (make_typename_type): Use it.
+ (make_unbound_class_template): Likewise.
+ (lookup_name_real): Don't call type_access_control if scope is
+ template parameter dependent.
+ * parse.y (template_arg): Call make_unbound_class_template with
+ tf_parsing set.
+ (nest_name_specifier): Call make_typename_type with tf_parsing set.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ (instantiate_decl): Push class scope.
+ * pt.c (regenerate_decl_from_template): Call pushclass and popclass
+ for both static variable and member function template.
+ (instantiate_decl) Call pushclass and popclass when tsubst'ing type
+ and arguments.
+ * search.c (type_access_control): Do type access for TEMPLATE_DECL
+ too.
+
+2002-07-20 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (cxx_decode_option): Simplify -fhandle-exceptions
+ test by using positive_option. Make whitespace consistent.
+
+2002-07-20 Gabriel Dos Reis <gdr@nerim.net>
+
+ * spew.c (struct unparsed_test): Replace 'filename' and 'lineno'
+ members with 'locus'. Adjust use throughout.
+ (struct feed): Likewise.
+ (alloc_unparsed_test): Change prototype, take a 'const location_t *'.
+ Adjust use.
+ (snarf_defarg): Use error(), not error_with_file_and_line().
+
+2002-07-19 Chris Demetriou <cgd@broadcom.com>
+
+ * lang-specs.h (@c++): Include "%2" (cc1plus_spec) wherever
+ cpp_options is included.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2862, c++/2863
+ * pt.c (determine_specialization): Compare the length of
+ TYPE_ARG_TYPES. Tidy.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3797
+ * decl.c (duplicate_decls): Don't propagate inlining parameters from
+ olddecl to newdecl when newdecl is a specialization of the
+ instantiation olddecl.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4802, c++/5387
+ * decl.c (make_typename_type): Use enforce_access.
+
+2002-07-17 Scott Snyder <snyder@fnal.gov>
+
+ PR c++/7320
+ * rtti.c (get_tinfo_decl): Set DECL_COMDAT.
+
+2002-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Correct handling of conversion operators.
+
+2002-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7224
+ * class.c (add_method): Simplify.
+
+2002-07-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/7279
+ * tree.c (cp_copy_res_decl_for_inlining): Also copy
+ TREE_ADDRESSABLE.
+
+2002-07-10 Graham Stott <graham.stott@btinternet.com>
+
+ * pt.c (template_parm_this_level_p, push_template_decl_real):
+ Pass depth as int pointer.
+
+2002-07-11 Tim Josling <tej@melbpc.org.au>
+
+ Remove front end hard coding from gengtype.c.
+
+ * config-lang.in (gtfiles): Add files needed for this front end.
+
+2002-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (unqualified_name_lookup_error): Declare it.
+ (begin_function_definition): Adjust prototype.
+ * lex.c (unqualified_name_lookup_error): New function, split out
+ from ...
+ (do_identifier): ... here.
+ * parse.y (parse_begin_function_definition): New function.
+ (fn.def1): Use it.
+ * semantics.c (begin_function_definition): Accept decl-specifiers
+ and attributes as separate parameters.
+
+2002-07-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/6255
+ * decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than
+ modifying the old one.
+
+2002-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (constructor_name_p): Declare it.
+ (check_template_template_default_arg): Likewise.
+ * class.c (handle_using_decl): Use constructor_name_p.
+ * decl.c (grokdeclarator): Likewise.
+ * decl2.c (constructor_name_p): Define it.
+ * init.c (build_member_call): Use constructor_name_p.
+ * parse.y (template_parm): Use check_template_template_default_arg.
+ * pt.c (check_explicit_specialization): Use constructor_name_p.
+ * semantics.c (check_template_template_default_arg): New function.
+
+2002-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (can_complete_type_without_circularity): Add static to
+ function definition.
+
+2002-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (have_extern_spec): Declare it
+ * decl.c (have_extern_spec): Define it.
+ (start_decl): Eliminate use of used_extern_spec.
+ (start_function): Likewise.
+ * parse.y (have_extern_spec): Remove declaration.
+ (used_extern_spec): Likewise.
+ (frob_specs): Eliminate use of used_extern_spec.
+ (.hush_warning): Likewise.
+
+2002-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (cp/parse.o): Depend on decl.h.
+ * cp-tree.h (do_decl_instantiation): Change prototype.
+ * parse.y: Include decl.h.
+ (parse_decl_instantiation): New function.
+ (explicit_instantiation): Use it.
+ * pt.c (do_decl_instantiation): Accept a DECL, not a DECLARATOR
+ and DECLSPECS.
+
+2002-07-07 Roger Sayle <roger@eyesopen.com>
+
+ * error.c (dump_function_name): Use DECL_TEMPLATE_RESULT for
+ constructor and destructor tests when passed a TEMPLATE_DECL.
+
+2002-07-05 Jason Merrill <jason@redhat.com>
+
+ * cvt.c (cp_convert_to_pointer): Call force_fit_type for null
+ pointers.
+
+ PR optimization/7145
+ * tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL.
+
+2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Repair damage on weak-impared targets caused by my previous patch.
+ * cp-tree.h (import_export_tinfo): Add parameter.
+ * decl2.c (import_export_tinfo): Add parameter, post adjust
+ DECL_COMDAT.
+ * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
+ import_export_tinfo.
+
+2002-07-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6944
+ * init.c (build_aggr_init): Remove qualifiers of init before calling
+ build_vec_init.
+ (build_vec_init): Flatten multi-dimensional array during cleanup.
+ (build_vec_delete_1): Abort if the type of each element is array.
+
+2002-07-03 Graham Stott <graham.stott@btinternet.com>
+
+ * pt.c (instantiate_class_template): Fix typo.
+
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck2.c (cxx_incomplete_type_diagnostic): Fix typo caused
+ by CVS conflict in my last patch.
+
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6716
+ * pt.c (can_complete_type_without_circularity): New function.
+ (instantiate_class_template): Use it.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Improve error
+ message due to incomplete fields.
+
+2002-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7112
+ * mangle.c (write_expression): Add mangling for sizeof when
+ applied to a type.
+ * operators.def: Remove stale comment.
+
+2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
+ (CPTI_TYPE_INFO_PTR_TYPE): ... this.
+ (tinfo_decl_type): Replace with ...
+ (type_info_ptr_type): ... this.
+ (import_export_tinfo): Declare.
+ (tinfo_decl_p): Rename to ...
+ (unemitted_tinfo_decl_p): ... this.
+ * decl2.c (import_export_decl): Break out tinfo handling into ...
+ (import_export_tinfo): ... here. New function.
+ (finish_file): Adjust.
+ * rtti.c (TINFO_REAL_NAME): New macro.
+ (init_rtti_processing): Create the tinfo types.
+ (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
+ (get_tinfo_decl): Adjust.
+ (get_tinfo_ptr): New function.
+ (get_type_id): Use it.
+ (tinfo_base_init): Create vtable decl here, if it doesn't exist.
+ (ptr_initializer): Use get_tinfo_ptr.
+ (ptm_initializer): Likewise.
+ (synthesize_tinfo_var): Break into ...
+ (get_pseudo_ti_init): ... this. Just create the initializer.
+ (get_pseudo_ti_desc): .. and this.
+ (create_real_tinfo_var): Remove.
+ (create_pseudo_type_info): Don't create the vtable decl here.
+ (get_vmi_pseudo_type_info): Remove.
+ (create_tinfo_types): Adjust.
+ (tinfo_decl_p): Rename to ...
+ (unemitted_tinfo_decl_p): ... here. Adjust.
+ (emit_tinfo_decl): Adjust. Create the initializer.
+
+2002-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6695
+ * pt.c (tsubst_friend_class): Substitute into the context of the
+ friend before using it.
+
+2002-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (xref_tag): Change prototype.
+ (handle_class_head): Likewise.
+ (build_x_component_ref): Likewise.
+ * decl.c (cxx_init_decl_processing): Adjust call to xref_tag.
+ (xref_tag): Take attributes as a separate parameter.
+ (xref_tag_from_type): Adjust call to xref_tag.
+ * decl2.c (build_expr_from_tree): Adjust call to
+ build_x_component_ref.
+ (handle_class_head): Take attributes as a separate parameter.
+ * parse.y (parse_xref_tag): New function.
+ (parse_handle_class_head): Likewise.
+ (primary): Use parse_xref_tag.
+ (class_head_decl): Use parse_handle_class_head.
+ (class_head_defn): Likewise.
+ * rtti.c (init_rtti_processing): Adjust call to xref_tag.
+ (build_dynamic_cast_1): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (emit_support_tinfos): Likewise.
+ * typeck.c (build_object_ref): Adjust call to
+ build_x_component_ref.
+ (build_x_component_ref): Remove protect parameter.
+
+2002-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Use BASELINK_FUNCTIONS.
+ * class.c (handle_using_decl): Likewise.
+ (instantiate_type): Likewise.
+ * cp-tree.h (BASELINK_FUNCTIONS): New macro.
+ (xref_basetypes): Change prototype.
+ (begin_mem_initializers): New function.
+ (get_overloaded_fn): Likewise.
+ * decl.c (xref_basetypes): Simplify.
+ * error.c (dump_expr): Use BASELINK_FUNCTIONS.
+ * init.c (build_offset_ref): Likewise.
+ * parse.y (base_init): Use begin_mem_initializers().
+ (structsp): Adjust call to xref_basetypes.
+ * pt.c (determine_specialization): Use BASELINK_FUNCTIONS.
+ (instantiate_class_template): Adjust call to xref_basetypes.
+ * semantics.c (begin_mem_initializers): New function.
+ * tree.c (is_overloaded_fn): Use BASELINK_FUNCTIONS.
+ (really_overloaded_fn): Likewise.
+ (get_overloaded_fn): New function.'
+ (get_first_fn): USe BASELINK_FUNCTIONS.
+
+2002-06-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SCALAR_TYPE_P): New macro.
+ (check_for_out_of_scope_variable): New function.
+ (at_class_scope_p): Likewise.
+ (finish_fname): Likewise.
+ * class.c (finish_struct): Use at_function_scope_p.
+ * decl.c (check_for_out_of_scope_variable): New function, split
+ out from do_identifier.
+ (finish_enum): Use at_function_scope_p.
+ * lex.c (do_identifier): Use check_for_out_of_scope_variable.
+ * parse.y (VAR_FUNC_NAME): Give it <ttype>. Use finish_fname.
+ (primary): Use at_function_scope_p.
+ * search.c (at_class_scope_p): New function.
+ * semantics.c (finish_fname): Likewise.
+ (check_multiple_declarators): Use at_function_scope_p.
+
+2002-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y (parse_scoped_id): New function.
+ (primary): Use it.
+ * cp-tree.h (do_scoped_id): Adjust declaration.
+ * lex.c (do_scoped_id): Remove call to yylex.
+ * decl2.c (build_expr_from_tree): Adjust use of do_scoped_id.
+ * typeck2.c (add_exception_specifier): Use tree_cons, rather than
+ expanding it inline.
+
+2002-06-23 Matt Thomas <matt@3am-software.com>
+
+ * decl.c (finish_function): Change "#ifdef VMS_TARGET" to
+ "#if VMS_TARGET".
+
+2002-06-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mangle.c (integer_type_codes): Const-ify.
+
+2002-06-20 Richard Henderson <rth@redhat.com>
+
+ PR c++/6747
+ * typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early.
+ Call put_var_into_stack.
+
+2002-06-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * spew.c (remove_last_token): Use ARRAY_SIZE in lieu of explicit
+ array size calculation.
+
+2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6892
+ * pt.c (tsubst_expr): Handle FILE_STMT.
+
+2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6723
+ * pt.c (lookup_template_class): Don't build complete argument of
+ BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template
+ argument.
+
+2002-06-19 Akim Demaille <akim@epita.fr>
+
+ * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with
+ decl.h's TYPENAME.
+ * spew.c, lex.c: Adjust.
+ * parse.y (explicit_instantiation): Add empty action to override
+ the default $$ = $1 where it introduces a type clash.
+
+2002-06-14 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (begin_for_stmt): Push the 'for' scope before
+ adding the FOR_STMT.
+
+ C++ ABI changes.
+ * class.c (build_base_field): Set DECL_PACKED.
+ (layout_class_type): Don't use tail padding of PODs.
+ * mangle.c (write_unqualified_name): Fix template conversion op
+ mangling.
+
+2002-06-16 Richard Henderson <rth@redhat.com>
+
+ PR opt/6793
+ * tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test
+ after template instantiation.
+
+2002-06-16 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common.
+
+2002-06-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * cp-tree.h (compiler_error): Remove declaration.
+ * lex.c (compiler_error): Remove definition.
+
+2002-06-14 Steve Ellcey <sje@cup.hp.com>
+
+ * g++spec.c (LIBUNWIND): New.
+ (lang_specific_driver): Add it if USE_UNWIND_EXCEPTIONS is set.
+
+2002-06-13 Jessica Han <jessica@cup.hp.com>
+
+ * class.c (build_vtable): Use TARGET_VTABLE_ENTRY_ALIGN.
+ (build_vtbl_initializer): Honor TARGET_VTABLE_DATA_ENTRY_DISTANCE.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (get_tinfo_decl_dynamic): Likewise.
+ (create_pseudo_type_info): Likewise.
+
+2002-06-12 Stan Shebs <shebs@apple.com>
+
+ * mpw-config.in: Remove file, no longer used.
+ * mpw-make.sed: Ditto.
+
+2002-06-07 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c: Update call to cpp_handle_option.
+
+2002-06-07 H.J. Lu (hjl@gnu.org)
+
+ * decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT.
+
+2002-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_error_at): Fix typo.
+
+2002-06-04 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_diagnostic_starter): Adjust call.
+ (maybe_print_instantiation_context): Change prototype to take a
+ 'diagnostic_info *'.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (cp_printer): Take a secondary parameter as a 'text_info *'.
+ Remove output_state savings. Adjust calls.
+
+2002-06-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * pt.c (inline_parm_levels): Mark for GC.
+
+ * mangle.c (start_mangling): Allocate G.substitutions here...
+ (init_mangle): ... rather than here.
+ (finish_mangling): Clear the varray pointer when done with it.
+ * spew.c (yylexstring): Don't use VARRAY_FREE.
+ * search.c (bfs_walk): Don't use VARRAY_FREE.
+ * decl2.c (pending_statics): Use gengtype to mark.
+ (deferred_fns): Likewise.
+ (ssdf_decls): Likewise.
+ (init_decl2): Delete.
+ * decl.c (pop_from_top_level): Don't use VARRAY_FREE.
+ (cxx_init_decl_processing): Don't call init_decl2.
+ (cxx_pop_function_context): Don't use VARRAY_FREE.
+ * cp-tree.h (struct saved_scope): No need for special marking
+ of varrays.
+ (struct language_function): Likewise.
+ (local_classes): Use gengtype to mark.
+ (init_decl2): Delete prototype.
+ * class.c (init_class_processing): Don't use
+ ggc_add_tree_varray_root.
+ (build_vtbl_initializer): Don't use VARRAY_FREE.
+
+ * decl.c (typename_compare): Don't use same_type_p.
+
+ * decl.c: Include hashtab.h instead of hash.h.
+ (typename_hash): Update to use htab_h.
+ (typename_compare): Likewise.
+ (typename_htab): Use gengtype to mark.
+ (build_typename_type): Update to use htab_h.
+ * Make-lang.in (cp/decl.o): Use HASHTAB_H instead of hash.h.
+
+ * Make-lang.in (gt-cp-tree.h): New rule.
+ (cp/tree.o): Depend on gt-cp-tree.h.
+ * config-lang.in (gtfiles): Add cp/tree.c.
+ * tree.c: Include gt-cp-tree.h.
+ (list_hash_table): Use gengtype to mark.
+ (init_tree): Use gengtype to mark trees.
+
+ * Make-lang.in (cp/decl.o): Add debug.h dependency.
+ * call.c (struct z_candidate): Use gengtype.
+ (USER_CONV_CAND): Use WRAPPER_ZC.
+ (convert_class_to_reference): Use build_zc_wrapper.
+ (build_type_conversion_1): Likewise.
+ (build_over_call): Use WRAPPER_ZC.
+ (add_warning): Use build_zc_wrapper.
+ * cp-lang.c (LANG_HOOKS_MARK_TREE): Delete.
+ * cp-tree.h (struct lang_identifier): Use gengtype.
+ (struct template_parm_index_s): Likewise.
+ (struct ptrmem_cst): Likewise.
+ (struct tree_binding): Likewise.
+ (struct tree_overload): Likewise.
+ (struct tree_srcloc): Likewise.
+ (struct tree_wrapper): Likewise. Also modify to have a pointer
+ to struct z_candidate rather than void.
+ (enum cp_tree_node_structure_enum): New.
+ (union lang_tree_node): New.
+ (cxx_mark_tree): Delete prototype.
+ (cp_tree_node_structure): New prototype.
+ (build_ptr_wrapper): Delete prototype.
+ (build_int_wrapper): Delete prototype.
+ (build_zc_wrapper): New prototype.
+ * decl.c: Include debug.h
+ (cxx_mark_tree): Delete.
+ (cp_tree_node_structure): New.
+ * tree.c (build_ptr_wrapper): Delete.
+ (build_int_wrapper): Delete.
+ (build_zc_wrapper): New.
+
+ * cp-tree.h [! ENABLE_TREE_CHECKING] (LANG_TYPE_PTRMEM_CHECK):
+ Correct typo. Patch from k_fukui@highway.ne.jp.
+
+ * semantics.c (current_stmt_tree): Update for change to
+ struct language_function.
+ (finish_mem_initializers): Likewise.
+ * decl.c (cxx_init_decl_processing): Don't set mark_lang_status.
+ * cp-tree.h (struct language_function): Rename from
+ cp_language_function. Change all uses.
+ (cp_function_chain): Don't need to cast.
+
+ * class.c (duplicate_tag_error): Reset discriminator.
+ (check_bases_and_members): Update for data structure changes.
+ * cp-tree.h (struct lang_id2): Use gengtype.
+ (flagged_type_tree): Likewise.
+ (SET_LANG_ID): Use GGC on struct lang_id2.
+ (struct cp_language_function): Use gengtype. Remove field
+ 'x_vcalls_possible_p'.
+ (current_vcalls_possible_p): Delete.
+ (struct lang_type_header): New.
+ (struct lang_type_class): Rename from struct lang_type. Include
+ struct lang_type_header.
+ (struct lang_type_ptrmem): New.
+ (struct lang_type): New.
+ (LANG_TYPE_CLASS_CHECK): New. Use it in all the appropriate macros.
+ (LANG_TYPE_PTRMEM_CHECK): New. Use it in all the appropriate macros.
+ (TYPE_SET_PTRMEMFUNC_TYPE): Set discriminator, update for changes.
+ (struct lang_decl_flags): Use gengtype. Add discriminators.
+ (struct lang_decl): Use gengtype. Add and use discriminators.
+ Update the macros that reference moved fields.
+ (LANG_DECL_U2_CHECK): New function. Use it when appropriate.
+ (SET_DECL_THUNK_P): Set discriminator too.
+ (clear_inline_text_obstack): Delete prototype.
+ (finish_inline_definitions): Delete prototype.
+ (mark_pending_inlines): Delete prototype.
+ (lang_check_failed): New prototype.
+ * decl.c (struct named_label_use_list): Use gengtype.
+ (struct named_label_list): Likewise.
+ (mark_binding_level): Delete.
+ (mark_named_label_lists): Delete.
+ (push_local_name): Set discriminator on DECL_LANG_SPECIFIC.
+ (cxx_init_decl_processing): Use generated marker routine.
+ (begin_destructor_body): Delete dead set to
+ current_vcalls_possible_p.
+ (mark_lang_function): Delete.
+ (mark_cp_function_context): Delete.
+ (lang_mark_tree): Use generated marker routines.
+ * decl2.c (start_objects): Set discriminator when setting
+ GLOBAL_INIT_PRIORITY.
+ * lex.c (retrofit_lang_decl): Set discriminators.
+ (copy_lang_type): Update for changes to lang_type structure.
+ (cp_make_lang_type): Set discriminator.
+ * parse.y: Use gengtype on YYLVAL. Don't use dots in identifiers.
+ * search.c: Include ggc.h.
+ * semantics.c (anon_aggr_type_p): Use the macro, don't hand-code it.
+ (finish_inline_definitions): Delete.
+ * spew.c (struct token): Use gengtype.
+ (struct token_chunk): New.
+ (struct unparsed_text): Use gengtype. Store tokens in chunks.
+ (struct feed): Use gengtype.
+ (feed_obstack): Delete.
+ (feed): Mark as GC root.
+ (pending_inlines): Mark as GC root.
+ (pending_inlines_tail): Likewise.
+ (processing_these_inlines): Likewise.
+ (token_obstack): Make static.
+ (first_token): Likewise.
+ (init_spew): Don't initialize deleted things; use gengtype for roots.
+ (clear_inline_text_obstack): Delete.
+ (feed_input): Use GC for struct feed. Update for changes to
+ struct unparsed_text.
+ (mark_pending_inlines): Delete.
+ (next_token): Rename from add_token. Change all callers. Update
+ for changes to struct unparsed_text.
+ (space_for_token): New.
+ (remove_last_token): New.
+ (alloc_unparsed_text): New.
+ (snarf_block): Take an unparsed_text. Update for changes to struct
+ unparsed_text.
+ (snarf_method): Update for changes to struct unparsed_text.
+ (snarf_defarg): Update for changes to struct unparsed_text.
+ * tree.c (lang_check_failed): New.
+
+ * Make-lang.in (gt-cp-call.h gt-cp-decl2.h gt-cp-parse.h
+ gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h): New rules.
+ (cp/spew.o): Add dependency on gt-<filename>.h.
+ (cp/decl2.o): Add dependency on gt-<filename>.h.
+ (cp/call.o): Add dependency on gt-<filename>.h.
+ (cp/pt.o): Add dependency on gt-<filename>.h.
+ (cp/repo.o): Add dependency on gt-<filename>.h.
+ (cp/parse.o): Add dependency on gt-<filename>.h.
+ * call.c: Use gengtype for roots.
+ * config-lang.in (gtfiles): Add cp-tree.h decl.h lex.h call.c
+ decl2.c parse.y pt.c repo.c spew.c.
+ * cp-tree.h: Use gengtype for roots.
+ (struct saved_scope): Use GGC, gengtype.
+ (cp_parse_init): Delete prototype.
+ (init_pt): Delete prototype.
+ * decl.c: Use gengtype for roots.
+ (mark_saved_scope): Delete.
+ (cxx_init_decl_processing): Don't call deleted initilisation
+ routines.
+ (signed_size_zero_node): Delete, unused.
+ * decl.h: Use gengtype for roots.
+ * decl2.c: Use gengtype for roots.
+ * lex.h: Use gengtype for roots.
+ * parse.y: Use gengtype for roots.
+ (cp_parse_init): Delete.
+ * pt.c: Use gengtype for roots.
+ (init_pt): Delete.
+ * repo.c: Use gengtype for roots.
+ * spew.c: Use gengtype for roots.
+
+ * Make-lang.in: Allow for filename changes. Add gtype-cp.h.
+ (cp/decl.o): Add dependency on gtype-cp.h.
+ * decl.c: Remove use of add_deletable_root, use GTY marker instead.
+ Include gtype-cp.h. Allow for filename changes.
+
+ * Make-lang.in (cp/gt-decl.h): Generate using gengtype.
+ (cp/decl.o): Add cp/gt-decl.h dependency.
+ * config-lang.in (gtfiles): New.
+ * tree.h: Rename struct binding_level to struct cp_binding_level.
+ * decl.c: Rename struct binding_level to struct cp_binding_level.
+ Include cp/gt-decl.h.
+ (struct cp_binding_level): Use gengtype.
+ (make_binding_level): Use GGC on struct cp_binding_level.
+ (mark_binding_level): Use gt_ggc_m_cp_binding_level.
+ (cxx_init_decl_processing): Mark free_binding_level as
+ deletable.
+
+ * decl.c (mark_cp_function_context): Update calling sequence.
+
+ * decl.c (start_function): Don't free 'struct
+ cp_language_function'.
+ (pop_cp_function_context): Likewise.
+ (save_function_data): Allocate it using GC.
+ * semantics.c (genrtl_start_function): Don't free 'struct
+ cp_language_function'.
+
+2002-05-31 Matthew Woodcraft <mattheww@chiark.greenend.org.uk>
+
+ * lang-specs.h: Use cpp_debug_options.
+
+2002-05-28 Zack Weinberg <zack@codesourcery.com>
+
+ * mangle.c, tree.c: Include real.h.
+ * Make-lang.in: Update dependency lists.
+
+2002-05-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lex.c: Don't include c-lex.h.
+ * parse.y, spew.c: Don't include c-lex.h; include c-pragma.h.
+
+2002-05-23 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * spew.c (yyungetc, snarf_block): Remove indent_level handling.
+
+2002-05-22 Richard Henderson <rth@redhat.com>
+
+ * decl.c (obscure_complex_init): Check for VAR_DECL
+ before using DECL_THREAD_LOCAL.
+
+2002-05-22 Richard Henderson <rth@redhat.com>
+
+ * decl.c (check_tag_decl): Handle RID_THREAD.
+ (obscure_complex_init): Reject run-time init of tls.
+ (grokvardecl, grokdeclarator): Handle RID_THREAD.
+ * lex.c (reswords): Add __thread.
+ (rid_to_yy): Map RID_THREAD to SCSPEC.
+
+2002-05-22 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options.
+ * cp-tree.h (cxx_post_options): Kill.
+ * cp-lex.c (cxx_post_options): Kill.
+
+2002-05-21 Richard Henderson <rth@redhat.com>
+
+ * lex.c (rid_to_yy): Add RID_THREAD.
+
+2002-05-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * init.c (build_vec_init): Test for trivial copy-assignment when
+ copy-assigning arrays.
+
+2002-05-20 Andreas Jaeger <aj@suse.de>
+
+ * init.c (build_default_init): Remove unused variable.
+
+2002-05-20 Alexandre Oliva <aoliva@redhat.com>
+
+ * call.c (any_strictly_viable): New.
+ (build_new_op): Use it for COMPOUND_EXPR and ADDR_EXPRs.
+
+2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing.
+
+2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/186, DR 259
+ * pt.c (do_decl_instantiation): Don't complain explicit
+ instantiation after explicit specialization.
+ (do_type_instantiation): Likewise.
+
+2002-05-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (complete_type_or_diagnostic): Changed prototype,
+ renamed from...
+ (complete_type_or_else): ... this. Redefined as macro.
+ (cxx_incomplete_type_diagnostic): Declare.
+ (cxx_incomplete_type_error): Define as macro.
+ * init.c (build_delete): Warn about incomplete types other than
+ void, and use the built-in operator delete for them.
+ * typeck.c (complete_type_or_diagnostic): Renamed from
+ complete_type_or_else. Added warn_only argument, passed to...
+ * typeck2.c (cxx_incomplete_type_diagnostic): ... this. Print
+ warnings or errors depending on new warn_only argument. Renamed
+ from...
+ (cxx_incomplete_type_error): ... this. New implementation in
+ terms of cxx_incomplete_type_diagnostic.
+
+2002-05-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/6611
+ * decl2.c (import_export_decl): If we clear
+ DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
+
+2002-05-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6620
+ * pt.c (verify_class_unification): Don't check if PARM is template
+ parameter dependent. Simplify.
+ (unify) [TEMPLATE_PARM_INDEX]: Handle when ARG is a template
+ parameter dependent expression.
+
+2002-05-14 Jason Merrill <jason@redhat.com>
+
+ * rtti.c (get_tinfo_decl): Don't call comdat_linkage.
+ Do set DECL_COMDAT.
+ (synthesize_tinfo_var): Take the public decl.
+ (create_real_tinfo_var): Likewise. Check DECL_COMDAT.
+ (emit_tinfo_decl): Adjust. Call import_export_decl.
+ * decl2.c (import_export_decl): Simplify tinfo decl handling.
+
+2002-05-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (struct lang_type): Added non_zero_init.
+ (CLASSTYPE_NON_ZERO_INIT_P): New macro.
+ (zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
+ * class.c (check_field_decls): Test non_zero_init.
+ * cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
+ zero-to-NULL conversions.
+ * decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
+ type that needs zero-initialization without zeros.
+ (check_initializer_decl): Compute zero-initializer for types
+ that require a non-trivial one.
+ * init.c (build_forced_zero_init): New function.
+ (build_default_init): Use it.
+ * tree.c (zero_init_p): New function.
+ * typeck2.c (force_store_init_value): New function.
+ (process_init_constructor): Create non-trivial zero-initializers
+ for array members and class fields.
+
+2002-05-14 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lang-specs.h: Remove redundant -lang-c++.
+
+2002-05-13 Jason Merrill <jason@redhat.com>
+
+ * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
+ (fixed_type_or_null): See through reference vars.
+ (build_base_path): Vtable contents are constant.
+ * typeck.c (get_member_function_from_ptrfunc): Likewise.
+
+2002-05-12 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created
+ structs are safe.
+
+2002-05-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (flag_ansi): Remove.
+ * decl2.c (flag_ansi): Remove.
+ (cxx_decode_option): Set flag_iso and flag_undef.
+
+2002-05-09 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Reorganize.
+ Use subtraction rather than a bitmask to get the index.
+ * cvt.c (cp_convert_to_pointer): Bail on an error_mark_node.
+
+ * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
+
+2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * Make-lang.in (decl2.o): Update.
+ * cp-tree.h (warn_multichar): Remove.
+ * decl2.c: Include c-common.h.
+ (warn_multichar): Remove.
+
+2002-05-03 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_cplus_array_type): Only const and volatile get
+ special handling.
+
+ * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h.
+
+2002-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ ABI change, returning simple classes from functions.
+ * class.c (finish_struct_bits): Only mark TREE_ADDRESSABLE if
+ TYPE_HAS_TRIVIAL_INIT_REF is false or
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true.
+
+2002-04-30 Jason Merrill <jason@redhat.com>
+
+ PR debug/6436
+ * decl.c (grokdeclarator): Don't override TYPE_NAME of an
+ anonymous class with a typedef if there are attributes.
+
+2002-04-29 Paul Eggert <eggert@twinsun.com>
+
+ * parse.y (nomods_initdcl0): Replace $<ttype>3 with $<ttype>$.
+
+2002-04-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6477
+ * decl.c (follow_tag_typedef): Check if TYPE_NAME (original) is
+ non-NULL first.
+
+2002-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6492
+ * pt.c (tsubst_friend_class): If the friend has an explicit scope,
+ enter that scope before name lookup.
+
+ PR c++/6486
+ * method.c (do_build_copy_constructor): Avoid building
+ cv-qualified reference types.
+
+2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5719
+ * decl.c (grok_op_properties): Assignment ops don't have to return
+ by value. operator% should.
+
+2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR c/6343
+ * decl.c (duplicate_decls): Call merge_weak.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ * parse.y (malloced_yyss, malloced_yyvs): New.
+ (yyoverflow): Re-add. Set them.
+ (free_parser_stacks): New.
+
+2002-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6497
+ * method.c (do_build_assign_ref): Pass a derivation to
+ build_method_call when calling base class assignment operators.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ * parse.y (yyoverflow): Revert.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ PR c/3581
+ * parse.y (string): Remove. Update all uses to use STRING
+ instead, and not call combine_strings.
+ * rtti.c (tinfo_name): Use fix_string_type.
+ * semantics.c (finish_asm_stmt): Don't call combine_strings.
+ * spew.c (yylexstring): New.
+ (read_token): Use it.
+
+2002-04-25 Richard Henderson <rth@redhat.com>
+
+ PR c/2161
+ * parse.y (yyoverflow): New.
+
+2002-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/5607
+ * search.c (check_final_overrider): No longer static.
+ * class.c (update_vtable_entry_for_fn): Call it.
+ * cp-tree.h: Adjust.
+
+2002-04-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SET_YYDEBUG): Remove.
+ * cp-tree.h (cxx_set_yydebug): Die.
+ * lex.c (YYDEBUG): Get from c-lex.h.
+ (cxx_set_yydebug): Remove.
+ * parse.y: Include c-lex.h.
+ (YYDEBUG): Get from c-lex.h.
+
+2002-04-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6438.
+ * cvt.c (convert_to_void): Don't unconditionally make COND_EXPRs
+ void.
+
+2002-04-24 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE,
+ LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, LANG_HOOKS_ATTRIBUTE_TABLE):
+ Redefine.
+ * cp-tree.h (cp_attribute_table): Rename.
+ * decl.c (lang_attribute_table): Remove declaration.
+ (cxx_init_decl_processing): Don't set it.
+ * tree.c (cp_attribute_table): Rename.
+
+2002-04-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/6331
+ * method.c (do_build_copy_constructor): Use cp_build_qualified_type.
+ * typeck.c (build_modify_expr): Allow arrays to differ in cv-quals.
+ The pedwarn for array assignment is now unconditional.
+ * tree.c (build_cplus_array_type_1): Still process simple array types
+ normally in templates.
+
+ PR c++/6395
+ * decl.c (make_rtl_for_nonlocal_decl): Don't mess with #pragma i/i
+ stuff for comdats.
+
+2002-04-23 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (check_class_key): Allow KEY to be union/enum/struct/class
+ node with attributes.
+
+2002-2-23 David O'Brien <obrien@FreeBSD.org>
+
+ * g++spec.c (MATH_LIBRARY_PROFILE, LIBSTDCXX_PROFILE): Add.
+ Use MATH_LIBRARY_PROFILE and LIBSTDCXX_PROFILE if profile flag given.
+
+2002-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6256:
+ * pt.c (tsubst_friend_class): Handle templates with explicit
+ nested names.
+
+ PR c++/6331:
+ * typeck.c (merge_types): Remember the cv-qualification of pointer
+ types when merging them.
+
+2002-04-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_FUNCTION_INIT,
+ LANG_HOOKS_FUNCTION_FREE, LANG_HOOKS_FUNCTION_MARK): Redefine.
+ * cp-tree.h (cxx_push_function_context, cxx_pop_function_context,
+ cxx_mark_function_context): New.
+ * decl.c (push_cp_function_context, pop_cp_function_context,
+ mark_cp_function_context): Rename for consistency.
+ (cxx_init_decl_processing): Don't set old hooks.
+
+2002-04-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (convert_type_from_ellipsis): Rename, update.
+ * cp-lang.c (LANG_HOOKS_TYPE_PROMOTES_TO): Redefine.
+ * cp-tree.h (convert_type_from_ellipsis): Rename.
+ * decl.c (cxx_init_decl_processing): Don't set hook.
+
+2002-04-18 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_new_method_call): Update.
+ * cp-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine.
+ * cp-tree.h (cxx_incomplete_type_error): New.
+ * decl.c (grokdeclarator, grokparms): Update.
+ * decl2.c (check_classfn): Update.
+ * pt.c (tsubst): Update.
+ * typeck.c (complete_type_or_else, expr_sizeof,
+ decay_conversion): Update.
+ * typeck2.c (incomplete_type_error): Rename.
+ (add_exception_specifier): Update.
+
+2002-04-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/5658
+ * search.c (setup_class_bindings): A class template qualifies as a
+ type binding.
+
+2002-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6316
+ * decl2.c (finish_file): Clear DECL_EXTERNAL in a separate loop
+ before expanding.
+
+2002-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (begin_init_stmts): Remove commented out code.
+ (finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
+ * semantics.c (begin_gobal_stmt_expr): Adjust call to
+ expand_start_stmt_expr.
+
+2002-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (register_dtor_fn): Pass the address of dso_handle, not
+ dso_handle itself, to __cxa_atexit.
+
+2002-04-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (cxx_print_error_function): Adjust call to macros.
+
+2002-04-14 Jakub Jelinek <jakub@redhat.com>
+
+ * class.c (layout_virtual_bases): Do all dsize computation on trees.
+
+2002-04-14 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Don't do
+ gratuitious division and multiplication on
+ ptrmemfunc_vbit_in_delta targets.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5373.
+ * semantics.c (finish_expr_stmt): Remember the type of the
+ expression before any conversions are performed.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5189.
+ * call.c (add_template_candidate_real): Do not treat member
+ templates as copy constructors.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Do not copy the RTL for a variable
+ declaration if the old variable had an incomplete type and the new
+ variable does not.
+ (complete_vars): Do not call layout_decl for completed variables.
+
+2002-04-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (duplicate_decls): Don't try to unify an implicit typedef
+ with an explicit one.
+ (follow_tag_typedef): New.
+ (lookup_tag): Use it to extract the tag of an explicit typedef.
+ (xref_tag): Likewise.
+
+2002-04-11 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions):
+ If two types have the same variant, return immediately.
+ When two floating-point operands are the same precision:
+ convert to float if one of the operands is float;
+ if neither operand is one of the standard types, return the type
+ of the first operand.
+
+2002-04-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5507
+ * decl.c (make_typename_type): Remove implicit typenameness.
+
+2002-04-09 Jason Merrill <jason@redhat.com>
+
+ PR optimization/6189
+ * semantics.c (genrtl_start_function): Don't free
+ DECL_SAVED_FUNCTION_DATA for inline functions.
+
+ * init.c (build_member_call): For now, don't convert to
+ intermediate base if it would cause an error.
+
+2002-04-08 Paolo Carlini <pcarlini@unitus.it>
+
+ * parse.y (namespace_qualifier, maybe_identifier,
+ begin_explicit_instantiation, end_explicit_instantiation,
+ apparent_template_type, .finish_template_type,
+ do_id, maybe_init, defarg_again, component_decl_1):
+ Add ending ';', in accordance with POSIX.
+
+2002-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5571
+ * class.c (layout_class_type): Remember incomplete static
+ variables.
+ (finish_struct_1): Call complete_vars, not
+ hack_incomplete_structures.
+ * cp-tree.h (hack_incomplete_structures): Rename to ...
+ (complete_vars): ... this.
+ (struct saved_scope): Remove incomplete.
+ (namespace_scope_incomplete): Remove.
+ * decl.c (struct binding_level): Remove incomplete.
+ (incomplete_vars): New variable.
+ (mark_binding_level): Don't mark incomplete.
+ (print_binding_level): Don't print it.
+ (mark_saved_scope): Don't mark incomplete.
+ (pushdecl): Use maybe_register_incopmlete_var.
+ (cxx_init_decl_processing): Register incomplete_vars for GC.
+ (start_decl_1): Clarify error message.
+ (hack_incomplete_vars): Remove.
+ (maybe_register_incomplete_var): New function.
+ (complete_vars): Likewise.
+
+2002-04-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/4934
+ * error.c (dump_expr) [CONVERT_EXPR]: Make sure TREE_TYPE (t) is
+ set before checking it.
+
+ PR c++/525
+ * init.c (build_member_call): Use build_scoped_ref.
+ (resolve_offset_ref): Likewise.
+ * call.c (build_scoped_method_call): Likewise.
+ * tree.c (maybe_dummy_object): Kludge around current_class_type being
+ wrong.
+ * typeck2.c (build_scoped_ref): Return the binfo via binfo_p parm.
+ * cp-tree.h: Adjust.
+
+ * init.c (push_base_cleanups): Just use build_scoped_method_call.
+
+ PR c++/6179
+ * method.c (implicitly_declare_fn): Pass unqualified type to
+ synthesize_exception_spec.
+
+2002-04-04 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Redefine.
+ * cvt.c: Update comment.
+ * init.c (expand_cleanup_for_base): Update.
+ * semantics.c (finish_parenthesized_expr): Update.
+ * typeck.c (cp_truthvalue_conversion): Update.
+
+2002-04-04 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_eh_cleanup): New fn.
+ * cp-tree.h: Add prototype.
+ * init.c (perform_member_init, expand_cleanup_for_base): Use
+ finish_eh_cleanup.
+ * cp-tree.def (SUBOBJECT, CTOR_STMT): Remove.
+ * cp-tree.h: Remove references.
+ * decl.c (begin_constructor_body, end_constructor_body): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (genrtl_ctor_stmt, genrtl_subobject): Remove.
+ (cp_expand_stmt): Remove handling of CTOR_STMT and SUBOBJECT.
+ * tree.c (cp_statement_code_p): Likewise.
+
+ * init.c (build_new_1): Set CLEANUP_EH_ONLY on deleting cleanup.
+
+ PR c++/5636
+ * semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on
+ cleanup for nrv.
+
+ PR c++/5104
+ * typeck.c (comptypes) [FUNCTION_TYPE]: Don't compare exception
+ specifiers.
+ [METHOD_TYPE]: Use same code as FUNCTION_TYPE.
+
+2002-04-03 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (cxx_warn_unused_global_decl): New.
+ (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
+
+2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine.
+ * tree.c (init_tree): Don't set hook.
+
+2002-04-03 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (duplicate_decls): Don't mess with assembler names when
+ redeclaring builtin functions as static.
+
+2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_addr_func): Update.
+ * class.c (resolve_address_of_overloaded_function): Update.
+ * cp-lang.c (LANG_HOOKS_MARK_ADDRESSABLE): Redefine.
+ * cp-tree.h (cxx_mark_addressable): New.
+ * decl.c (register_dtor_fn, cxx_maybe_build_cleanup): Update.
+ * decl2.c (build_cleanup): Update.
+ * except.c (build_throw): Update.
+ * init.c (resolve_offset_ref): Update.
+ * pt.c (convert_nontype_argument): Update.
+ * semantics.c (finish_asm_stmt, simplify_affr_init_exprs_r): Update.
+ * typeck.c (decay_conversion, build_array_ref, build_unary_op,
+ unary_complex_lvalue): Update.
+ (mark_addressable): Rename.
+
+2002-04-01 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (duplicate_decls): Overwrite the RTL when (and only
+ when) overwriting a built-in function. Don't use COPY_DECL_RTL,
+ but follow the SET_DECL_RTL idiom used elsewhere in the function.
+
+2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE,
+ LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): New.
+ * decl.c (grokdeclarator): Update.
+ * mangle.c (write_integer_cst): Update.
+ * typeck.c (build_binary_op): Update.
+
+2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Redefine.
+ * lex.c (cxx_init): Don't set hook.
+
+2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * Make-lang.in (error.o): Update.
+ * cp-lang.c (LANG_HOOKS_PRINT_ERROR_FUNCTION): Redefine.
+ * cp-tree.h (struct diagnostic_context): Predeclare.
+ (cxx_print_error_function): New.
+ * error.c: Include langhooks-def.h.
+ (lang_print_error_function): Rename. Update.
+ (init_error): Don't set hook.
+
+2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
+ Redefine.
+ * cvt.c (cp_convert_to_pointer, type_promotes_to): Use new hooks.
+ * decl.c (finish_enum): Similarly.
+ * error.c (dump_type): Similarly.
+ * lex.c (cxx_init): Similarly.
+ * mangle.c (write_builtin_type): Similarly.
+ * typeck.c (comptypes): Similarly.
+
+2002-03-28 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (cxx_init_decl_processing): Re-enable built-in functions
+ in the g++ front-end.
+ (duplicate_decl): Allow redefinition of anticipated built-ins.
+ Fix inlining problem by over-writing the old DECL_RTL.
+ (lookup_namespace_name): Fail to find an identifier in the
+ specified namespace if its still anticipated.
+ (builtin_function_1): New function split out from builtin_function
+ to create a builtin in the current namespace with given context.
+ (builtin_function): Call builtin_function_1 to define the
+ appropriate builtins in both the std and global namespaces.
+ (select_decl): Don't test for anticipated decls here.
+ (unqualified_namespace_lookup): Instead ignore them whilst
+ searching through scopes and namespaces.
+ * decl2.c (do_nonmember_using_decl): If a using declaration
+ specifies an anticipated built-in function, mark it as no longer
+ anticipated in that scope.
+ (ambiguous_decl): Avoid resolving to an anticipated decl.
+ * lex.c (do_scoped_id): Fail to find an identifier in the global
+ namespace if its still anticipated.
+
+2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_MAKE_TYPE): Redefine.
+ * cp-tree.h (cp_make_lang_type): Rename.
+ * lex.c (cp_make_lang_type): Rename.
+ (make_aggr_type): Update.
+ * tree.c (init_tree): Don't set make_lang_type_fn.
+
+2002-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6073
+ * class.c (finish_struct_1): Update static field's DECL_MODE even
+ if its type is a variant of t.
+
+2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Redefine.
+ * cp-tree.h (cxx_insert_default_attributes): New.
+ * decl.c (insert_default_attributes): Rename.
+
+2002-03-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884
+ * call.c (build_op_delete_call): Allow for the fact the placement
+ may be a COMPOUND_EXPR.
+
+2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_EXPAND_EXPR): Redefine.
+ * cp-tree.h (init_cplus_expand): Remove.
+ (cxx_expand_expr): New.
+ * expr.c (cplus_expand_expr): Rename cxx_expand_expr,
+ fix prototype.
+ (init_cplus_expand): Remove.
+ * lex.c (cxx_init): Don't call init_cplus_expand.
+
+2002-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884.
+ * init.c (build_new_1): Allow for the fact the result of
+ build_function_call may be a COMPOUND_EXPR.
+
+2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5682
+ * cp-tree.h (BINFO_PRIMARY_P): Explain meaning better.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ * search.c (get_shared_vbase_if_not_primary): Remove.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo.
+ (dfs_marked_real_bases_queue_p): Likewise.
+
+2002-03-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_MARK_TREE): Redefine.
+ * cp-tree.h (cxx_mark_tree): New.
+ * decl.c (lang_mark_tree): Rename cxx_mark_tree.
+
+2002-03-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (cxx_maybe_build_cleanup): New.
+ * decl.c (destroy_local_var, hack_incomplete_structures): Update.
+ (maybe_build_cleanup): Rename cxx_maybe_build_cleanup.
+ * tree.c (build_target_expr): Update.
+ * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP): Redefine.
+
+2002-03-24 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (cxx_decode_option): Handle -E.
+ * lang-specs.h (default_compilers): Preprocess with cc1plus.
+ * lex.c (cxx_init): Exit quickly if c_common_init returns NULL.
+
+2002-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6037
+ * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node.
+
+2002-03-23 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (dump_type): Be careful about implicit typenames.
+
+2002-03-21 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ PR C++/3656
+ * semantics.c (finish_base_specifier): Handle erronous base
+ classes.
+
+2002-03-22 Zack Weinberg <zack@codesourcery.com>
+
+ * error.c: Always use REAL_VALUE_TO_DECIMAL; don't test
+ REAL_IS_NOT_DOUBLE.
+
+2002-03-22 Jeff Knaggs <jknaggs@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Scale idx down to
+ an index into the vtable_entry array regardless of
+ TARGET_PTRMEMFUNC_VBIT_LOCATION.
+
+2002-03-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (cp_cannot_inline_tree_fn): Same.
+
+2002-03-21 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (pushdecl, pushlevel, poplevel, set_block,
+ insert_block, getdecls, global_bindings_p): New.
+
+2002-03-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4361
+ * mangle.c (struct globals) Add internal_mangling_p member.
+ (write_template_param): Do internal mangling, if needed.
+ (mangle_conv_op_name_for_type): Request internal mangling.
+
+2002-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/2136
+ * init.c (build_delete): Check access for a member op delete here.
+ * decl2.c (delete_sanity): Not here.
+
+2002-03-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/5118
+ * class.c (get_vfield_name): Use the constructor_name.
+
+2002-03-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Redefine.
+ * cp-tree.h (lang_printable_name): Rename.
+ * error.c (lang_decl_name): Use new hook.
+ * lex.c (cxx_init): Remove old hook.
+ * pt.c (tsubst_decl): Use new hook.
+ * tree.c (lang_printable_name): Rename.
+
+2002-03-18 Eric Botcazou <ebotcazou@multimania.com>
+
+ PR c++/3882
+ * pt.c (tsubst_decl): Move __PRETTY_FUNCTION__ handling...
+ (tsubst_expr) [DECL_STMT]: ...here. And substitute the initializer
+ only after recording the declaration.
+
+2002-03-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/2039
+ * init.c (resolve_offset_ref): Hand off to build_component_ref.
+
+ PR c++/4222, c++/5995
+ * call.c (build_over_call): Fix empty class logic.
+
+ PR c++/3870
+ * cp-tree.h (struct saved_scope): Add last_parms field.
+ * decl.c (maybe_push_to_top_level): Save last_function_parms.
+ (pop_from_top_level): Restore it.
+
+ PR c++/4377
+ * mangle.c (write_expression): Strip NOP_EXPRs sooner. Also strip
+ NON_LVALUE_EXPRs.
+
+ PR c++/4003
+ * pt.c (tsubst_friend_function): Use decl_namespace_context.
+
+ PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
+ * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a
+ type with a nontrivial destructor.
+
+2002-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/4460
+ * class.c (build_base_path): Virtual base layout is fixed in
+ in-charge [cd]tors.
+
+2002-03-17 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_PARSE_FILE): Redefine.
+ * parse.y (yyparse): Remove macro.
+
+2002-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/5757
+ * init.c (build_new_1): Pass the right pointer to op delete.
+
+2002-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4361
+ * cp-tree.h (CLASSTYPE_METHOD_VEC): Document where templated
+ conversion operators go.
+ (struct lang_decl_flags): Add template_conv_p and unused
+ bitfields.
+ (DECL_TEMPLATE_CONV_FN_P): New macro.
+ * call.c (build_user_type_conversion_1): Don't check second type
+ conversion of overload set first.
+ * class.c (add_method): Make sure templated conversion operators
+ all end up on slot 2.
+ * lex.c (do_identifier): A conversion operator token might be
+ satisfied by a templated conversion operator.
+ * pt.c (check_explicit_specialization): Use
+ CLASSTYPE_FIRST_CONVERSION_SLOT.
+ (template_parm_this_level_p): New function.
+ (push_template_decl_real): Determine DECL_TEMPLATE_CONV_FN_P.
+ * search.c (lookup_fnfields_1): Template conversions will be on
+ the first slot.
+ * typeck.c (build_component_ref): Preserve the type of an
+ conversion operator name on the overload type.
+ (build_x_function_call): Retrieve the conversion operator name.
+
+2002-03-15 Richard Henderson <rth@redhat.com>
+
+ * init.c (build_new_1): Use size_binop instead of cp_build_binary_op.
+
+2002-03-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEANUP_DECL): Remove.
+ (CLEANUP_EXPR): Likewise.
+ * decl.c (destroy_local_var): Simplify.
+ (maybe_build_cleanup): Tidy.
+ * dump.c (cp_dump_tree): Remove handling of CLEANUP_STMT.
+ * semantics.c (cp_expand_stmt): Likewise.
+ * cp/tree.c (cp_statement_code_p): Likewise.
+
+2002-03-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/5857
+ * decl.c (duplicate_decls): Use merge_types instead of common_type.
+ * typeck.c (common_type): Just hand off to
+ type_after_usual_arithmetic_conversions and
+ composite_pointer_type.
+ (merge_types): New fn.
+ (commonparms): Use it instead of common_type.
+ (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE.
+ (composite_pointer_type): Also handle attributes.
+ * cp-tree.h: Declare merge_types.
+
+ * decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
+ variables.
+ * decl2.c (maybe_make_one_only): Also mark the decl as needed.
+
+2002-03-14 Richard Henderson <rth@redhat.com>
+
+ * decl.c: Include c-pragma.h.
+ (start_decl, start_function): Invoke maybe_apply_pragma_weak.
+ * Make-lang.in: Update dependencies.
+
+2002-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/5908
+ * call.c (build_over_call): Set TREE_NO_UNUSED_WARNING too.
+ * cvt.c (convert_to_void): Preserve TREE_NO_UNUSED_WARNING.
+
+2002-03-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * mangle.c (write_builtin_type): Handle 128-bit integers even if
+ they are not a standard integer type.
+
+2002-03-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * cp-tree.h (init_init_processing): Remove declaration.
+ * init.c (BI_header_type, init_init_processing): Remove old ABI stuff.
+ * decl.c (cxx_init_decl_processing): Don't call init_init_processing.
+
+2002-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-lang.c (tree_code_type, tree_code_length, tree_code_name):
+ Define.
+ * decl.c (duplicate_decls): Use TREE_CODE_LENGTH, not
+ tree_code_length.
+ * lex.c (cplus_tree_code_type, cplus_tree_code_length,
+ cplus_tree_code_name): Delete.
+ (cxx_init): Don't call add_c_tree_codes, instead set
+ lang_unsafe_for_reeval. Don't try to copy into the various
+ tree_code arrays.
+
+2002-03-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5659
+ * decl.c (xref_tag): Don't set CLASSTYPE_DECLARED_CLASS here.
+ * decl2.c (handle_class_head): Set CLASSTYPE_DECLARED_CLASS for
+ definitions.
+
+2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert 2001-03-26 Nathan Sidwell <nathan@codesourcery.com>,
+ DR209 is now not a defect.
+ * cp-tree.h (skip_type_access_control): Remove.
+ * decl.c (grokdeclarator): Do type access control for friend
+ declarations.
+ * semantics.c (decl_type_access_control): Don't reset
+ current_type_lookups.
+ (save_type_access_control): Always save the lookups.
+ (skip_type_access_control): Remove.
+ (finish_class_definition): Don't change type_lookups.
+
+2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert 2000-12-01 Nathan Sidwell <nathan@codesourcery.com>,
+ It is incorrect.
+ * typeck.c (build_static_cast): Compare non-qualified types
+ with pointer to member conversions.
+
+2002-03-11 Dan Nicolaescu <dann@ics.uci.edu>
+ Daniel Berlin <dan@dberlin.org>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): New function.
+ (cxx_get_alias_set): Use it.
+
+2002-03-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (stabilize_expr): Prototype.
+
+2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
+ conditional return void.
+
+2002-03-08 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_UNSAVE): Redefine.
+ * cp-tree.h (cxx_unsave): New.
+ * tree.c (cp_unsave): Rename cxx_unsave, update prototype.
+ (init_tree): Update.
+
+2002-03-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (cxx_init_decl_processing): Use ARRAY_SIZE in lieu of
+ explicit sizeof/sizeof.
+ * decl2.c (cxx_decode_option): Likewise.
+ * lex.c (init_reswords, REDUCE_LENGTH, TOKEN_LENGTH): Likewise.
+
+2002-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/775
+ * decl.c (lookup_tag): Only reject enum/class mismatch, not
+ class/union mismatch.
+ * parse.y (check_class_key): New function.
+ (structsp): Call it.
+
+2002-03-01 Michael Matz <matz@suse.de>
+
+ * typeck.c (cp_pointer_int_sum): Complete inner type which is
+ used later by size_in_bytes().
+
+2002-03-01 Phil Edwards <pme@gcc.gnu.org>
+
+ * cp-tree.h: Require __GNUC__ to be #defined.
+ (build_init): Add missing prototype.
+
+2002-03-01 Jason Merrill <jason@redhat.com>
+
+ * except.c: Don't include decl.h or obstack.h. Do include
+ tree-inline.h.
+ (build_throw): Destroy temporaries from the thrown
+ expression before calling __cxa_throw. Construct a thrown
+ temporary directly into the exception object.
+ (stabilize_throw_expr): New function.
+ (wrap_cleanups_r): New function.
+ * tree.c (stabilize_expr): New function.
+ * init.c (build_init): New function.
+ * Make-lang.in (cp/except.o): Adjust .h deps.
+
+2002-02-28 Jason Merrill <jason@redhat.com>
+
+ * search.c (lookup_base_r): Don't clear is_non_public just because
+ we found a friendly scope.
+
+ * decl.c (finish_function): Only warn about missing return
+ statement with -Wreturn-type.
+
+2002-02-28 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * class.c (build_clone): Update.
+ * cp-lang.c (LANG_HOOKS_DUP_LANG_SPECIFIC_DECL): Redefine.
+ * cp-tree.h (cxx_dup_lang_specific_decl): New.
+ * lex.c (copy_lang_decl): Rename cxx_dup_lang_specific_decl.
+ (copy_decl): Update.
+ * method.c (make_thunk): Update.
+
+2002-02-27 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c: Delete traditional-mode-related code copied from
+ the C front end but not used, or used only to permit the
+ compiler to link.
+
+2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ PR c++/4093
+ * cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
+ to void.
+
+2002-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/5746
+ * semantics.c (finish_switch_cond): Don't call get_unwidened
+ if error_mark_node.
+
+2002-02-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2645, DR 295
+ * cp-tree.h (tsubst_flags_t): Add tf_ignore_bad_quals,
+ tf_keep_type_decl.
+ (make_typename_type): Use tsubst_flags_t.
+ * decl.c (make_typename_type): Adjust. Return non-artificial
+ TYPE_DECLs, if required.
+ (grokdeclarator): Simplify CVR qualification handling. Allow bad
+ qualifiers on typedef types.
+ * decl2.c (handle_class_head): Adjust make_typename_type call.
+ * parse.y (nested_name_specifier): Likewise.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ * pt.c (convert_template_argument): Adjust make_typename_type
+ return value.
+ (tsubst): Adjust cp_build_qualified_type_real calls.
+ (check_cv_quals_for_unify): Cope with allowing bad qualifications
+ on template type parms.
+ (instantiate_decl): Recheck substitutions to give warnings on bad
+ qualifications.
+ * tree.c (cp_build_qualified_type_real): Use tf_allow_bad_quals.
+
+2002-02-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp/decl.c (duplicate_decls): Merge always_inline attribute.
+
+ * cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0
+ unless DECL_ALWAYS_INLINE.
+
+2002-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (cp_pointer_int_sum): Renamed from
+ pointer_int_sum, call pointer_int_sum.
+
+2002-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): Return 0 if issued error about
+ redeclaration.
+
+2002-02-19 Jason Merrill <jason@redhat.com>
+
+ ABI change: Mangle `void (A::*)() const' as
+ M1AKFvvE, not MK1AFvvE.
+ * mangle.c (write_function_type): Write cv-quals for member
+ function type here.
+ (write_pointer_to_member_type): Not here.
+
+2002-02-18 Jason Merrill <jason@redhat.com>
+
+ * pt.c (do_type_instantiation): Don't pedwarn if in_system_header.
+ (do_decl_instantiation): Likewise.
+
+2002-02-17 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ PR c++/5685
+ * decl.c (duplicate_decls): Make warning unconditional
+ if duplicate default argument declarations are present.
+
+2002-02-17 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (build_binary_op) [BIT_XOR_EXPR]: Remove explicit
+ shortening.
+
+2002-02-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Set typedef_decl for all TYPE_DECLs,
+ remove incorrect comment. Move #if 0'd code to common path. Use
+ IMPLICIT_TYPENAME_P. Simplify & reformat ARRAY_TYPE duplication.
+
+2002-02-13 Jason Merrill <jason@redhat.com>
+
+ * decl.c (builtin_function): Set TREE_THIS_VOLATILE on return fns.
+ (finish_function): Don't warn if current_function_returns_null.
+
+ * typeck2.c (digest_init): Do handle values of vector type.
+
+ * typeck2.c (digest_init, process_init_constructor): Treat vectors
+ like arrays.
+
+2002-02-11 Jason Merrill <jason@redhat.com>
+
+ * parse.y (reserved_declspecs): Don't handle attributes.
+ (reserved_typespecquals): Handle them here.
+ * Make-lang.in (parse.c): Adjust expected conflicts.
+
+2002-02-08 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (primary, primary_no_id): Use compstmt_or_stmtexpr
+ instead of compstmt.
+ (compstmt_or_stmtexpr): Renamed from compstmt.
+ (compstmt): In addition to compstmt_or_stmtexpr clear last_expr_type.
+
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename instantiate_type_flags to tsubst_flags_t & expand use.
+ * cp-tree.h (instantiate_type_flags): Rename to ...
+ (tsubst_flags_t): ... here. Rename itf_complain to tf_error,
+ add tf_warning flag.
+ (instantiate_type): Adjust prototype.
+ (tsubst, tsubst_expr, tsubst_copy, lookup_template_class,
+ do_type_instantiation, cp_build_qualified_type_real): Likewise.
+ cp_build_qualified_type: Adjust.
+ * class.c (instantiate_type): Adjust parameter. Rename itf_* to
+ tf_*.
+ * call.c (standard_conversion): Rename itf_* to tf_*.
+ (reference_binding): Likewise.
+ (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * decl.c (lookup_namespace_name): Use tf_* flags.
+ (make_typename_type): Likewise.
+ (grokdeclarator): Likewise.
+ * pt.c (convert_nontype_argument): Adjust COMPLAIN usage.
+ (coerce_template_template_parms, convert_template_argument,
+ coerce_template_parms, maybe_get_template_decl_from_type_decl,
+ lookup_template_class, tsubst_friend_function, tsubst_friend_class,
+ instantiate_class_template, tsubst_template_arg_vector,
+ tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
+ tsubst_decl, tsubst_arg_types, tsubst_function_type,
+ tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
+ instantiate_template, fn_type_unification,
+ resolve_overloaded_unification, verify_class_unification,
+ unify, get_bindings_real, do_type_instantiation,
+ regenerate_decl_from_template, instantiate_decl,
+ tsubst_initializer_list, tsubst_enum,
+ get_mostly_instantiated_function_type,
+ invalid_nontype_parm_type_p): Likewise.
+ * tree.c (cp_build_qualified_type_real): Likewise.
+ * typeck.c (build_binary_op): Rename itf_* to tf_*.
+ (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/109
+ * decl.c (grokdeclarator): Allow friend declarations from
+ dependent types.
+ * decl2.c (handle_class_head): Don't push into template parm contexts.
+ * pt.c (push_template_decl_real): Template parm contexts are never
+ being defined.
+
+2002-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * class.c: Include target.h.
+ (check_bitfield_decl): Disregard EMPTY_FIELD_BOUNDARY,
+ BITFIELDS_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS for MS
+ bit-field layout.
+ * Make-lang.in: Adjust deps.
+
+2002-02-05 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_type): Be more helpful about VECTOR_TYPE.
+
+2002-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (begin_switch_stmt): Clear SWITCH_TYPE.
+ (finish_switch_cond): Set SWITCH_TYPE.
+
+2002-02-04 Richard Henderson <rth@redhat.com>
+
+ * method.c (use_thunk): Always initialize the block tree. Reindent.
+ * semantics.c (expand_body): Emit thunks after function, not before.
+
+2002-02-04 Jason Merrill <jason@redhat.com>
+
+ * decl.c (start_function): Call cplus_decl_attributes immediately
+ after grokdeclarator.
+
+ * decl.c (start_function): Combine DECL_RESULT handling code.
+
+2002-02-03 Jason Merrill <jason@redhat.com>
+
+ * xref.c: Remove.
+ * Make-lang.in (CXX_OBJS): Remove cp/xref.o
+ (cp/xref.o): Remove dependencies.
+ * class.c (finish_struct_1, check_methods): Don't call xref fns.
+ (finish_struct_1): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * lex.c (cxx_init, cxx_finish, extract_interface_info): Likewise.
+ * spew.c (read_process_identifier): Likewise.
+
+2002-02-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/4872
+ * decl.c (finish_function): Warn about a non-void function with
+ no return statement and no abnormal exit.
+ * cp-tree.h (struct cp_language_function): Add returns_abnormally.
+ (current_function_returns_abnormally): New macro.
+ * call.c (build_call): Set it.
+
+ * typeck.c (build_component_ref): Always complain about offsetof
+ constructs on non-PODs. Only make it an error for members of
+ virtual bases.
+
+ * error.c (dump_scope): Don't add TFF_DECL_SPECIFIERS.
+ (dump_function_decl): Always dump parms.
+
+ * decl2.c (finish_static_data_member_decl): Complain about a local
+ class with a static data member.
+
+ PR c++/4286
+ * search.c (lookup_field_1): Don't xref a static data member
+ just because we looked it up.
+
+2002-01-31 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (parse.c): Handle .output file.
+
+ PR c++/3395
+ * decl.c (xref_tag): Remember early attributes in TYPE_ATTRIBUTES,
+ not TREE_TYPE.
+ * semantics.c (finish_class_definition): Adjust.
+
+ Allow attributes in parms and casts.
+ * parse.y (named_parm): Don't strip attrs.
+ (declmods): Remove 'attributes' production.
+ (nonempty_cv_qualifiers): Accept attributes.
+ (ATTRIBUTE): Give precedence.
+ * decl.c (groktypename): Handle attributes.
+ (grokparms): Likewise.
+
+2002-01-29 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (cxx_decode_option): Pass 0 as last argument to
+ cpp_handle_option.
+ * lang-specs.h: Use cpp_unique_options instead of cpp_options
+ when used together with cc1_options.
+
+2002-01-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5132
+ * typeck2.c (digest_init): Make sure non-array core type is
+ instantiated.
+ * decl2.c (reparse_absdcl_as_casts): Just store the type in the
+ constructor, rather than build a new one.
+ (build_expr_from_tree, CONSTRUCTOR case): Be careful with the
+ PURPOSE of constructor elts.
+
+2002-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (parse.c): Adjust expected number of
+ shift-reduce conflicts.
+ (decl.o): Depend on diagnostic.h.
+ * decl.c: Include diagnostic.h.
+ (grokdeclarator): Check for null pointer.
+ (finish_function): Don't abort when
+ current_binding_level->parm_flag != 1, if errors have
+ occurred; throw away the statement tree and extra binding
+ levels, and continue.
+ * lex.c (note_list_got_semicolon): Check for null pointer.
+ * method.c (hack_identifier): Just return error_mark_node if
+ value is error_mark_node.
+ * parse.y (primary: TYPEID(type_id)): No need to use
+ TYPE_MAIN_VARIANT here.
+ (handler_seq): Accept an empty list of catch clauses and
+ generate a fake handler block to avoid later crashes.
+ (ansi_raise_identifier): Accept the error token too.
+ * semantics.c (begin_class_definition,
+ finish_class_definition): Check for error_mark_node.
+
+2002-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ * typeck2.c (friendly_abort): Delete definition.
+ * cp-tree.h (friendly_abort): Don't prototype.
+ (my_friendly_assert): Use fancy_abort.
+
+2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * cp-tree.h (my_friendly_abort): Remove.
+
+2002-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ * spew.c (pending_inlines, pending_inlines_tail,
+ processing_these_inlines): Make static.
+ (mark_pending_inlines): Remove static.
+ (begin_parsing_inclass_inline): If in function, save pi
+ for GC to cp_function_chain->unparsed_inlines instead.
+ (process_next_inline): Likewise.
+ * cp-tree.h (struct cp_language_function): Add unparsed_inlines.
+ (mark_pending_inlines): Add prototype.
+ * decl.c (spew_debug): Remove unused extern.
+ (mark_lang_function): Call mark_pending_inlines.
+
+2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * call.c, class.c, decl.c, decl2.c, error.c, expr.c, friend.c,
+ init.c, lex.c, mangle.c, method.c, pt.c, repo.c, rtti.c, search.c,
+ semantics.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c:
+ Change my_fancy_abort() to abort().
+
+2002-01-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/5453
+ * class.c (fixed_type_or_null): Fix thinko.
+
+ PR c++/3331
+ * init.c (resolve_offset_ref): Use build_indirect_ref.
+
+ * decl2.c (grokclassfn): Don't set DECL_REGISTER on 'this'.
+
+2002-01-22 Jason Merrill <jason@redhat.com>
+
+ * parse.y (function_body): Suppress the block for the outermost
+ curly braces.
+ * decl.c (pushdecl): Don't try to skip it.
+ (begin_function_body): Keep the block we create, not the next one.
+ * init.c (emit_base_init): Don't mess with keep_next_level.
+
+ * class.c (build_base_path): Tweak formatting.
+
+2002-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix regression introduced with patch for c++/775
+ * parse.y (class_head_defn): Check for template specializations
+ with a different class-key.
+
+2002-01-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (begin_constructor_body, begin_destructor_body): New fns.
+ (begin_function_body): Call them and keep_next_level.
+ * init.c (emit_base_init): Call keep_next_level.
+ * semantics.c (setup_vtbl_ptr): Lose.
+ * cp-tree.h (struct cp_language_function): Remove vtbls_set_up_p.
+ (vtbls_set_up_p): Lose.
+ * pt.c (tsubst_expr, CTOR_INITIALIZER): Call emit_base_init.
+ * method.c (do_build_copy_constructor): Likewise.
+ (synthesize_method): Call finish_mem_initializers.
+ * parse.y (nodecls): Likewise.
+
+ * error.c (dump_type_suffix): Print the exception specs before
+ recursing.
+ (dump_function_decl): Here, too.
+
+ * cp-tree.h (TMPL_PARMS_DEPTH): Cast to signed HOST_WIDE_INT.
+
+2002-01-10 Ira Ruben <ira@apple.com>
+
+ PR c++/907
+ * decl.c (start_method): Handle attrlist.
+
+2002-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (max_tinst_depth): Increase default limit to 500.
+
+2002-01-10 Graham Stott <grahams@redhat.com>
+
+ * spew.c (YYCHAR): Uppercase macro parameter and add
+ parenthesis.
+ (YYCODE): Likewise.
+ (NAME): Uppercase macro parameter.
+
+2002-01-09 Graham Stott <grahams@redhat.com>
+
+ * decl.h (grokdeclarator): Wrap long line.
+
+ * semantics.c (FINISH_COND): Uppercase macro paramaters and
+ add parenthesis.
+
+2002-01-08 Graham Stott <grahams@redhat.com>
+
+ * xref.c (FILE_NAME_ABSOLUTE_P): Add parenthesis.
+ (PALLOC): Uppercase macro parameter and whitespace.
+ (SALLOC): Uppercase macro parameter.
+ (SFREE): Uppercase macros parameter, add parenthese and
+ whitespace.
+ (STREQL): Uppercase macro parameter and whitespace.
+ (STRNEQ): Likewise.
+ (STRLSS): Likewise.
+ (STRLEQ): Likewise.
+ (STRGTR): Likewise.
+ (STRGEQ): Likewise.
+
+ * call.c (convert_like): Add parenthesis and wrap.
+ (convert_like_with_context): Likewise.
+ (ICS_RANK): Whitespace.
+ (NEED_TEMPORARY_P): Remove parenthesis.
+
+ * class.c (VTT_TOP_LEVEL_P): Uppercase macro parameter and
+ whitespace.
+ (VTT_MARKED_BINFO_P): Likewise.
+
+ * decl.c (BINDING_LEVEL): Add parenthesis.
+ (DEF_OPERATOR): Likewise.
+
+ * mangle.c (MANGLE_TRACE): Add parenthesis.
+ (MANGLE_TRACE_TREE): Likewise.
+ (write_signed_number): Likewise.
+ (write_unsigned_number): Likewise.
+
+ * pt.c (ccat): Uppercase macro parameter.
+ (cat): Likewise
+
+ * search.c (SET_BINFO_ACCESS): Add parenthesis.
+
+2002-01-07 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (coerce_new_type): Downgrade error for size_t mismatch
+ to pedwarn.
+
+ PR c++/3536
+ * method.c (make_thunk): If !flag_weak, give the thunk the
+ function's linkage.
+ (use_thunk): Here, too.
+
+2002-01-07 Graham Stott <grahams@redhat.com>
+
+ * error.c: Update copyright date.
+ (print_scope_operator): Add parenthesis.
+ (print_left_paren): Likewise.
+ (print_right_paren): Likewise.
+ (print_left_bracket): Likewise.
+ (print_right_bracket): Likewise.
+ (print_template_argument_list_start): Likewise.
+ (print_template_argument_list_end): Likewise.
+ (print_non_consecutive_character): Likewise.
+ (print_tree_identifier): Likewise.
+ (print_identifier): Likewise.
+ (NEXT_CODE): Uppercase macro parameter.
+ (ident_fndecl): Delete unused.
+ (GLOBAL_THING): Likewise.
+
+2002-01-06 Graham Stott <grahams@redhat.com>
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK): Add parenthesis.
+ (VAR_FUNCTION_OR_PARM_DECL_CHECK): Likewise.
+ (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK) Likewise.
+ (RECORD_OR_UNION_TYPE_CHECK): Likewise.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Likewise.
+ (C_IS_RESERVED_WORD): Uppercase macro parameter.
+ (C_RID_YYCODE) Likewise.
+ (ptrmem_cst): Use rtx.
+ (LOCAL_BINDING_P): Add whitespace.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Wrap long line.
+ (BINDING_HAS_LEVEL_P): Remove parenthesis.
+ (BINDING_VALUE): Wrap long line.
+ (BINDING_TYPE): Whitespace.
+ (IDENTIFIER_GLOBAL_VALUE): Add parenthesis.
+ (SET_IDENTIFIER_GLOBAL_VALUE): Likewise.
+ (IDENTIFIER_NAMESPACE_VALUE): Likewise.
+ (SET_IDENTIFIER_NAMESPACE_VALUE: Likewise.
+ (same_type_p): Uppercase macro parameters.
+ (same_type_ignoring_top_level_qualifiers_p): Likewise.
+ (OVL_FUNCTION): Wrap long line.
+ (OVL_CHAIN): Whitespace.
+ (OVL_CURRENT): Add parenthesis and whitespace.
+ (OVL_NEXT): Whitespace.
+ (OVL_USED): Likewise.
+ (IDENTIFIER_TYPE_VALUE): Likewise.
+ (REAL_IDENTIFIER_TYPE_VALUE): Remove parenthesis.
+ (SET_IDENTIFIER_TYPE_VALUE): Add parenthesis and whitespace.
+ (LANG_ID_FIELD): Whitespace.
+ (SET_LANG_ID(NODE,VALUE,NAME): Likewise.
+ (IDENTIFIER_LABEL_VALUE): Whitespace and wrap.
+ (SET_IDENTIFIER_LABEL_VALUE): Whitespace.
+ (IDENTIFIER_IMPLICIT_DECL): Whitespace and wrap.
+ (SET_IDENTIFIER_IMPLICIT_DECL); Whitespace.
+ (IDENTIFIER_ERROR_LOCUS): Whitespace and wrap.
+ (SET_IDENTIFIER_ERROR_LOCUS); Whitespace.
+ (IDENTIFIER_VIRTUAL_P): Likewise.
+ (IDENTIFIER_OPNAME_P): Likewise.
+ (IDENTIFIER_TYPENAME_P): Remove parenthesis.
+ (C_TYPE_FIELDS_READONLY): Uppercase macro parameters.
+ (C_SET_EXP_ORIGINAL_CODE): Likewise.
+ (TYPE_ASSEMBLER_NAME_STRING): Wrap long line.
+ (TYPE_ASSEMBLER_NAME_LENGTH): Likewise.
+ (IS_AGGR_TYPE): Uppercase macro parameter.
+ (CLASS_TYPE_P): Likewise.
+ (IS_AGGR_TYPE_CODE): Uppercase macro parameter and parenthesis.
+ (IS_AGGR_TYPE_2): Whitespace.
+ (TAGGED_TYPE_P): Uppercase macro parameter.
+ (TYPE_BUILT_IN): Whitespace.
+ (TYPE_FOR_JAVA): Likewise.
+ (FUNCTION_ARG_CHAIN): Remove parenthesis.
+ (FUNCTION_FIRST_USER_PARMTYPE): Add parenthesis.
+ (FUNCTION_FIRST_USER_PARAM): Likewise.
+ (PROMOTES_TO_AGGR_TYPE): Whitespace.
+ (DERIVED_FROM_P): Add parenthesis and wrap.
+ (UNIQUELY_DERIVED_FROM_P): Likewise.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P): Likewise.
+ (PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+ (CLASSTYPE_USE_TEMPLATE): Whitespace.
+ (CLASSTYPE_INLINE_FRIENDS): Remove parenthesis.
+ (TYPE_GETS_DELETE): Add parenthesis.
+ (TYPE_HAS_CONVERSION): Add parenthesis and wrap.
+ (TYPE_HAS_ASSIGN_REF): Likewise,
+ (TYPE_HAS_CONST_ASSIGN_REF): Likewise.
+ (TYPE_HAS_INIT_REF): Likewise.
+ (TYPE_HAS_CONST_INIT_REF): Likewise.
+ (TYPE_BEING_DEFINED): Likewise.
+ (TYPE_LANG_SPECIFIC): Likewise.
+ (CLASSTYPE_RTTI): Likewise.
+ (TYPE_OVERLOADS_CALL_EXPR): Likewise.
+ (TYPE_OVERLOADS_ARRAY_REF): Likewise.
+ (TYPE_OVERLOADS_ARROW): Likewise.
+ (TYPE_USES_MULTIPLE_INHERITANCE): Likewise.
+ (TYPE_USES_VIRTUAL_BASECLASSES): Add parenthesis.
+ (CLASSTYPE_METHOD_VEC): Likewise.
+ (CLASSTYPE_MARKED_N): Likewise.
+ (CLASSTYPE_MARKED): Likewise.
+ (CLASSTYPE_MARKED2): Likewise.
+ (CLASSTYPE_MARKED3): Likewise.
+ (CLASSTYPE_MARKED4): Likewise.
+ (CLASSTYPE_MARKED5): Likewise.
+ (CLASSTYPE_MARKED6): Likewise.
+ (SET_CLASSTYPE_MARKED): Whitespace.
+ (CLEAR_CLASSTYPE_MARKED): Likewise.
+ (SET_CLASSTYPE_MARKED2): Likewise.
+ (CLEAR_CLASSTYPE_MARKED2): Likewise.
+ (SET_CLASSTYPE_MARKED3): Likewise.
+ (CLEAR_CLASSTYPE_MARKED3): Likewise.
+ (SET_CLASSTYPE_MARKED4): Likewise.
+ (CLEAR_CLASSTYPE_MARKED4): Likewise.
+ (SET_CLASSTYPE_MARKED5): Likewise.
+ (CLEAR_CLASSTYPE_MARKED5): Likewise.
+ (SET_CLASSTYPE_MARKED6): Likewise.
+ (CLEAR_CLASSTYPE_MARKED6): Likewise.
+ (CLASSTYPE_TAGS): Likewise.
+ (CLASSTYPE_VSIZE): Likewise.
+ (CLASSTYPE_VBASECLASSES): Likewise.
+ (CANONICAL_BINFO): Add parenthesis.
+ (CLASSTYPE_SIZE(NODE): Likewise.
+ (CLASSTYPE_SIZE_UNIT): Likewise.
+ (CLASSTYPE_ALIGN(NODE): Likewise.
+ (CLASSTYPE_USER_ALIGN): Likewise.
+ (TYPE_JAVA_INTERFACE): Likewise.
+ (CLASSTYPE_PURE_VIRTUALS): Likewise.
+ (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Whitespace and wrap.
+ (TYPE_HAS_DEFAULT_CONSTRUCTOR): Likewise.
+ (CLASSTYPE_HAS_MUTABLE): Likewise.
+ (CLASSTYPE_FRIEND_CLASSES): Likewise. Likewise.
+ (CLASSTYPE_DECLARED_CLASS): Whitespace and wrap.
+ (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Likewise.
+ (CLASSTYPE_REF_FIELDS_NEED_INIT): Likewise.
+ (CLASSTYPE_INTERFACE_ONLY): Likewise.
+ (CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (CLASSTYPE_DEBUG_REQUESTED): Whitespace and wrap.
+ (BINFO_UNSHARED_MARKED): Whitespace.
+ (BINFO_MARKED): Whitespace and wrap.
+ (SET_BINFO_MARKED): Likewise.
+ (CLEAR_BINFO_MARKED): Likewise.
+ (BINFO_VTABLE_PATH_MARKED): Likewise.
+ (SET_BINFO_VTABLE_PATH_MARKED): Likewise.
+ (CLEAR_BINFO_VTABLE_PATH_MARKED): Likewise.
+ (BINFO_SUBVTT_INDEX): Remove parenthesis.
+ (BINFO_VPTR_INDEX): Likewise.
+ (BINFO_PRIMARY_BASE_OF): Likewise,
+ (CLASSTYPE_VFIELDS): Whitespace.
+ (VF_DERIVED_VALUE): Wrap long line.
+ (NAMESPACE_LEVEL): Whitespace.
+ (CAN_HAVE_FULL_LANG_DECL_P): Remove parenthesis.
+ (DEFARG_POINTER): Whitespace.
+ (DECL_NEEDED_P): Remove parenthesis.
+ (DECL_LANGUAGE): Whitespace.
+ (SET_DECL_LANGUAGE): Add parenthesis.
+ (DECL_CONSTRUCTOR_P): Whitespace and wrap.
+ (DECL_OVERLOADED_OPERATOR_P): Remove parenthesis.
+ (DECL_IN_AGGR_P): Whitespace.
+ (DECL_FRIEND_P): Likewise.
+ (DECL_BEFRIENDING_CLASSES): Likewise.
+ (DECL_STATIC_FUNCTION_P): Whitespace and wrap.
+ (DECL_NONCONVERTING_P): Whitespace.
+ (DECL_PURE_VIRTUAL_P): Likewise.
+ (DECL_NEEDS_FINAL_OVERRIDER_P): Likewise.
+ (DECL_PENDING_INLINE_INFO): Whitespace.
+ (DECL_SORTED_FIELDS): Likewise.
+ (DECL_DEFERRED_FN): Likewise.
+ (DECL_TEMPLATE_INFO): Likewise.
+ (CLASSTYPE_TEMPLATE_INFO): Whitespace and wrap.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO); Likewise.
+ (SET_TYPE_TEMPLATE_INFO): Add parenthesis.
+ (TMPL_ARGS_LEVEL): Likewise.
+ (SET_TMPL_ARGS_LEVEL): Likewise.
+ (INNERMOST_TEMPLATE_PARMS): Whitespace.
+ (C_TYPEDEF_EXPLICITLY_SIGNED): Uppercase macro parameter.
+ (INTEGRAL_CODE_P(CODE): Add parenthesis.
+ (CP_INTEGRAL_TYPE_P): Remove parenthesis.
+ (TYPE_HAS_CONSTRUCTOR): Whitespace.
+ (TREE_HAS_CONSTRUCTOR): Likewise.
+ (TYPE_HAS_DESTRUCTOR): Likewise.
+ (TYPE_HAS_REAL_ASSIGN_REF): Likewise.
+ (TYPE_HAS_COMPLEX_ASSIGN_REF): Likewise.
+ (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
+ (TYPE_HAS_COMPLEX_INIT_REF): Likewise.
+ (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Likewise.
+ (TYPE_PTRMEMFUNC_P): Likewise.
+ (TYPE_PTRMEMFUNC_FLAG): Likewise.
+ (TYPE_GET_PTRMEMFUNC_TYPE): Likewise.
+ (TYPE_SET_PTRMEMFUNC_TYPE): Likewise.
+ (TYPE_PTRMEM_CLASS_TYPE): Remove parenthesis.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (DECL_ACCESS): Whitespace.
+ (DECL_GLOBAL_CTOR_P): Remove parenthesis.
+ (DECL_GLOBAL_DTOR_P): Likewise.
+ (GLOBAL_INIT_PRIORITY): Likewise.
+ (DECL_TEMPLATE_PARMS): Likewise.
+ (DECL_TEMPLATE_RESULT): Likewise.
+ (DECL_TEMPLATE_INSTANTIATIONS): Likewise.
+ (DECL_TEMPLATE_SPECIALIZATIONS): Likewise.
+ (DECL_IMPLICIT_TYPEDEF_P): Remove parenthesis.
+ (SET_DECL_IMPLICIT_TYPEDEF_P): Likewise.
+ (PRIMARY_TEMPLATE_P): Add parenthesis.
+ (DECL_USE_TEMPLATE): Whitespace.
+ (CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
+ (SET_CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
+ (CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
+ (SET_CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
+ (CALL_DECLARATOR_PARMS): Remove parenthesis.
+ (CALL_DECLARATOR_QUALS): Likewise.
+ (CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
+ (TEMP_NAME_P): Wrap.
+ (VFIELD_NAME_P): Likewise.
+ (B_SET): Uppercase macro parameters and add parenthesis.
+ (B_CLR): Likewise.
+ (B_TST): Likewise.
+ (LOOKUP_NAMESPACES_ONLY): Uppercase macro parameters.
+ (LOOKUP_TYPES_ONLY): Uppercase macro parameters.
+ (LOOKUP_QUALIFIERS_ONLY): Uppercase macro parameters.
+ (same_or_base_type_p): Likewise.
+ (cp_deprecated): Likewise.
+
+2002-01-05 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_body): Revert last change.
+
+2002-01-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/4122
+ * class.c (update_vtable_entry_for_fn): Set delta to zero for a
+ lost primary.
+
+ * class.c (build_vtbl_initializer): Check for a lost primary
+ before calculating the vtable entry to throw away.
+
+2002-01-02 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (expand_body): Call outlining_inline_function when
+ emitting an inline function out of line.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764 reversion
+ * call.c (build_new_op): Revert the instantiations. They are
+ incorrect.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5089
+ * decl2.c (reparse_absdcl_as_casts): Don't warn about casts to void.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3716
+ * pt.c (tsubst_aggr_type): Move pmf handling into tsubst.
+ (tsubst, case POINTER_TYPE): Handle pmfs here.
+ (tsubst, case OFFSET_TYPE): Check it is not an offset to
+ reference. If it is offset to FUNCTION_TYPE, create a METHOD_TYPE.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/35
+ * cp-tree.h (DECL_LANG_FLAG_0): Used for PARM_DECL too.
+ (DECL_TEMPLATE_PARM_P): A PARM_DECL might be one too.
+ * pt.c (process_template_parm): SET_DECL_TEMPLATE_PARM_P on the
+ PARM_DECL.
+ (tsubst_template_parms): Break up loop statements.
+ (tsubst_decl, case PARM_DECL): Copy DECL_TEMPLATE_PARM_P. Template
+ parm PARM_DECLs don't get promoted.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5123
+ * typeck.c (build_component_ref): Cope with a TEMPLATE_ID_EXPR.
+ (build_x_function_call): Cope with a COMPONENT_REF containing a
+ TEMPLATE_ID_EXPR.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5213
+ * pt.c (convert_template_argument): Be more careful determining
+ when RECORD_TYPE templates are or are not templates.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/775
+ * cp-tree.h (handle_class_head): Adjust prototype.
+ * decl2.c (handle_class_head): Add DEFN_P and NEW_TYPE_P
+ parameters. Use for all class heads.
+ * parse.y (named_class_head_sans_basetype, named_class_head,
+ named_complex_class_head_sans_basetype,
+ named_class_head_sans_basetype_defn,
+ unnamed_class_head): Remove.
+ (class_head, class_head_apparent_template): Recognize class heads
+ (class_head_decl, class_head_defn): New reductions. Process class
+ heads.
+ (structsp): Adjust class definition and class declaration
+ reductions.
+ (maybe_base_class_list): Give diagnostic on empty list.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4379
+ * typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
+ single non-static member.
+ (unary_complex_lvalue): If it cannot be a pointer to member, don't
+ make it so. Check it is not pointer to reference.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5132
+ * decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
+ are processing a template decl.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated. Simplify arglist construction.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1): Use my_friendly_assert
+ rather than if ... abort.
+ * cvt.c (convert_to_reference): Likewise.
+ * semantics.c (setup_vtbl_ptr): Likewise.
+ * pt.c (lookup_template_class): Comment typo.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5125
+ * pt.c (push_template_decl_real): Make sure DECL has
+ DECL_LANG_SPECIFIC.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/335
+ * init.c (resolve_offset_ref): Copy cv qualifiers of this pointer
+ for non-reference fields.
+ * typeck.c (require_complete_type): Use resolve_offset_ref).
+
+2001-12-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/196
+ * parse.y (bad_parm): Better diagnostic when given a SCOPE_REF.
+
+2001-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/160
+ * typeck.c (build_modify_expr): Remove old unreachable code & tidy
+ up. Don't stabilize_references when initializing a reference.
+
+2001-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (lang_f_options): Const-ify.
+
+2001-12-20 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * config-lang.in (diff_excludes): Remove.
+
+2001-12-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/90
+ * typeck.c (build_function_call_real): Use original function
+ expression for errors.
+
+2001-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/3242
+ * class.c (add_method): Do compare 'this' quals when trying to match a
+ used function. Don't defer to another used function.
+
+2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_clone): Remove, fold into ...
+ (instantiate_template): ... here. Simplify by removing mutual
+ recursion.
+ * typeck2.c (build_m_component_ref): Don't cv qualify the function
+ pointed to by a pointer to function.
+ * class.c (delete_duplicate_fields_1): Typo.
+
+2001-12-18 Jason Merrill <jason@redhat.com>
+
+ C++ ABI change: destroy value arguments in caller.
+ * semantics.c (genrtl_start_function, genrtl_finish_function): Don't
+ create an extra binding level for the parameters.
+ * decl.c (store_parm_decls): Don't do parameter cleanups.
+
+2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_method_call): Use '%#V'.
+ * error.c (cv_to_string): Use V parameter to determine padding.
+
+2001-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * call.c, decl2.c, init.c: Use "built-in" and "bit-field"
+ spellings in messages.
+
+2001-12-17 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.h: Delete #defines for cp_error, cp_warning,
+ cp_pedwarn, and cp_compiler_error.
+ * call.c, class.c, cp-tree.h, cvt.c, decl.c, decl2.c, error.c,
+ except.c, friend.c, init.c, lex.c, method.c, parse.y, pt.c,
+ rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
+ typeck2.c: Change calls to the above macros to use their
+ language-independent equivalents: error, warning, pedwarn, and
+ internal_error respectively.
+
+2001-12-16 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (finish_file): Remove back_end_hook.
+
+2001-12-16 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * ChangeLog.1, ChangeLog.2, ChangeLog, NEWS, call.c, class.c,
+ cp-tree.h, decl.c, decl2.c, except.c, operators.def, optimize.c,
+ pt.c, rtti.c, semantics.c, typeck.c: Fix spelling errors.
+
+2001-12-15 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lang-options.h: Use American spelling in messages.
+
+2001-12-13 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (parse.h): Separate rule, just depend on parse.c.
+
+ Use cleanups to run base and member destructors.
+ * init.c (push_base_cleanups): New function, split out from...
+ (build_delete): ...here. Lose !TYPE_HAS_DESTRUCTOR code.
+ * decl.c (finish_destructor_body): Move vbase destruction code to
+ push_base_cleanups.
+ (begin_function_body, finish_function_body): New fns.
+ (finish_function): Move [cd]tor handling and call_poplevel to
+ finish_function_body.
+ (pushdecl): Skip the new level.
+ * semantics.c (genrtl_try_block): Don't call end_protect_partials.
+ (setup_vtbl_ptr): Call push_base_cleanups.
+ * method.c (synthesize_method): Call {begin,end}_function_body.
+ * pt.c (tsubst_expr): Handle COMPOUND_STMT_BODY_BLOCK.
+ * cp-tree.h: Declare new fns.
+ * parse.y (function_body, .begin_function_body): New nonterminals.
+ (fndef, pending_inline, function_try_block): Use function_body.
+ (ctor_initializer_opt, function_try_block): No longer has a value.
+ (base_init): Remove .set_base_init token.
+ (.set_base_init, compstmt_or_error): Remove.
+ * Make-lang.in (parse.c): Expect two fewer s/r conflicts.
+
+ * optimize.c (maybe_clone_body): Fix parameter updating.
+
+2001-12-12 Jason Merrill <jason@redhat.com>
+
+ * decl.c (store_parm_decls): Remove parms_have_cleanups cruft.
+ * semantics.c (genrtl_start_function): Don't pass
+ parms_have_cleanups or push an extra binding level.
+ (genrtl_finish_function): Lose cleanup_label cruft.
+
+ * cp-tree.h (struct cp_language_function): Remove x_ctor_label.
+ (ctor_label): Remove.
+ * semantics.c (finish_return_stmt): Lose ctor_label support.
+ * decl.c (finish_constructor_body, mark_lang_function): Likewise.
+ * typeck.c (check_return_expr): Check DECL_DESTRUCTOR_P, not
+ dtor_label.
+
+ * call.c (build_new_method_call): Let resolves_to_fixed_type_p
+ check for [cd]tors.
+ * class.c (fixed_type_or_null, case INDIRECT_REF): Fix.
+
+ * decl.c (finish_function): Check VMS_TARGET, not VMS.
+
+ * decl.c (start_cleanup_fn): Remove redundant pushlevel.
+ (end_cleanup_fn): And poplevel.
+
+ * semantics.c (setup_vtbl_ptr): Always build a CTOR_INITIALIZER
+ if we're in a template.
+
+2001-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P,
+ ANON_PARMNAME_FORMAT, ANON_PARMNAME_P, DESTRUCTOR_NAME_FORMAT,
+ THIS_NAME_P): Delete.
+ * spew.c (read_process_identifier): Remove DESTRUCTOR_NAME_P,
+ THIS_NAME_P and ANON_PARMNAME_P tests from warning about clash
+ with internal naming scheme.
+ * error.c (dump_decl): Remove DESTRUCTOR_NAME_P use.
+
+2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Deprecated implicit typename use.
+
+2001-12-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/51
+ * parse.y (frob_specs): Indicate it is a language linkage which
+ contained the extern.
+ * decl.c (grokdeclarator): Allow extern language linkage with
+ other specifiers.
+
+2001-12-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/72
+ * decl.c (add_binding): Don't reject duplicate typedefs involving
+ template parameters.
+
+2001-12-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y, semantics.c: Similarly.
+
+2001-12-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/87
+ * cp-tree.h (DECL_COPY_CONSTRUCTOR_P): Use copy_fn_p.
+ (copy_args_p): Rename to ...
+ (copy_fn_p): ... here.
+ (grok_special_member_properties): New function.
+ (grok_op_properties): Lose VIRTUALP parameter.
+ (copy_assignment_arg_p): Remove.
+ * call.c (build_over_call): Use copy_fn_p.
+ * decl.c (grokfndecl): Reformat. Adjust call to
+ grok_op_properties.
+ (copy_args_p): Rename to ...
+ (copy_fn_p): ... here. Reject template functions. Check for pass
+ by value.
+ (grok_special_member_properties): Remember special functions.
+ (grok_ctor_properties): Don't remember them here, just check.
+ (grok_op_properties): Likewise.
+ (start_method): Call grok_special_member_properties.
+ * decl2.c (grokfield): Likewise.
+ (copy_assignment_arg_p): Remove.
+ (grok_function_init): Don't remember abstract assignment here.
+ * pt.c (instantiate_class_template): Call
+ grok_special_member_properties.
+ (tsubst_decl): Adjust grok_op_properties call.
+
+2001-12-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * lex.c (rid_to_yy): Add RID_CHOOSE_EXPR and
+ RID_TYPES_COMPATIBLE_P.
+
+2001-12-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Add DIRECT_BIND flag in
+ call to build_aggr_init.
+ * cp-tree.h (DIRECT_BIND): Document new use of DIRECT_BIND.
+
+2001-12-08 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y: Replace uses of the string non-terminal with STRING.
+ Don't perform string concatentaion here.
+ (string): Remove non-terminal.
+ * semantics.c (finish_asm_stmt): Don't concatenate strings here.
+
+2001-12-05 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
+ (LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
+ * tree.c (cp_start_inlining, cp_end_inlining): New fns.
+ * pt.c (push_tinst_level): No longer static.
+ * cp-tree.h: Declare them.
+
+ * init.c (resolve_offset_ref): Don't check access for the base
+ conversion to access a FIELD_DECL.
+
+ * cp-tree.h (TYPE_REFFN_P): New macro.
+ * decl.c (bad_specifiers): Check it, too.
+
+ * rtti.c (create_pseudo_type_info): Set CLASSTYPE_INTERFACE_ONLY
+ on the __*_type_info type if we haven't seen a definition.
+
+2001-12-05 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl.c: Include c-common.h.
+ (shadow_warning): Move to c-common.c.
+
+2001-12-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (duplicate_decls): Don't copy DECL_NO_CHECK_MEMORY_USAGE.
+
+2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (end_template_parm_list): Clear TREE_CHAIN of each parm.
+
+2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/164
+ * init.c (sort_base_init): Allow binfos to be directly specified.
+ * method.c (do_build_copy_constructor): Explicitly convert to the
+ base instance.
+ (do_build_assign_ref): Likewise.
+
+2001-12-03 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * decl.c (xref_basetypes): Don't use C99 construct in tag_code
+ declaration and initialization.
+
+2001-12-03 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * typeck2.c: Remove leading capital from diagnostic messages, as
+ per GNU coding standards.
+
+2001-12-03 Mumit Khan <khan@nanotech.wisc.edu>
+
+ PR c++/3394
+ * decl.c (xref_basetypes): Handle attributes between
+ 'class' and name.
+
+2001-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3381
+ * parse.y (named_complex_class_head_sans_basetype): Add new
+ reduction.
+ * Make-lang.in (parse.c): Adjust expected conflict count.
+
+2001-12-03 Jason Merrill <jason@redhat.com>
+
+ * class.c (finish_vtbls): Fill in BINFO_VPTR_FIELD in the
+ immediate binfos for our virtual bases.
+
+2001-12-02 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_java_interface_fn_ref): Similarly.
+ * except.c (is_admissible_throw_operand): Similarly.
+ * init.c (build_java_class_ref): Similarly.
+ * xref.c (open_xref_file): Similarly.
+
+2001-12-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * class.c (finish_struct): Remove trailing periods from messages.
+ * decl.c (check_tag_decl): Similarly.
+ * lex.c (cxx_set_yydebug): Similarly.
+ * typeck2.c (friendly_abort): Similarly.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3048
+ * cp-tree.h (ovl_member): Remove.
+ * decl2.c (merge_functions): Handle extern "C" functions
+ specially.
+ * tree.c (ovl_member): Remove.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4842
+ * class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
+ FUNCTION_DECL, as input.
+ (mark_overriders): Remove.
+ (warn_hidden): Rework for the new ABI.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3471
+ * call.c (convert_like_real): Do not build additional temporaries
+ for rvalues of class type.
+
+2001-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.
+ (ACCESSIBLY_UNIQUELY_DERIVED_FROM_P): Likewise.
+ (PUBLICLY_UNIQUELY_DERIVED_FROM_P: Likewise.
+ (DERIVED_FROM_P): Likewise.
+ (enum base_access): Renumber, add ba_quiet bit mask.
+ (get_binfo): Remove.
+ (get_base_distance): Remove.
+ (binfo_value): Remove.
+ (ACCESSIBLY_DERIVED_FROM_P): Remove.
+ * call.c (standard_conversion): Use lookup_base.
+ * class.c (strictly_overrides): Likewise.
+ (layout_virtual_bases): Likewise.
+ (warn_about_ambiguous_direct_bases): Likewise.
+ (is_base_of_enclosing_class): Likewise.
+ (add_vcall_offset_vtbl_entries_1): Likewise.
+ * cvt.c (build_up_reference): Adjust comment.
+ * init.c (build_member_call): Reformat.
+ * search.c (get_binfo): Remove.
+ (get_base_distance_recursive): Remove.
+ (get_base_distance): Remove.
+ (lookup_base_r): Tweak.
+ (lookup_base): Add ba_quiet control. Complete the types here.
+ (covariant_return_p): Use lookup_base.
+ * tree.c (binfo_value): Remove.
+ (maybe_dummy_object): Use lookup_base.
+ * typeck.c (build_static_cast): Use lookup_base.
+ (get_delta_difference): Likewise.
+ * typeck2.c (binfo_or_else): Use lookup_base.
+ (build_scoped_ref): Add back error_mark_check.
+ (build_m_component_ref): Use lookup_base.
+
+2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.generated-manpages): New dummy target.
+
+2001-11-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (cp-lang.o): Depends on c-common.h.
+ * cp-lang.c (c-common.h): Include.
+ (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks.
+ * decl.c (cxx_init_decl_processing): Don't set lang_safe_from_p.
+ * expr.c (init_cplus_expand): Don't set lang_expand_constant.
+
+2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (c_language): Move to c-common.c.
+ * lex.c (cxx_post_options, cxx_init_options): Use c-common.c
+ functions.
+ (cxx_init): Update.
+
+2001-11-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (joust): Remove COND_EXPR hack.
+
+2001-11-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * search.c (lookup_base_r): Declare bk in variable declaration
+ space.
+
+2001-11-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3145
+ * class.c (build_vbase_pointer): Remove.
+ (build_vbase_path): Remove.
+ (build_base_path): New function.
+ * cp-tree.h (base_access, base_kind): New enumerations.
+ (build_base_path): Declare.
+ (convert_pointer_to_real): Remove.
+ (convert_pointer_to): Remove.
+ (lookup_base): Declare.
+ (convert_pointer_to_vbase): Remove.
+ * call.c (build_scoped_method_call): Use lookup_base &
+ build_base_path instead of convert_pointer_to_real,
+ get_base_distance & get_binfo.
+ (build_over_call): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_pointer_force): Likewise.
+ (build_up_reference): Likewise.
+ (convert_pointer_to_real): Remove.
+ (convert_pointer_to): Remove.
+ * init.c (dfs_initialize_vtbl_ptrs): Use build_base_path
+ instead of convert_pointer_to_vbase & build_vbase_path.
+ (emit_base_init): Use build_base_path instead of
+ convert_pointer_to_real.
+ (expand_virtual_init): Lose unrequired conversions.
+ (resolve_offset_ref): Use lookup_base and build_base_path
+ instead of convert_pointer_to.
+ * rtti.c (build_dynamic_cast_1): Use lookup_base &
+ build_base_path instead of get_base_distance & build_vbase_path.
+ * search.c (get_vbase_1): Remove.
+ (get_vbase): Remove.
+ (convert_pointer_to_vbase): Remove.
+ (lookup_base_r): New function.
+ (lookup_base): New function.
+ * typeck.c (require_complete_type): Use lookup_base &
+ build_base_path instead of convert_pointer_to.
+ (build_component_ref): Likewise.
+ (build_x_function_call): Likewise.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_component_addr): Likewise.
+ * typeck2.c (build_scoped_ref): Likewise.
+
+2001-11-22 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
+
+ * cp-tree.h (CP_TYPE_QUALS): Removed.
+ * decl.c (cxx_init_decl_processing): Don't set lang_dump_tree.
+ * cp-lang.c: Set LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN and
+ LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN.
+ * dump.c (cp_dump_tree): Use void* dump_info argument to match
+ lang-hooks prototype.
+ * call.c, cp-tree.h, cvt.c, decl.c, init.c, mangle.c, method.c, pt.c,
+ rtti.c, semantics.c, tree.c, typeck.c, typeck2.c: All references to
+ CP_TYPE_QUALS changed to cp_type_quals.
+ * Make-lang.in: References to c-dump.h changed to tree-dump.h.
+ (CXX_C_OBJS): Remove c-dump.o.
+
+2001-11-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3637
+ * pt.c (lookup_template_class): Ensure that all specializations
+ are registered on the list corresponding to the most general
+ template.
+
+2001-11-20 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (non_reference): Add documentation.
+ (convert_class_to_reference): Do not strip reference types
+ from conversion operators.
+ (maybe_handle_ref_bind): Simplify.
+ (compare_ics): Correct handling of references.
+
+2001-11-19 John Wilkinson <johnw@research.att.com>
+
+ * dump.c (dump_op): New function.
+ (cp_dump_tree): Dump CLASSTYPE_TEMPLATE_SPECIALIZATION. Use
+ dump_op. Dump DECL_MUTABLE, access and staticness for VAR_DECLs.
+ DECL_PURE_VIRTUAL_P, DECL_VIRTUAL_P,
+
+2001-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR4629
+ * semantics.c (finish_sizeof): Make sure that expression created
+ while processing a template do not have a type.
+ (finish_alignof): Likewise.
+ * typeck.c (c_sizeof): Likewise.
+ (expr_sizeof): Likewise.
+
+2001-11-18 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lex.c (cxx_finish): Call c_common_finish.
+ (finish_parse): Remove.
+
+2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (create_array_type_for_decl): Check if NAME is NULL_TREE
+ when displaying error message about missing array bounds.
+
+2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * mangle.c (write_expression): Handle CAST_EXPR, STATIC_CAST_EXPR,
+ CONST_CAST_EXPR.
+ * operators.def: Add CAST_EXPR, STATIC_CAST_EXPR, CONST_CAST_EXPR.
+
+2001-11-16 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (print_class_statistics): Restore.
+
+2001-11-15 Jason Merrill <jason@redhat.com>
+
+ * method.c (use_thunk): Don't emit debugging information for thunks.
+
+ * parse.y: Add ... IDENTIFIER SCOPE and ... PTYPENAME SCOPE expansions.
+ * decl.c (make_typename_type): Handle getting a class template.
+ * search.c (lookup_field_r): A class template is good enough for
+ want_type.
+
+ * call.c (convert_like_real): Only use cp_convert for the bad part.
+ (standard_conversion): Also allow bad int->enum.
+ * typeck.c (ptr_reasonably_similar): Also allow functions to
+ interconvert. Pointers to same-size integers are reasonably
+ similar.
+
+ * cvt.c (convert_to_void): If we build a new COND_EXPR, always
+ give it void type.
+
+2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3154
+ * init.c (sort_base_init): Remove unreachable code.
+ (expand_member_init): Adjust comment to reflect reality. Simplify
+ and remove unreachable code.
+
+2001-11-15 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (init_reswords, cxx_init_decl_processing): New.
+ (cxx_init): Update prototype.
+ * decl.c (init_decl_processing): Rename. Move null node init
+ to its creation time.
+ * lex.c (cxx_init_options): Update.
+ (cxx_init): Combine with old init_parse; also call
+ cxx_init_decl_processing.
+
+2001-11-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (check_initializer): Try to complete the type of an
+ array element before checking whether it's complete. Don't
+ complain about arrays with complete element types but an
+ unknown size.
+ (cp_finish_decl): Build the hierarchical constructor before
+ calling maybe_deduce_size_from_array_init.
+
+2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in: Change all uses of $(manext) to $(man1ext).
+
+2001-11-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/4206
+ * parse.y (already_scoped_stmt): Remove.
+ (simple_stmt, WHILE & FOR): Use implicitly_scoped_stmt.
+
+2001-11-12 H.J. Lu <hjl@gnu.org>
+
+ * cvt.c (ocp_convert): Don't warn the address of a weak
+ function is always `true'.
+
+2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_PRINT_DECL, LANG_HOOKS_PRINT_TYPE,
+ LANG_HOOKS_PRINT_STATISTICS, LANG_HOOKS_PRINT_XNODE,
+ LANG_HOOKS_PRINT_IDENTIFIER, LANG_HOOKS_SET_YYDEBUG): Override.
+ * cp-tree.h (print_class_statistics): Remove.
+ (cxx_print_statistics, cxx_print_xnode, cxx_print_decl, cxx_print_type,
+ cxx_print_identifier, cxx_set_yydebug): New.
+ * lex.c (set_yydebug): Rename c_set_yydebug.
+ * ptree.c (print_lang_decl, print_lang_type, print_lang_identifier,
+ lang_print_xnode): Rename.
+ * tree.c (print_lang_statistics): Rename.
+
+2001-11-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (dump_array): Fix format specifier warning.
+
+2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_NAME): Override.
+ (struct lang_hooks): Constify.
+ * lex.c (cxx_init_options): Update.
+ (lang_identify): Remove.
+ * parse.y (language_string): Remove.
+
+2001-11-08 Andreas Franck <afranck@gmx.de>
+
+ * Make-lang.in (CXX_INSTALL_NAME, GXX_CROSS_NAME,
+ DEMANGLER_CROSS_NAME): Handle program_transform_name the way
+ suggested by autoconf.
+ (GXX_TARGET_INSTALL_NAME, CXX_TARGET_INSTALL_NAME): Define.
+ (c++.install-common): Use the transformed target alias names.
+
+2001-11-06 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * Make-lang.in: Update.
+ * cp-lang.c: Include langhooks-def.h.
+
+2001-11-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst_copy): Call tsubst for TYPEOF_EXPR.
+
+2001-11-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (copy_lang_type): Add static prototype.
+
+2001-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (unify): Handle SCOPE_REF.
+
+2001-11-01 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.c (cp_copy_res_decl_for_inlining): Adjust
+ DECL_ABSTRACT_ORIGIN for the return variable.
+
+2001-10-31 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Replace $(INTL_TARGETS) with po-generated.
+
+2001-10-28 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * ChangeLog.1, ChangeLog.2, ChangeLog, class.c, decl2.c, search.c,
+ semantics.c, spew.c: Fix spelling errors.
+
+2001-10-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl2.c (validate_nonmember_using_decl): Handle NAMESPACE_DECL.
+
+2001-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c: Redefine LANG_HOOKS_CLEAR_BINDING_STACK to
+ pop_everything.
+
+2001-10-23 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-lang.c (cxx_get_alias_set): New function.
+ Point LANG_HOOKS_GET_ALIAS_SET to it.
+
+2001-10-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.def (UNBOUND_CLASS_TEMPLATE): New tree node.
+ * cp-tree.h (make_unbound_class_template): Prototype new function.
+ * decl.c (make_unbound_class_template): New function.
+ * decl2.c (arg_assoc_template_arg): Handle UNBOUND_CLASS_TEMPLATE.
+ * error.c (dump_type): Likewise.
+ * mangle.c (write_type): Likewise.
+ * parse.y (template_parm): Likewise.
+ (template_argument): Use make_unbound_class_template.
+ * pt.c (convert_template_argument): Handle UNBOUND_CLASS_TEMPLATE.
+ (tsubst): Likewise.
+ (tsubst_copy): Likewise.
+ (unify): Likewise.
+ * tree.c (walk_tree): Likewise.
+ * typeck.c (comptypes): Likewise.
+
+2001-10-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xref.c (GNU_xref_member): Use safe-ctype macros and/or fold
+ extra calls into fewer ones.
+
+2001-10-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_UNINLINABLE.
+ Warn when merging inline with attribute noinline.
+ (start_decl, start_function): Warn if inline and attribute
+ noinline appear in the same declaration.
+
+2001-10-16 H.J. Lu <hjl@gnu.org>
+
+ * cp-tree.h (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Defined
+ for tree checking disabled.
+
+2001-10-16 Hans-Peter Nilsson <hp@axis.com>
+
+ * cp-tree.h (VFIELD_NAME_FORMAT) [NO_DOLLAR_IN_LABEL &&
+ NO_DOT_IN_LABEL]: Adjust to match VFIELD_NAME.
+
+2001-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * pt.c (UNIFY_ALLOW_MAX_CORRECTION): Define.
+ (unify): Only handle MINUS_EXPR specially if the above flag is set
+ and the subtracted constant is 1. Clear the flag on recursive calls.
+ Set it when unifying the maximum value in an INTEGER_TYPE's range.
+
+2001-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (bad_specifiers): Don't allow exception specifications
+ on any typedefs.
+
+2001-10-14 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c (init_cp_pragma): Similarly.
+
+2001-10-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (lookup_template_class): Build complete template arguments
+ for BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (TYPE_BINFO): Update comment.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info.
+ (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS.
+ (copy_type): Prototype new function.
+ * lex.c (copy_lang_decl): Gather tree node statistics.
+ (copy_lang_type): New function.
+ (copy_type): Likewise.
+ (cp_make_lang_type): Create lang_type for
+ BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE
+ and BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (tsubst): Use copy_type instead of copy_node.
+ * search.c (lookup_field_1): Ignore TYPENAME_TYPE.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (determine_specialization): Ignore functions without
+ DECL_TEMPLATE_INFO.
+
+2001-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/4476
+ * typeck2.c (abstract_virtuals_error): Ignore incomplete classes.
+
+2001-10-11 Jason Merrill <jason_merrill@redhat.com>
+
+ * typeck2.c (store_init_value): Don't re-digest a bracketed
+ initializer.
+
+ * class.c (finish_struct_anon): Use TYPE_ANONYMOUS_P instead of
+ ANON_AGGR_TYPE_P.
+
+2001-10-11 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
+ of an asm statement.
+ (build_vtbl_ref_1): Split out from build_vtbl_ref.
+ (build_vfn_ref): Use it to handle vtable descriptors before
+ calling build_vtable_entry_ref.
+ * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
+
+2001-10-10 Richard Henderson <rth@redhat.com>
+
+ * parse.y (asm_operand): Allow named operands.
+ * semantics.c (finish_asm_stmt): Tweek for changed location
+ of the operand constraint.
+
+2001-10-09 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (standard_conversion): Add bad conversion between
+ integers and pointers.
+ (convert_like_real): Don't use convert_for_initialization for bad
+ conversions; complain here and use cp_convert.
+ (build_over_call): Don't handle bad conversions specially.
+ (perform_implicit_conversion): Allow bad conversions.
+ (can_convert_arg_bad): New fn.
+ * cp-tree.h: Declare it.
+ * typeck.c (convert_for_assignment): Use it.
+ (ptr_reasonably_similar): Any target type is similar to void.
+
+2001-10-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (CXX_OBJS): Added cp-lang.o.
+ (cp/cp-lang.o): New rule.
+ * cp-tree.h: Declare hooks.
+ * tree.c: Make hooks non-static.
+ (init_tree): Don't initialize hooks here.
+ * lex.c: Likewise. Move definition of lang_hooks to...
+ * cp-lang.c: ... new file.
+
+2001-10-08 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct lang_decl_flags): Remove declared_inline.
+ (DECL_DECLARED_INLINE_P): Use the bit in struct c_lang_decl.
+
+2001-10-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (build_vtable_entry_ref): Const-ify.
+ * decl.c (predefined_identifier,
+ initialize_predefined_identifiers): Likewise.
+ * init.c (build_new_1): Likewise.
+ * lex.c (cplus_tree_code_type, cplus_tree_code_length, resword):
+ Likewise.
+
+2001-10-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * optimize.c (struct inline_data): Moved to ../tree-inline.c.
+ (INSNS_PER_STMT): Likewise.
+ (remap_decl, remap_block, copy_scopy_stmt, copy_body_r): Likewise.
+ (copy_body, initialize_inlined_parameters): Likewise.
+ (declare_return_variable, inlinable_function_p): Likewise.
+ (expand_call_inline, expand_calls_inline): Likewise.
+ (optimize_inline_calls, clone_body): Likewise.
+ * tree.c (walk_tree): Moved to ../tree-inline.c.
+ (walk_tree_without_duplicates): Likewise.
+ (copy_tree_r, remap_save_expr): Likewise.
+
+2001-10-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (cp/decl.o, cp/tree.o): Depend on tree-inline.h.
+ (cp/pt.o, cp/semantics.o, cp/optimize.o): Likewise.
+ * cp-tree.h (lang_decl): Moved inlined_fns to tree_decl.
+ (TREE_READONLY_DECL_P, DECL_INLINED_FNS): Moved to ../tree.h.
+ (flag_inline_trees): Moved declaration to ../tree-inline.h.
+ (walk_tree): Moved declaration to ../tree-inline.h.
+ (walk_tree_without_duplicates, copy_tree_r): Likewise.
+ (remap_save_expr): Likewise.
+ * decl.c: Include tree-inline.h.
+ (lang_mark_tree): Don't mark inlined_fns.
+ * decl2.c (flag_inline_trees): Moved defn to ../tree-inline.c.
+ * optimize.c: Include tree-inline.h.
+ (optimize_inline_calls): Move declaration to ../tree.h, as
+ non-static.
+ (remap_decl): Use language-independent constructs and hooks.
+ (remap_block, copy_body_r, declare_return_variable): Likewise.
+ (inlinable_function_p): Likewise. Don't test for
+ DECL_LANG_SPECIFIC before DECL_INLINED_FNS as inlined_fns is
+ no longer language-specific.
+ (optimize_inline_calls): Likewise. Make it non-static. Moved
+ call of dump_function to...
+ (optimize_function): Here...
+ (clone_body): New function, extracted from...
+ (maybe_clone_body): ... here. Build decl_map locally and pass
+ it on to clone_body.
+ * pt.c, semantics.c: Include tree-inline.h.
+ * tree.c: Likewise.
+ (cp_walk_subtrees): New language-specific hook for tree inlining.
+ (cp_cannot_inline_tree_fn, cp_add_pending_fn_decls,
+ cp_is_overload_p, cp_auto_var_in_fn_p,
+ cp_copy_res_decl_for_inlining): Likewise.
+ (walk_tree): Move language-specific constructs into...
+ (cp_walk_subtrees): this new function.
+ (copy_tree_r): Use language-independent constructs and hooks.
+ (init_tree): Initialize tree inlining hooks.
+ (remap_save_expr): Adjust prototype so that the declaration
+ does not require the definition of splay_tree.
+
+2001-10-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * rtti.c (get_tinfo_decl): Call typeinfo_in_lib_p with the type used
+ to build the declaration instead of the declaration itself.
+
+2001-10-02 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl2.c (cxx_decode_option): Add 'else'.
+
+ * spew.c (end_input): No longer static.
+ * cp-tree.h: Declare it.
+ * parse.y (datadef): Add "error END_OF_SAVED_INPUT" expansion.
+
+2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * call.c (build_over_call), typeck.c (build_function_call_real):
+ Pass type attributes to check_function_format rather than name or
+ assembler name. Don't require there to be a name or assembler
+ name to check formats.
+
+2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (init_decl_processing): Don't call
+ init_function_format_info. Initialize lang_attribute_table
+ earlier.
+ (builtin_function): Call decl_attributes.
+ (insert_default_attributes): New.
+
+2001-10-01 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl.c (grokdeclarator): Copy array typedef handling from C
+ frontend.
+
+ * decl.c (grokdeclarator): Copy too-large array handling from C
+ frontend.
+
+2001-09-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * config-lang.in (target_libs): Added target-gperf, so that we
+ don't try to build it if C++ is disabled.
+
+2001-09-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (CXX_OBJS): Take out cp/errfn.o.
+ (cp/errfn.o): Delete rule.
+ (cp/error.o): Depend on flags.h.
+ * errfn.c: Delete file.
+ * cp-tree.h: Declare warn_deprecated. Remove definitions of
+ TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS,
+ and TFF_TEMPLATE_DEFAULT_ARGUMENTS. #define cp_error, cp_warning,
+ cp_pedwarn, and cp_compiler_error to error, warning, pedwarn, and
+ internal_error respectively. Make cp_deprecated into a macro.
+ Don't define cp_printer typedef or declare cp_printers.
+ * error.c: Include flags.h.
+ Delete: struct tree_formatting_info, print_function_argument_list,
+ print_declaration, print_expression, print_function_declaration,
+ print_function_parameter, print_type_id, print_cv_qualifier_seq,
+ print_type_specifier_seq, print_simple_type_specifier,
+ print_elaborated_type_specifier, print_rest_of_abstract_declarator,
+ print_parameter_declaration_clause, print_exception_specification,
+ print_nested_name_specifier, and definition of cp_printers.
+ (locate_error): New function.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Moved here and
+ rewritten in terms of locate_error and diagnostic.c.
+ (cp_tree_printer): Rename cp_printer; wire up to *_to_string
+ instead of deleted print_* routines. Handle %C, %L, %O, %Q also.
+ (init_error): Adjust to match.
+
+2001-09-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (CXX_C_OBJS): Add attribs.o.
+
+2001-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c (set_vindex): Mind TARGET_VTABLE_USES_DESCRIPTORS.
+ (build_vtbl_initializer): Likewise.
+ (build_vfn_ref): New.
+ * cp-tree.h: Declare it.
+ * call.c (build_over_call): Use it.
+ * decl2.c (mark_vtable_entries): Mark FDESC_EXPR.
+ * typeck.c (get_member_function_from_ptrfunc): Mind descriptors.
+
+2001-09-21 J"orn Rennecke <amylaar@redhat.com>
+
+ * decl.c (grokdeclarator): Use C syntax for attr_flags declaration.
+
+2001-09-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ Table-driven attributes.
+ * decl.c: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES.
+ * decl2.c (cplus_decl_attributes): Only take one attributes
+ parameter.
+ * cp-tree.c (cplus_decl_attributes): Update prototype.
+ * class.c (finish_struct), decl.c (start_decl, start_function),
+ decl2.c (grokfield), friend.c (do_friend), parse.y
+ (parse_bitfield): Update calls to cplus_decl_attributes.
+ * decl.c (grokdeclarator): Take a pointer to a single ordinary
+ attribute list.
+ * decl.h (grokdeclarator): Update prototype.
+ * decl2.c (grokfield): Take a single ordinary attribute list.
+ * friend.c (do_friend): Likewise.
+ * decl.c (shadow_tag, groktypename, start_decl,
+ start_handler_parms, grokdeclarator, grokparms, start_function,
+ start_method), decl2.c (grokfield, grokbitfield, grokoptypename),
+ parse.y (parse_field, parse_bitfield, component_decl_1), pt.c
+ (process_template_parm, do_decl_instantiation): Pass single
+ ordinary attribute lists around.
+ * decl.c (grokdeclarator): Correct handling of nested attributes.
+ Revert the patch
+ 1998-10-18 Jason Merrill <jason@yorick.cygnus.com>
+ * decl.c (grokdeclarator): Embedded attrs bind to the right,
+ not the left.
+ .
+ * cp-tree.h (cp_valid_lang_attribute): Remove declaration
+ (cp_attribute_table): Declare.
+ * decl.c (valid_lang_attribute): Don't define.
+ (lang_attribute_table): Define.
+ (init_decl_processing): Initialize lang_attribute_table instead of
+ valid_lang_attribute.
+ * tree.c (cp_valid_lang_attribute): Remove.
+ (handle_java_interface_attribute, handle_com_interface_attribute,
+ handle_init_priority_attribute): New functions.
+ (cp_attribute_table): New array.
+ * decl2.c (import_export_class): Don't use
+ targetm.valid_type_attribute.
+
+2001-09-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * Make-lang.in (cp/error.o): Depend on real.h
+ * error.c: #include "real.h"
+
+2001-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mangle.c (mangle_conv_op_name_for_type): Use concat in lieu of
+ xmalloc/strcpy/strcat.
+
+2001-09-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (warn_extern_redeclared_static, cp_make_fname_decl):
+ Const-ification.
+ * pt.c (tsubst_decl): Likewise.
+
+2001-09-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (lang_f_options): Const-ification.
+ * lex.c (cplus_tree_code_name): Likewise.
+ * spew.c (yyerror): Likewise.
+
+2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3986
+ * class.c (force_canonical_binfo_r): Check & move an indirect
+ primary base first.
+ (force_canonical_binfo): Check that it's not already
+ canonical.
+ (mark_primary_virtual_base): Remove BINFO parameter.
+ (mark_primary_bases): Adjust, set BINFO_LOST_PRIMARY_P here.
+
+2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove TYPE_NONCOPIED_PARTS.
+ * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Map onto
+ CLASSTYPE_PURE_VIRTUALS.
+ (TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
+ * class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
+ (layout_class_type): Don't call fixup_inline_methods here ...
+ (finish_struct_1): ... call it here.
+
+2001-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Remove code deadling with
+ DECL_SAVED_INSNS.
+ * decl2.c (finish_file): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * semantics.c (expand_body): Don't defer local functions if
+ they wouldn't be deferred for some other reason. Don't
+ generate RTL for functions that will not be emitted.
+ (genrtl_start_function): Remove code deadling with
+ DECL_SAVED_INSNS.
+ (genrtl_finish_function): Likewise.
+
+2001-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4203
+ * call.c (build_over_call): Do not optimize any empty base
+ construction.
+
+2001-08-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * error.c (dump_template_decl): Output template parameters
+ together with their specifiers.
+ Output `class' prefix for template template parameter.
+ (dump_decl): Fix formatting.
+
+2001-08-30 Kurt Garloff <garloff@suse.de>
+
+ * optimize.c (inlinable_function_p): Allow only smaller single
+ functions. Halve inline limit after reaching recursive limit.
+
+2001-08-30 Joern Rennecke <amylaar@redhat.com>
+ Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Subtract in char*, not
+ ptrdiff_t.
+
+2001-08-23 Jason Merrill <jason_merrill@redhat.com>
+
+ * tree.c (cp_build_qualified_type_real): Use get_qualified_type.
+ (build_cplus_array_type): Use cp_build_qualified_type, not
+ TYPE_MAIN_VARIANT, to get an unqualified version.
+
+ * decl2.c (grok_alignof): Lose.
+ (build_expr_from_tree): Use expr_sizeof and c_alignof_expr.
+ * typeck.c (c_alignof): Lose.
+ * semantics.c (finish_sizeof, finish_alignof): New.
+ * parse.y: Use them.
+ * cp-tree.h: Declare them.
+
+2001-08-22 Jason Merrill <jason_merrill@redhat.com>
+
+ * pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement.
+ Don't loop in COMPOUND_STMT, FOR_STMT or TRY_BLOCK.
+ * tree.c (cp_statement_code_p): A TAG_DEFN is a statement.
+
+2001-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck2.c (add_exception_specifier): Only require complete type if
+ not in processing template declaration.
+
+2001-08-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c: Cast argument to size_t, not HOST_WIDE_INT, in calls to
+ GNU_xref_start_scope and GNU_xref_end_scope.
+
+ * tree.c (TYPE_HASH): Moved to ../tree.h.
+
+2001-08-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cvt.c (convert_to_void): Preserve TREE_SIDE_EFFECTS
+ on COMPOUND_EXPRs.
+
+2001-08-14 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h (build_vfn_ref): Remove.
+ * call.c, rtti.c: Replace all refernces with build_vtbl_ref.
+
+2001-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Mark COMPOUND_EXPRs generated for
+ empty class assignment as having side-effects to avoid
+ spurious warnings.
+
+2001-08-13 Zack Weinberg <zackw@panix.com>
+
+ * Make-lang.in (cp/except.o): Add libfuncs.h to dependencies.
+ * except.c: Include libfuncs.h.
+
+2001-08-11 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * decl.c (grokdeclarator): Clarify diagnostic message.
+
+2001-08-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl2.c (do_nonmember_using_decl): Replace using directive
+ with using declaration in the error message.
+
+2001-08-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (maybe_fold_nontype_arg): Use TREE_TYPE of ARG as the
+ criterion to avoid rebuilding expression tree instead of
+ processing_template_decl.
+
+2001-08-07 Jason Merrill <jason_merrill@redhat.com>
+
+ Support named return value optimization for inlines, too.
+ * decl.c (finish_function): Nullify returns here.
+ * semantics.c (genrtl_start_function): Not here.
+ (cp_expand_stmt): Don't mess with CLEANUP_STMTs.
+ (nullify_returns_r): No longer static. Just clear RETURN_EXPR.
+ Also nullify the CLEANUP_STMT for the nrv.
+ * cp-tree.h: Declare it.
+ * optimize.c (declare_return_variable): Replace the nrv with the
+ return variable.
+ * typeck.c (check_return_expr): Be more flexible on alignment check.
+ Ignore cv-quals when checking for a matching type.
+
+2001-08-09 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_objects): Use target hooks instead of
+ assemble_constructor and assemble_destructor.
+
+2001-08-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * g++spec.c (lang_specific_driver): Quote argument after `-Xlinker'.
+
+2001-08-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3820
+ Stop using TYPE_NONCOPIED_PARTS.
+ * call.c (build_over_call): Be careful when copy constructing
+ or assigning to an empty class.
+ * class.c (check_bases_and_members): It has a
+ COMPLEX_ASSIGN_REF if it has a vptr.
+ (layout_class_type): Don't add empty class padding to
+ TYPE_NONCOPIED_PARTS.
+ (finish_struct_1): Don't add the VFIELD either.
+ * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): Mention _copy_
+ initialization.
+
+2001-08-07 Jason Merrill <jason_merrill@redhat.com>
+
+ * tree.c (walk_tree): Walk siblings even if !walk_subtrees.
+
+2001-08-06 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_objects): Pass a symbol_ref and priority to
+ assemble_{constructor,destructor}. Remove priority handling.
+
+2001-08-05 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ Don't allow template-id in using-declaration.
+ * decl2.c (validate_nonmember_using_decl): Handle template-ids.
+ (do_class_using_decl): Likewise.
+
+2001-08-04 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * cp/spew.c (read_token): No need to pop buffers.
+
+2001-08-02 Stan Shebs <shebs@apple.com>
+
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY): Remove, no longer used.
+ (fnaddr_from_vtable_entry): Remove decl.
+ * method.c (use_thunk): Update comment.
+
+2001-08-01 Andrew Cagney <ac131313@redhat.com>
+
+ * repo.c (get_base_filename): Change return value to const char
+ pointer.
+
+2001-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill -fhonor-std.
+ * NEWS: Document.
+ * cp-tree.h (flag_honor_std): Remove.
+ (CPTI_FAKE_STD): Remove.
+ (std_node): Remove comment about it being NULL.
+ (fake_std_node): Remove.
+ * decl.c (in_fake_std): Remove.
+ (walk_namespaces_r): Remove fake_std_node check.
+ (push_namespace): Remove in_fake_std code.
+ (pop_namespace): Likewise.
+ (lookup_name_real): Remove fake_std_node check.
+ (init_decl_processing): Always create std_node. Always add
+ std:: things there.
+ (builtin_function): Always put non '_' fns in std.
+ * decl2.c (flag_honor_std): Remove.
+ (lang_f_options): Remove honor-std.
+ (unsupported_options): Add honor-std.
+ (set_decl_namespace): Remove fake_std_node check.
+ (validate_nonmember_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (handle_class_head): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * except.c (init_exception_processing): Adjust.
+ * init.c (build_member_call): Remove fake_std_node check.
+ (build_offset_ref): Likewise.
+ * lang-options.h: Remove -fhonor-std, -fno-honor-std.
+ * rtti.c (init_rtti_processing): Adjust.
+
+2001-07-31 Alexandre Petit-Bianco <apbianco@redhat.com>
+
+ * tree.c (cp_tree_equal): WITH_CLEANUP_EXPR node to use its second
+ operand while calling cp_tree_equal.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ The 3.0 ABI no longer has vbase pointer fields.
+ * cp-tree.h (VBASE_NAME, VBASE_NAME_FORMAT, VBASE_NAME_P,
+ FORMAT_VBASE_NAME): Remove.
+ * method.c (do_build_copy_constructor): Adjust.
+ (do_build_assign_ref): Adjust.
+ * search.c (lookup_field_r): Adjust.
+ * typeck.c (build_component_ref): Adjust.
+
+ The 3.0 ABI always has a vtable pointer at the start of every
+ polymorphic class.
+ * rtti.c (build_headof_sub): Remove.
+ (build_headof): Adjust.
+ (get_tinfo_decl_dynamic): No need to check flag_rtti
+ here. Adjust.
+ (create_real_tinfo_var): Explain why we need a hidden name.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3631
+ * class.c (update_vtable_entry_for_fn): The fixed adjustment
+ of a virtual thunk should be from declaring base.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_ctor_vtable_bases_queue_p): Always walk into
+ the shared virtual base, so preserving inheritance graph order.
+
+2001-07-30 Andreas Jaeger <aj@suse.de>
+
+ * decl2.c: Remove unused var global_temp_name_counter.
+
+2001-07-28 Richard Henderson <rth@redhat.com>
+
+ * method.c (pending_inlines): Remove.
+
+2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (mark_primary_virtual_base): Don't adjust base
+ offsets here.
+ (dfs_unshared_virtual_bases): Adjust them here.
+ (mark_primary_bases): Explain why we adjust at the end.
+
+2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct_1): When copying the primary base's
+ VFIELD, make sure we find it is at offset zero.
+
+2001-07-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst_template_parms): Call maybe_fold_nontype_arg and
+ tsubst_expr for default template arguments.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3621
+ * spew.c (yylex): Only copy the token's lineno, if it is
+ nonzero.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3624
+ * call.c (resolve_args): Simplify, call
+ convert_from_reference.
+ (build_new_op): Resolve and convert from reference ARG1
+ earlier. Adjust ARG2 & ARG3 resolve and conversion.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (last_function_parm_tags): Remove.
+ (current_function_parm_tags): Remove.
+ (init_decl_processing): Adjust.
+ (start_function): Adjust.
+ (store_parm_decls): Adjust.
+
+ PR c++/3152
+ * decl.c (grokdeclarator): Detect when a function typedef is
+ declaring a function, and create last_function_parms correctly.
+
+2001-07-25 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (joust): Only prefer a non-builtin candidate to a builtin
+ one if they have the same signature.
+
+ * cvt.c (build_up_reference): Take DECL parm. Check TREE_STATIC on
+ it rather than toplevel_bindings_p. Give it a mangled name if static.
+ (convert_to_reference): Adjust.
+ * decl2.c (get_temp_name): Lose.
+ * mangle.c (mangle_ref_init_variable): New fn.
+ (mangle_guard_variable): Strip the ref-init header.
+ * cp-tree.h: Adjust.
+ * decl.c (cp_finish_decl): Add the DECL_STMT after processing the
+ initializer.
+ (grok_reference_init): Always use DECL_INITIAL.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3416
+ * call.c (build_conditional_expr): Recheck args after
+ conversions.
+ * cp-tree.h (build_conditional_expr): Move to correct file.
+ * typeck.c (decay_conversion): Diagnose any unknown types
+ reaching here.
+ (build_binary_op): Don't do initial decay or default
+ conversions on overloaded functions.
+ (build_static_cast): Don't do a decay conversion here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3543
+ * typeck.c (condition_conversion): Resolve an OFFSET_REF.
+ * expr.c (cplus_expand_expr): An OFFSET_REF should never get here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vtbl_or_vbase_field): Remove, move into ...
+ (create_vtbl_ptr): ... here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vbase_offset_vbtl_entries): Look for
+ non-primary base of which we are a sub vtable.
+
+2001-07-24 Phil Edwards <pme@sources.redhat.com>
+
+ * semantics.c (finish_this_expr): Remove unused code.
+
+2001-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Simplify rtti, now we've only one ABI.
+ * cp-tree.h (cp_tree_index): Remove CPTI_TINFO_DECL_ID,
+ CPTI_TINFO_VAR_ID.
+ (tinfo_decl_id, tinfo_var_id): Remove.
+ (get_typeid_1): Remove.
+ * rtti.c
+ (init_rtti_processing): Remove tinfo_decl_id & tinfo_var_id.
+ (typeid_ok_p): New function.
+ (build_type_id): Call typeid_ok_p. Don't call tinfo_from_decl.
+ (get_tinfo_decl): Remove old abi documentation.
+ (tinfo_from_decl): Remove.
+ (get_type_id): Call typeid_ok_p. Absorb get_typeid_1.
+ (get_typeid_1): Remove.
+ (get_base_offset): Remove.
+ (synthesize_tinfo_var): Absorb get_base_offset.
+ (create_real_tinfo_var): Don't use tinfo_decl_id.
+
+2001-07-23 Graham Stott <grahams@redhat.com>
+
+ * cp/class.c (type_requires_array_cookie): Fix use of uninitialized
+ variable has_two_argument_delete_p.
+
+2001-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove flag_vtable_thunk. It is always on for the 3.0 ABI.
+ * cp-tree.h (CPTI_DELTA2_IDENTIFIER): Remove.
+ (CPTI_INDEX_IDENTIFIER): Remove.
+ (CPT_PFN_OR_DELTA2_IDENTIFIER): Remove.
+ (delta2_identifier): Remove.
+ (index_identifier): Remove.
+ (pfn_or_delta2_identifier): Remove.
+ (flag_vtable_thunks): Remove.
+ (VTABLE_DELTA2_NAME): Remove.
+ (VTABLE_INDEX_NAME): Remove.
+ (FNADDR_FROM_VTABLE_ENTRY): Adjust.
+ (vfunc_ptr_type_node): Adjust.
+ (VTABLE_NAME_PREFIX): Adjust.
+ (build_vfn_ref): Lose first parameter.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * decl.c (initialize_predefined_identifiers): Remove
+ delta2_identifier, index_identifier, pfn_or_delta2_identifier.
+ (init_decl_processing): Remove no-vtable-thunk code.
+ * decl2.c (flag_vtable_thunks): Remove.
+ (mark_vtable_entries): Remove no-vtable-thunk code.
+ * error.c (dump_decl): Remove no-vtable-thunk code.
+ (dump_expr): Adjust ptr to member function code.
+ * init.c (initialize_vtable_ptrs): Remove no-vtable-thunk
+ code.
+ * rtti.c (build_headof): Remove no-vtable-thunk code.
+ (get_tinfo_decl_dynamic): Adjust build_vfn_ref call.
+ * search.c (get_base_distance): Remove expand_upcast_fixups case.
+ (virtual_context) Remove.
+ (expand_upcast_fixups): Remove.
+ (fixup_virtual_upcast_offsets): Remove.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * typeck.c (get_member_function_from_ptrfunc): Remove
+ no-vtable-thunk code.
+ * call.c (build_over_call): Adjust call to build_vfn_ref.
+ * class.c (build_vfn_ref): Lose first parameter. Remove
+ no-vtable-thunk code.
+ (build_rtti_vtbl_entries): Remove no-vtable-thunk code.
+ (build_vtable_entry): Remove no-vtable-thunk code.
+
+2001-07-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove old-abi remnants. Remove comments about old abi
+ behavior. Remove references to 'new-abi' in comments.
+ * cp-tree.h: Adjust comments.
+ (vbase_offsets_in_vtable_p): Delete.
+ (vcall_offsets_in_vtable_p): Delete.
+ (vptrs_present_everywhere_p): Delete.
+ (all_overridden_vfuns_in_vtables_p): Delete.
+ (merge_primary_and_secondary_vtables_p): Delete.
+ (TYPE_CONTAINS_VPTR_P): Adjust.
+ (VTT_NAME_PREFIX): Remove.
+ (CTOR_VTBL_NAME_PREFIX): Remove.
+ (init_vbase_pointers): Remove.
+ * class.c: Adjust coments.
+ (build_vbase_pointer_fields): Delete.
+ (build_vbase_pointer): Remove old-abi code.
+ (build_secondary_vtable): Likewise.
+ (modify_all_vtables): Likewise.
+ (create_vtable_ptr): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise.
+ (finish_vtbls): Likewise.
+ (dfs_finish_vtbls): Delete.
+ (build_vbase_offset_vtbl_entries): Remove old-abi code.
+ * cvt.c: Adjust comments.
+ * decl.c: Adjust comments.
+ * decl2.c: Adjust comments.
+ * init.c: Adjust comments.
+ (construct_virtual_bases): Remove old-abi code.
+ * lang-specs.h: Remove -fno-new-abi.
+ * mangle.c: Adjust comments.
+ * rtti.c: Adjust comments.
+ (get_base_offset): Remove old-abi-code.
+ * search.c: Adjust comments.
+ (dfs_init_vbase_pointers): Remove.
+ (dfs_vtable_path_unmark): Remove.
+ (init_vbase_pointers): Remove.
+ * semantics.c: Adjust comments.
+ (emit_associated_thunks): Remove old-abi code.
+ * typeck.c: Adjust comments.
+
+2001-07-20 Daniel Berlin <dan@cgsoftware.com>
+
+ * Make-lang.in (cp/optimize.o): Depend on $(PARAMS_H), not
+ params.h.
+
+2001-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_anon): Forbid nested classes.
+
+2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c: Don't include dwarfout.h and dwarf2out.h.
+ * optimize.c: Include debug.h.
+ (maybe_clone_body): Use debug hook.
+ * semantics.c: Include debug.h.
+ (expand_body): Use debug hook.
+
+2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * spew.c (read_token, yyerror): Remove CPP_INT, CPP_FLOAT cases.
+
+2001-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (type_requires_array_cookie): New function.
+ (check_methods): Don't try to figure out whether the type needs a
+ cookie here.
+ (check_bases_and_members): Set TYPE_VEC_NEW_USES_COOKIE here.
+ * cp-tree.h (TYPE_VEC_DELETE_TAKES_SIZE): Remove.
+ (TYPE_VEC_NEW_USES_COOKIE): Reimplement.
+ * pt.c (instantiate_class_template): Don't set
+ TYPE_VEC_DELETE_TAKES_SIZE.
+ * NEWS: Document ABI changes from GCC 3.0.
+
+2001-07-18 Xavier Delacour <xavier@fmaudio.net>,
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * NEWS (Changes in GCC 3.0): Fix typo.
+
+2001-07-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (cplus_decl_attributes): Take a pointer to the node to
+ which attributes are to be attached, and a flags argument. Update
+ call to decl_attributes.
+ (grokfield): Update call to decl_attributes.
+ * class.c (finish_struct): Update call to cplus_decl_attributes.
+ * cp-tree.h (cplus_decl_attributes): Update prototype.
+ * decl.c (start_decl, grokdeclarator, start_function): Update
+ calls to decl_attributes and cplus_decl_attributes.
+ * friend.c (do_friend): Update call to cplus_decl_attributes.
+ * parse.y (parse_bitfield): Update call to cplus_decl_attributes.
+
+2001-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Set DECL_C_HARD_REGISTER
+ for `register' variables with an asm-specification.
+
+2001-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Mark the output operands
+ to an asm addressable, if necessary.
+
+2001-07-11 Ben Elliston <bje@redhat.com>
+
+ * Revert this change -- there is a subtle bug.
+
+ PR c++/80
+ * decl.c (finish_enum): New "attributes" argument; pass it to
+ cplus_decl_attributes. Use a narrower type if the enum is packed.
+ * cp-tree.h (finish_enum): Adjust prototype.
+ * parse.y (enum_head): New non-terminal.
+ (structsp): Use it. Enums now may be preceded or followed by
+ optional attributes -- pass their chained tree to finish_enum().
+ * pt.c (tsubst_enum): Pass NULL_TREE for the new argument.
+
+2001-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope
+ variables.
+
+2001-07-10 Jason Merrill <jason_merrill@redhat.com>
+
+ * semantics.c (cp_expand_stmt): Fix for null
+ current_function_return_value.
+
+2001-07-10 Jan van Male <jan.vanmale@fenk.wau.nl>
+
+ * call.c (build_op_delete_call): Initialize fn.
+ (convert_like_real): Delete conditional.
+ (joust): Initialize *w and *l.
+ * class.c: Add prototype for binfo_ctor_vtable.
+ (get_primary_binfo): Initialize result.
+ * init.c (build_java_class_ref): Initialize name.
+
+2001-07-09 Erik Rozendaal <dlr@acm.org>
+
+ * typeck.c (unary_complex_lvalue): Do not duplicate the
+ argument to modify, pre-, or post-increment when used as an
+ lvalue and when the argument has side-effects.
+
+2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (start_decl): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
+ (start_function): Don't call SET_DEFAULT_DECL_ATTRIBUTES. Call
+ cplus_decl_attributes even if attrs is NULL.
+ * friend.c (do_friend): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
+
+2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (grokdeclarator), decl2.c (cplus_decl_attributes): Update
+ calls to decl_attributes.
+
+2001-07-06 Ira Ruben <ira@apple.com>
+
+ * cp-tree.def (TEMPLATE_DECL): Update comment. DECL_RESULT should
+ be DECL_TEMPLATE_RESULT.
+
+2001-07-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (copy_template_template_parm): Rename to ...
+ (bind_template_template_parm): ... here.
+ * tree.c (copy_template_template_parm): Rename to ...
+ (bind_template_template_parm): ... here. Remove the case when
+ NEWARGS is NULL_TREE.
+ (copy_tree_r): Don't copy TEMPLATE_TEMPLATE_PARM and
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (lookup_template_class): Adjust.
+
+2001-07-05 Jason Merrill <jason_merrill@redhat.com>
+
+ * cvt.c (convert_lvalue): New fn.
+ * cp-tree.h: Declare it.
+ * method.c (do_build_assign_ref): Use it.
+ (do_build_copy_constructor): Convert parm to base types
+ before calling base constructors.
+
+ * typeck.c (check_return_expr): Check DECL_ALIGN instead of
+ DECL_USER_ALIGN. Check flag_elide_constructors instead of
+ optimize.
+ * semantics.c (cp_expand_stmt): Don't destroy the named return value.
+
+2001-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * optimize.c (optimize_inline_calls): New function, broken out
+ of ...
+ (optimize_function): ... here. Call it. Don't inline if it is
+ a thunk.
+ (dump_function): Print name of dump flag causing this dump.
+ * semantics.c (expand_body): Move thunk inline check to
+ optimize_function.
+
+2001-06-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * typeck.c (COMP_TYPE_ATTRIBUTES): Don't define.
+ (comptypes): Use target.comp_type_attributes.
+
+2001-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (flag_dump_class_layout): Remove unneeded declaration.
+
+2001-06-28 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (lang_print_error_function): Add a `diagnostic_context *'
+ parameter. Tweak.
+
+2001-06-27 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * decl2.c (import_export_class): Update.
+
+2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (init_error): Adjust settings.
+
+2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (init_error): Adjust settings.
+
+2001-06-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * except.c (initialize_handler_parm): Expect __cxa_begin_catch to
+ return pointers to data members by reference rather than by value.
+
+2001-06-18 Jason Merrill <jason_merrill@redhat.com>
+
+ Implement the Named Return Value optimization.
+ * cp-tree.h (struct cp_language_function): Add x_return_value.
+ (current_function_return_value): Now a macro.
+ * decl.c: Don't define it.
+ (define_label, finish_case_label): Don't clear it.
+ (init_decl_processing): Don't register it with GC.
+ * semantics.c (genrtl_finish_function): Don't check it for
+ no_return_label. Copy the RTL from the return value to
+ current_function_return_value and walk, calling...
+ (nullify_returns_r): ...this new fn.
+ * typeck.c (check_return_expr): Set current_function_return_value.
+
+2001-06-15 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (dfs_accumulate_vtbl_inits): Just point to the base we're
+ sharing a ctor vtable with. Merge code for cases 1 and 2.
+ (binfo_ctor_vtable): New fn.
+ (build_vtt_inits, dfs_build_secondary_vptr_vtt_inits): Use it.
+
+2001-06-14 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (dfs_find_final_overrider): Fix logic.
+
+ * class.c (update_vtable_entry_for_fn): Uncomment optimization to use
+ virtual thunk instead of non-virtual.
+ (get_matching_virtual): Uncomment.
+
+ * pt.c (unify): Don't recurse between the POINTER_TYPE and the
+ OFFSET_TYPE. If we're adding cv-quals, the extra ones would be on
+ PARM, not ARG.
+
+2001-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
+ we've not emerged from the hierarchy of RTTI_BINFO on reaching
+ a non-virtual base.
+
+2001-06-13 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Update release number.
+
+2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3130, c++/3131, c++/3132
+ * cp-tree.h (BINFO_UNSHARED_MARKED): New #define.
+ * class.c (force_canonical_binfo_r): Move
+ BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move
+ virtual bases unless they're primary and what they're primary
+ too has been moved.
+ (dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope
+ with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and
+ BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most
+ derived binfo.
+ (mark_primary_bases): Use BINFO_UNSHARED_MARKED.
+ (layout_nonempty_base_or_field): Add most derived type
+ parameter. Adjust.
+ (layout_empty_base): Likewise.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (propagate_binfo_offsets): Add most derived type
+ parameter. Skip non canonical virtual bases too.
+ (dfs_set_offset_for_unshared_vbases): Don't skip primary
+ bases. Do skip canonical bases.
+ (layout_virtual_bases): Adjust.
+ (layout_class_type): Adjust.
+ (dfs_get_primary_binfo): Build list of virtual primary base
+ candidates.
+ (get_primary_binfo): Check that the shared virtual primary
+ base candidate was found first.
+ (accumulate_vtbl_inits): Don't do anything for non-vptr
+ containing binfos. For case 1 primary virtual bases, keep
+ checking that we've not emerged from the hierarchy of RTTI_BINFO.
+
+2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3089
+ * class.c (dfs_accumulate_vtbl_inits): Always walk down the
+ hierarchy looking for primary bases for a ctor
+ vtable. Recursively call oneself, if we meet our primary via
+ this route and haven't met it yet via inheritance graph order.
+
+2001-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * lang-options.h: Emit documentation for -fno-honor-std, not
+ -fhonor-std.
+
+2001-06-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc) [vbit_in_delta]:
+ Don't clobber delta.
+ (expand_ptrmemfunc_cst) [ptrmemfunc_vbit_in_delta]: Adjust pfn.
+
+2001-06-10 Mark Mitchell <mark@codesourcery.com>
+ Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Make-lang.in (cp/call.o): Depend on diagnostic.h
+ (cp/typeck.o): Depend on diagnostic.h
+ (cp/typeck2.o): Depend on diagnostic.h
+ (cp/repo.o): Depend on dignostic.h
+ * typeck.c: #include diagnostic.h
+ (convert_for_initialization): Remove extern declaration for
+ warningcount and errorcount.
+
+ * call.c: #include diagnostic.h
+ (convert_like_real): Remove extern declaration for warnincount and
+ errorcount.
+
+ * repo.c: #include diagnostic.h
+ * typeck2.c: #include diagnostic.h
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (duplicate_decls): Fix DECL_TEMPLATE_RESULT thinko
+ in previous change.
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2929
+ * friend.c (do_friend): Use push_decl_namespace for classes at
+ namespace scope.
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+ Jason Merrill <jason_merrill@redhat.com>
+
+ PR c++/3061
+ * class.c (build_secondary_vtable): Use assert, rather than an error
+ message.
+ (dfs_fixup_binfo_vtbls): BINFO_VTABLE might be NULL.
+ (dfs_accumulate_vtbl_inits): A lost primary virtual base may
+ be between ORIG_BINFO and RTTI_BINFO, but neither of them.
+ Don't set BINFO_VTABLE for a primary virtual base.
+
+2001-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Update source position information
+ when a template function is defined.
+
+2001-06-07 Phil Edwards <pme@sources.redhat.com>
+
+ * lang-specs.h: Move -D_GNU_SOURCE to config/linux.h.
+
+2001-06-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2914
+ * decl.c (pushtag): Don't push into a complete type's scope.
+
+2001-06-06 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (THUNK_GENERATE_WITH_VTABLE_P): Lose.
+ (struct lang_decl_flags): Lose generate_with_vtable_p.
+ (BV_GENERATE_THUNK_WITH_VTABLE_P): Lose.
+ * class.c (copy_virtuals): Adjust.
+ * decl2.c (mark_vtable_entries): Adjust.
+ * method.c (make_thunk, build_vtable_entry): Adjust.
+ * class.c (update_vtable_entry_for_fn): Only look as far as the
+ first defining class.
+ (build_vtbl_initializer): Put nothing in the slot for a function only
+ defined in a lost primary virtual base.
+ (add_vcall_offset_vtbl_entries_1): Use the same code for
+ the lost primary case and the normal case.
+ (dfs_unshared_virtual_bases): Don't lose a non-virtual primary base.
+ (get_vfield_offset, get_derived_offset): Lose.
+ (dfs_find_final_overrider): Use look_for_overrides_here.
+ (get_matching_virtual): New fn.
+ * semantics.c (emit_associated_thunks): Check BV_USE_VCALL_INDEX_P,
+ not BV_VCALL_INDEX.
+ * search.c (look_for_overrides_here): Split out from...
+ (look_for_overrides_r): Here.
+
+ * class.c (find_final_overrider): Return error_mark_node on error.
+
+ * decl2.c (key_method): #if 0 accidental change.
+
+2001-06-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * call.c (convert_default_arg): Use INTEGRAL_TYPE_P.
+ (build_over_call): Likewise.
+ * decl.c (grokparms): Likewise.
+ * pt.c (tsubst_decl): Likewise.
+ * typeck.c (convert_arguments): Likewise.
+
+2001-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (begin_class_definition): Robustify.
+
+ * pt.c (instantiate_decl): Tell the repository code about the
+ clones, not the cloned functions.
+ * repo.c (repo_template_used): Explicitly instantiate the cloned
+ function, not the clones.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1): Set ICS_USER_FLAG and
+ ICS_BAD_FLAG on created conversion.
+ (compare_ics): Break out rank.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (xref_tag): Remove extraneous %s on dependent name
+ lookup warning.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (layout_vtable_decl): Fix off by one error on
+ build_index_type.
+ (build_vtt): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (maybe_indent_hierarchy): New function.
+ (dump_class_hierarchy_r): Add flags. Dump extra binfo
+ information, if enabled. Use maybe_indent_hierarchy. Adjust
+ output format.
+ (dump_class_hierarchy): Adjust prototype. Adjust output format.
+ (dump_array, dump_vtable, dump_vtt): New functions.
+ (finish_struct_1): Adjust hierarchy dumping.
+ (initialize_vtable): Call dump_vtable.
+ (build_vtt): Call dump_vtt.
+ (build_ctor_vtbl_group): Call dump_vtable.
+ * decl2.c (flag_dump_class_layout): Remove.
+ (cxx_decode_option): Remove dump translation unit
+ and dump class hierarchy check. Call dump_switch_p.
+ (finish_file): Adjust dumping.
+ (dump.c): Only dump base classes if not TDF_SLIM.
+ Only dump namespace members if not TDF_SLIM.
+ * optimize.c (dump_function): New function.
+ (optimize_function): Call dump_function.
+ * semantics.c (expand_body): Use dump_enabled_p.
+
+2001-06-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2936
+ Part missed from first commit
+ * decl2.c (finish_anon_union): Copy context.
+
+2001-05-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2936
+ * optimize.c (remap_decl): Remap anonymous aggregate members too.
+
+2001-05-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2823
+ * semantics.c (expand_body): Don't optimize thunks.
+
+2001-05-25 Sam TH <sam@uchicago.edu>
+
+ * cp-tree.h lex.h: Fix header include guards.
+
+2001-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Tweak.
+
+2001-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Tidy.
+ (init_decl_processing): Always set flag_no_builtin.
+
+2001-05-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2184
+ * decl2.c (do_local_using_decl): Push the decls, even in a
+ template.
+
+2001-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (initialize_inlined_parameters): Don't set
+ TREE_READONLY for a VAR_DECL taking the place of an inlined
+ PARM_DECL.
+
+2001-05-22 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c, cp-tree.h, rtti.c: Remove com_interface attribute support.
+ * tree.c (cp_valid_lang_attribute): Warn about use of com_interface
+ attribute.
+
+2001-05-22 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * parse.y: Refer to compound literals as such, not as
+ constructor-expressions.
+
+2001-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Ignore exception-specifications
+ when looking for matching delete operators.
+ * init.c (build_new_1): Compute whether or not the allocation
+ function used is a placement allocation function or not, and
+ communicate this information to build_op_delete_call.
+
+2001-05-21 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Lose vtbl parm. Fix for new abi.
+ (build_vtbl_ref): Adjust.
+ (dfs_accumulate_vtbl_inits): Set TREE_CONSTANT on the vtable address.
+ * decl2.c (lang_f_options): Remove huge-objects, vtable-thunks.
+ Re-add vtable-gc.
+ (unsupported_options): Correspondingly.
+
+ * decl2.c (maybe_make_one_only): Check flag_weak, not
+ supports_one_only().
+
+ * cp-tree.def (START_CATCH_STMT): Lose.
+ * dump.c (cp_dump_tree): Don't dump it. Do dump HANDLER_PARMS.
+ * tree.c (cp_statement_code_p): Don't case it.
+ * semantics.c (cp_expand_stmt): Likewise.
+ * cp-tree.h (START_CATCH_TYPE): Lose.
+ (HANDLER_TYPE): New.
+ * except.c (expand_start_catch_block): Don't start any blocks.
+ Return the type.
+ (expand_end_catch_block): Don't end any blocks.
+ * parse.y (handler): Don't pass anything from finish_handler_parms
+ to finish_handler.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_handler): Call note_level_for_catch here.
+ (finish_handler_parms): Don't return anything.
+ (genrtl_catch_block, begin_catch_block): Lose.
+ (genrtl_handler): Call expand_start_catch here.
+
+2001-05-18 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable): Set DECL_ASSEMBLER_NAME for vtables here.
+ (get_vtable_decl, build_vtt): Not here.
+
+2001-05-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2781
+ * optimize.c (update_cloned_parm): Copy addressability and other
+ flags.
+
+2001-05-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (determine_specialization): Ignore artificial functions.
+
+2001-05-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (struct lang_identifier, C_RID_YYCODE): Update.
+ (C_RID_CODE): Remove.
+ * lex.c (cxx_init_options): Call set_identifier_size. Update.
+ (init_parse): Don't do it here.
+
+2001-05-18 Diego Novillo <dnovillo@redhat.com>
+
+ * decl2.c (finish_objects): Use the original SYMBOL_REF from the
+ function declaration to avoid stripping the symbol's attributes.
+
+2001-05-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (pushdecl): Adjust error string.
+ (xref_tag): Adjust friend class injection warning. Remove the
+ inherited name from the class shadowed scope.
+
+2001-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * except.c (cp_protect_cleanup_actions): New function.
+ (init_exception_processing): Don't set protect_cleanup_actions
+ here. Do set lang_protect_cleanup_actions.
+
+2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (read_token): Call yyerror on all unexpected tokens.
+
+2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (member_init_ok_or_else): Take a tree rather than
+ string for name.
+ (expand_member_init): Adjust.
+
+2001-05-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * decl.c (duplicate_decls): Suppress warning about duplicate
+ decls if the first decl is a friend.
+
+2001-05-12 Zack Weinberg <zackw@stanford.edu>
+
+ * except.c (choose_personality_routine): Export. Add
+ explanatory comment. Take an enum languages, not a boolean.
+ (initialize_handler_parm): Adjust to match.
+ * cp-tree.h: Prototype choose_personality_routine.
+ * lex.c (handle_pragma_java_exceptions): New function.
+ (init_cp_pragma): Register #pragma GCC java_exceptions.
+
+2001-05-12 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * method.c (build_mangled_C99_name): Remove unused prototype.
+
+2001-05-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.
+ * typeck.c (get_member_function_from_ptrfunc,
+ build_ptrmemfunc, expand_ptrmemfunc_cst): Take
+ TARGET_PTRMEMFUNC_VBIT_LOCATION into account.
+
+ Reverted Geoff Keating's 2001-05-03's patch.
+
+2001-05-11 Ira Ruben <ira@apple.com>
+
+ * cp/cp-tree.h (C_EXP_ORIGINAL_CODE): Delete; declared in c-common.h.
+
+2001-05-11 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (finish_label_expr, lookup_label): Delete.
+ * parse.y: Update for '&&'; don't issue warning here.
+ * semantics.c (finish_label_expr): Delete.
+
+2001-05-07 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.h (splay_tree_max): New function.
+ (splay_tree_min): Likewise.
+
+2001-05-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * cp-tree.h (enum cp_tree_index): Add CPTI_PFN_VFLAG_IDENTIFIER.
+ (pfn_vflag_identifier): Define.
+ Update comment about layout of pointer functions.
+ (build_ptrmemfunc1): Update prototype.
+ (expand_ptrmemfunc_cst): Update prototype.
+ * decl.c (initialize_predefined_identifiers): Initialize
+ pfn_vflag_identifier.
+ (build_ptrmemfunc_type): When FUNCTION_BOUNDARY < 16, add
+ an extra field to the type.
+ * expr.c (cplus_expand_constant): Pass 'flag' between
+ expand_ptrmemfunc_cst and build_ptrmemfunc1.
+ * typeck.c (get_member_function_from_ptrfunc): When
+ FUNCTION_BOUNDARY < 16, look at additional field to determine
+ if a pointer-to-member is a real pointer or a vtable offset.
+ (build_ptrmemfunc1): Add new parameter to contain extra field.
+ (build_ptrmemfunc): Pass the extra field around.
+ (expand_ptrmemfunc_cst): Add new parameter to return extra field.
+ (pfn_from_ptrmemfunc): Ignore the extra field.
+
+2001-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (flag_inline_trees): Update documentation.
+ * decl.c (init_decl_processing): Adjust handling of
+ flag_inline_functions and flag_inline_trees to support -O3.
+ (grokfndecl): Set DECL_INLINE on all functions if that's what
+ the user requested.
+ (save_function_data): Clear DECL_INLINE in
+ current_function_cannot_inline is non-NULL.
+ * decl2.c (flag_inline_trees): Update documentation.
+
+2001-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dump.c (cp_dump_tree, USING_STMT case): New case.
+ * tree.c (cp_statement_code_p): Add USING_STMT.
+ * decl2.c (do_using_directive): Add the using directive statement.
+
+ * tree.c (walk_tree): Reformat an if block.
+
+2001-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (compute_array_index_type): Don't try to do anything with
+ the indices when processing a template.
+
+2001-05-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: NULL_PTR -> NULL.
+ * class.c: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2001-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_using_directive): Revert previous patch.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (USING_STMT): New statement node.
+ * cp-tree.h (USING_STMT_NAMESPACE): New macro.
+ * decl2.c (do_using_directive): Add USING_STMT to statement
+ tree. Don't emit errors when processing template decl.
+ * pt.c (tsubst_expr, USING_STMT case): New case.
+ * semantics.c (cp_expand_stmt, USING_STMT case): New case.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_op): Convert args from reference here.
+ (build_conditional_expr): Don't convert here.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (last_token_id): New static variable.
+ (read_token): Set it here.
+ (yyerror): Use it here.
+
+2001-04-30 Richard Henderson <rth@redhat.com>
+
+ * cvt.c: Downcase C_PROMOTING_INTEGER_TYPE_P invocations.
+ * decl.c: Likewise.
+
+2001-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * gxxint.texi: Remove.
+ * Make-lang.in: Remove all traces of gxxint.texi.
+
+2001-04-30 Mark P Mitchell <mark@codesourcery.com>
+
+ * decl2.c (start_static_initialization_or_destruction): Correct
+ logic to handle the -fno-use-cxa-atexit case.
+
+2001-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (update_cloned_parm): New function.
+ (maybe_clone_body): Use it. Update the `this' parameter too.
+
+2001-04-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (unsupported_options): Add new-abi.
+ * lang-options.h: Remove no longer supported options.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (can_convert_eh): Don't check template parms,
+ typename types etc.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy parameter names and locations.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (adjust_clone_args): Prototype new function.
+ * class.c (adjust_clone_args): New function.
+ * decl.c (start_function): Call it for in charge ctors.
+
+2001-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Make sure that thunks really are emitted
+ when requested.
+
+2001-04-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * mangle.c (write_chars): New macro.
+ (hwint_to_ascii): New function
+ (write_number): Use it.
+ (write_integer_cst): Deal with really big numbers.
+
+2001-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy TREE_PUBLIC before emitting
+ the clone.
+
+2001-04-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Set context of namespace scope
+ TYPE_DECLS.
+
+2001-04-24 Zack Weinberg <zackw@stanford.edu>
+
+ * cp/optimize.c: Include hashtab.h.
+ (struct inline_data): Add tree_pruner.
+ (expand_call_inline, expand_calls_inline): Use it when calling
+ walk_tree.
+ (optimize_function): Initialize and free tree_pruner.
+
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Lazy __FUNCTION__ generation.
+ * cp-tree.def (FUNCTION_NAME): Remove.
+ * cp-tree.h (function_name_declared_p): Remove.
+ (cp_fname_init): Prototype.
+ * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
+ don't call declare_function_name. Call start_fname_decls.
+ (cp_make_fname_decl): Adjust parameters. Generate the name. Don't
+ clobber the line number.
+ (cp_fname_init): New function.
+ (start_function): Call start_fname_decls.
+ (finish_function): Call finish_fname_decls.
+ * lex.c (reswords): Add slots for __FUNCTION__ et al.
+ (rid_to_yy): Add mappings for __FUNCTION__ et al.
+ * optimize.c (maybe_clone_body): Remove function_name_declared_p.
+ * parse.y (VAR_FUNC_NAME): New token.
+ (primary): Add VAR_FUNC_NAME.
+ * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
+ generation.
+ (tsubst, FUNCTION_NAME case): Remove.
+ (tsubst_copy, FUNCTION_NAME case): Remove.
+ (tsubst_expr, DECL_STMT case): Be careful with a
+ DECL_PRETTY_FUNCTION_P.
+ (instantiate_decl): Remove function_name_declared_p.
+ * semantics.c (begin_compound_statement): Don't call
+ declare_function_name here.
+ (setup_vtbl_ptr). Don't save & restore function_name_declared_p.
+ (finish_translation_unit): Call finish_fname_decls.
+ (expand_body): Remove function_name_declared_p.
+ * typeck2.c (digest_init): Allow any ERROR_MARK.
+
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_decl): Use VOID_TYPE_P.
+ * semantics.c: Fix some typos.
+
+2001-04-23 Phil Edwards <pme@sources.redhat.com>
+
+ * cp/decl2.c (flag_honor_std): Always initialize to 1.
+
+2001-04-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xref.c (GNU_xref_file): Use concat in lieu of xmalloc/sprintf.
+
+2001-04-23 Jason Merrill <jason_merrill@redhat.com>
+
+ * except.c (build_throw): Wrap the initialization of the exception
+ object in a MUST_NOT_THROW_EXPR.
+ (do_free_exception): #if 0.
+
+2001-04-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_enum): Change prototype.
+ * decl.c (finish_enum): Reorganize.
+ * parse.y (structsp): Adjust calls to finish_enum.
+
+2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (cp_tree_equal): Adjust final switch formatting. Add
+ 't' case.
+
+2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_unshared_virtual_bases): Add ATTRIBUTE_UNUSED.
+ (layout_empty_base): Return at end flag.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (layout_virtual_bases): Don't add 1 to eoc value.
+ (end_of_class): Use full size for empty bases.
+ (layout_class_type): Clear CLASSNEARLY_EMPTY_P if we appended
+ empty bases. Don't add 1 to eoc value. Only add trailing padding
+ if we're an empty class with no empty bases.
+ (dump_class_hierarchy): Dump size and alignment.
+
+2001-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * call.c (maybe_handle_ref_bind): Copy ICS_USER_FLAG and
+ ICS_BAD_FLAG.
+
+2001-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * search.c (lookup_field_r): If looking for type and non-TYPE_DECL
+ is found, look first if name does not match the structure name.
+
+2001-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is
+ set.
+ (SET_DECL_LANGUAGE): New macro.
+ * decl.c (duplicate_decls): Use SET_DECL_LANGUAGE.
+ (pushdecl): Likewise.
+ (build_library_fn_1): Likewise.
+ (build_cp_library_fn): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Mark `extern "C"' variables as having C linkage.
+ * decl2.c (grokclassfn): Use SET_DECL_LANGUAGE.
+ * lex.c (retrofit_lang_decl): Likewise.
+ * mangle.c (mangle_decl_string): Don't mangle the names of
+ variables declared with C language linkage.
+ * semantics.c (finish_member_declaration): Use SET_DECL_LANGUAGE.
+
+2001-04-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Don't restore
+ flag_access_control from uninitialized storage.
+
+2001-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_PTRMEM_CLASS_TYPE): Improve documentation.
+ * mangle.c (write_pointer_to_member_type): Fix mangling of
+ pointers to cv-qualified member function types.
+
+ * init.c (build_delete): Create a SAVE_EXPR for the address if
+ we're going to use it more than once.
+
+2001-04-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DELTA2_FROM_PTRMEMFUNC): Remove.
+ (expand_ptremfunc_cst): Change prototype.
+ (delta2_from_ptrmemfunc): Remove.
+ * expr.c (cplus_expand_constant): Adjust call to
+ expand_ptrmemfunc_cst.
+ * typeck.c (build_ptrmemfunc1): Simplify.
+ (build_ptrmemfunc): Make sure that casting a PTRMEM_CST still
+ results in a constant.
+ (expand_ptrmemfunc_cst): Remove idx and delta2 parameters.
+ (delta2_from_ptrmemfunc): Remove.
+ (pfn_from_ptrmemfunc): Adjust call to expand_ptrmemfunc_cst.
+
+2001-04-12 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (decl_namespace_list): New macro.
+ (struct saved_scope): Add decl_ns_list.
+ * decl.c (mark_saved_scope): Mark it.
+ * decl2.c: Lose static decl_namespace_list.
+ (init_decl2): Don't save it.
+
+2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (warn_return_type, yylex): Delete redundant
+ declarations.
+
+ * decl.c (current_class_depth, global_namespace): Likewise.
+
+ * decl2.c (current_class_depth, flag_gnu_xref): Likewise
+
+ * repo.c (flag_use_repository): Likewise.
+
+2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (pedantic, convert, global_bindings_p, insert_block,
+ set_block, pushdecl, getdecls, gettags, init_decl_processing,
+ maybe_build_cleanup, copy_lang_decl, prep_stmt, lvalue_p,
+ lvalue_or_else, print_lang_statistics, comp_target_types,
+ unsigned_type, signed_type, signed_or_unsigned_type,
+ build_function_call, mark_addressable, incomplete_type_error):
+ Delete redundant declarations.
+
+2001-04-11 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
+ (TYPE_ANONYMOUS_P): New macro.
+ (TAGGED_TYPE_P): New macro.
+ * decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P.
+ (grokfndecl, grokvardecl, grokdeclarator): Likewise.
+ * tree.c (no_linkage_helper): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * pt.c (convert_template_argument): Likewise.
+ * lex.c (check_for_missing_semicolon): Likewise.
+
+2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_unshared_virtual_bases): New function.
+ (mark_primary_bases): Call it.
+ (check_bases): Ignore virtual bases when determining
+ nearly-emptiness.
+
+2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (make_thunk): Clear DECL_CLONED_FUNCTION.
+
+2001-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy DECL_NUM_STMTS from the
+ cloned function to the clone.
+
+2001-04-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp/semantics.o): Depend on $(EXPR_H).
+
+ * semantics.c: Include expr.h.
+
+2001-04-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (implicitly_declare_fn): Commonize code for copy ctor
+ and assignment op. Set TREE_USED for parameter.
+
+2001-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (find_final_overrider_data): Add `candidates'.
+ (dfs_find_final_overrider): Don't issue error messages
+ prematurely.
+ (find_final_overrider): Issue error messages here.
+ (build_base_field): Don't warn about amgibuous direct bases here.
+ (warn_about_ambiguous_direct_bases): New function.
+ (layout_class_type): Use it.
+
+2001-04-10 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (build_array_ref): Push the array reference inside
+ COMPOUND_EXPR and COND_EXPR.
+
+2001-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_THIS_INLINE): Rename to DECL_DECLARED_INLINE_P.
+ * decl.c (duplicate_decls): Adjust accordingly.
+ (maybe_commonize_var): Likewise.
+ (grokfndecl): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ * decl2.c (key_method): Likewise.
+ (import_export_decl): Likewise.
+ * method.c (implicitly_declare_fn): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+
+2001-04-05 Benjamin Kosnik <bkoz@redhat.com>
+
+ * lang-specs.h: Add __DEPRECATED.
+
+2001-04-05 J"orn Rennecke <amylaar@redhat.com>
+
+ * search.c (get_dynamic_cast_base_type): When building a new
+ constant, set its type to ssizetype.
+
+2001-04-04 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (expand_call_inline): Only add newly inlined statements
+ into inlined_stmts.
+
+2001-04-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (OPERATOR_ASSIGN_FORMAT): Remove.
+ (OPERATOR_FORMAT): Likewise.
+ (OPERATOR_TYPENAME_FORMAT): Likewise.
+ * operators.def: Remove old name-mangling information.
+ * decl.c (grok_op_properties): Adjust accordingly.
+ * lex.c (init_operators): Likewise.
+ * rtti.c (get_tinfo_decl): Issue error messages about types that
+ have variable size.
+
+2001-04-03 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (import_export_decl): Don't call import_export_class
+ when processing an inline member function.
+ * semantics.c (expand_body): Call import_export_decl before
+ emitting inline functions.
+
+2001-03-28 Richard Henderson <rth@redhat.com>
+
+ IA-64 ABI Exception Handling:
+ * cp-tree.def (EH_SPEC_BLOCK): New.
+ (MUST_NOT_THROW_EXPR): New.
+ * cp-tree.h: Update changed function declarations.
+ (CPTI_PUSH_EXCEPTION_IDENTIFIER): Remove.
+ (CPTI_CALL_UNEXPECTED): New.
+ (struct cp_language_function): Rename x_eh_spec_try_block
+ to x_eh_spec_block.
+ (EH_SPEC_STMTS, EH_SPEC_RAISES): New.
+ * decl.c (current_binding_level): If no current function
+ bindings, revert to scope_chain.
+ (initialize_predefined_identifiers): Remove __cp_push_exception.
+ (store_parm_decls): Use begin_eh_spec_block.
+ (finish_function): Use finish_eh_spec_block.
+ (mark_lang_function): Update for name changes.
+ * decl2.c (finish_file): No mark_all_runtime_matches.
+ * dump.c (cp_dump_tree): Handle new tree codes.
+ * error.c (dump_expr) [BIND_EXPR]: Fix typo.
+ * except.c (catch_language_init, catch_language): Remove.
+ (init_exception_processing): Don't set language code.
+ Initialize call_unexpected_node, protect_cleanup_actions,
+ eh_personality_libfunc, lang_eh_runtime_type.
+ (call_eh_info, push_eh_info, get_eh_info, get_eh_value): Remove.
+ (get_eh_type, get_eh_caught, get_eh_handlers): Remove.
+ (prepare_eh_type): Split out type canonicalizations ...
+ (build_eh_type_type): ... from here.
+ (build_eh_type_type_ref): Remove.
+ (mark_all_runtime_matches): Remove.
+ (build_exc_ptr): New.
+ (do_begin_catch, do_end_catch): New.
+ (do_pop_exception): Remove.
+ (build_terminate_handler): Remove.
+ (choose_personality_routine): Split out language choice from ...
+ (initialize_handler_parm): ... here.
+ Use MUST_NOT_THROW_EXPR.
+ (expand_start_catch_block): Use do_begin_catch. Simplify Java
+ exception object handling.
+ (expand_start_eh_spec, expand_end_eh_spec): Remove.
+ (expand_exception_blocks, alloc_eh_object): Remove.
+ (begin_eh_spec_block, finish_eh_spec_block): New.
+ (do_allocate_exception, do_free_exception): New.
+ (expand_throw): Merge into ...
+ (build_throw): ... here. Update for abi.
+ * expr.c (cplus_expand_expr): No expand_internal_throw.
+ Handle MUST_NOT_THROW_EXPR.
+ * pt.c (tsubst_expr): Handle EH_SPEC_BLOCK.
+ * semantics.c (*) Update for except.h name changes.
+ (genrtl_try_block): No protect_with_terminate.
+ (genrtl_eh_spec_block): New.
+ (genrtl_handler): Don't emit the goto here.
+ (cp_expand_stmt): Handle EH_SPEC_BLOCK.
+ (genrtl_finish_function): Don't expand_exception_blocks.
+ * tree.c (cp_statement_code_p): Handle EH_SPEC_BLOCK.
+
+2001-03-28 Richard Henderson <rth@redhat.com>
+
+ * decl.c (struct named_label_list): Rename eh_region to
+ in_try_scope, add in_catch_scope.
+ (struct binding_level): Rename eh_region to is_try_scope,
+ add is_catch_scope.
+ (note_level_for_try): Rename from note_level_for_eh.
+ (note_level_for_catch): New.
+ (poplevel): Copy both is_try_scope and is_catch_scope to
+ the named_label_list struct.
+ (check_previous_goto_1): Don't check for catch block via
+ DECL_ARTIFICIAL; use in_try_scope instead.
+ (check_goto): Likewise.
+ * cp-tree.h (note_level_for_try, note_level_for_catch): Declare.
+ * except.c (expand_start_catch_block): Call note_level_for_catch.
+ * semantics.c (begin_compound_stmt): Update for note_level_for_try.
+
+2001-03-27 Richard Henderson <rth@redhat.com>
+
+ * except.c: Use USING_SJLJ_EXCEPTIONS instead of
+ exceptions_via_longjmp.
+
+2001-03-27 Phil Edwards <pme@sources.redhat.com>
+
+ * pt.c (check_default_tmpl_args): Make error messages clearer.
+
+2001-03-26 Phil Edwards <pme@sources.redhat.com>
+
+ * error.c: Also undefine 'A' macro used for cp_printers definition.
+
+2001-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Depend on $(SYSTEM_H), not system.h.
+
+2001-03-26 Mike Yang <yang@research.att.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dump_access): New function.
+ (cp_dump_tree): Use it. Dump basetype information for class
+ types.
+
+2001-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (optimize.o): Depend on params.h.
+ (duplicate_decls): Copy DECL_NUM_STMTS, not DECL_FRAME_SIZE.
+ (init_decl_processing): Set flag_no_inline when doing
+ inlining-on-trees.
+ * optimize.c: Include params.h.
+ (struct inline_data): Improve documentation of FNS. Add
+ FIRST_INLINED_FN, INLINED_STMTS, and CLONING_P.
+ (INSNS_PER_STMT): New macro.
+ (remap_block): Use CLONING_P.
+ (inlinable_function_p): Don't inline big functions.
+ (expand_call_inline): Keep track of how much inlining we've done.
+ (optimize_function): Set FIRST_INLINED_FN.
+ (maybe_clone_body): Set CLONING_P.
+ * semantics.c (simplify_aggr_init_exprs_r): Fix typing problems in
+ tree nodes.
+ (genrtl_finish_function): Clear DECL_DEFER_OUTPUT before calling
+ rest_of_compilation. Clear DECL_RTL for local variables
+ afterwards.
+ (clear_decl_rtl): New function.
+
+2001-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement DR 209
+ * cp-tree.h (skip_type_access_control,
+ reset_type_access_control): Prototype.
+ * decl.c (grokdeclarator): Access of friends is not checked.
+ * parse.y (component_decl_list): Reset type access control.
+ * semantics.c (decl_type_access_control): Clear
+ current_type_lookups.
+ (save_type_access_control): Don't save if not deferring.
+ (skip_type_access_control, reset_type_access_control): New
+ functions.
+ (begin_class_definition): Do type access control for basetypes.
+ Start deferred access control.
+ (finish_class_definition): Resume immediate access control if
+ this is a local class.
+
+2001-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (add_method): Use memcpy/memmove, not bcopy.
+
+ * decl.c (duplicate_decls): Likewise.
+
+2001-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (write_discriminator): Use `_0' for discriminator 1,
+ not `_'.
+
+2001-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (local_names): Define.
+ (push_local_name): New.
+ (grok_reference_init): Return init if initializing static reference
+ variable with non-constant instead of emitting it.
+ Move expand_static_init call to cp_finish_decl.
+ (layout_var_decl): Call push_local_name.
+ (maybe_commonize_var): Allow inlining functions even if they have
+ static local variables, use comdat_linkage for them if flag_weak.
+ (check_initializer): Call obscure_complex_init if
+ grok_reference_init returned nonzero.
+ (save_function_data): Clear x_local_names.
+ (pop_cp_function_context): Free x_local_names.
+ (mark_inlined_fns): Remove.
+ (mark_lang_function): Mark x_local_names.
+ (lang_mark_tree): Don't mark DECL_ACCESS for DECL_DISCRIMINATOR_P.
+ Mark inlined_fns as tree, remove call to mark_inlined_fns.
+ * class.c (alter_access): Ensure DECL_ACCESS is never set if
+ DECL_DISCRIMINATOR_P.
+ * cp-tree.h (cp_language_function): Add x_local_names.
+ (lang_decl_flags): Add discriminator into u2.
+ (lang_decl_inlined_fns): Remove.
+ (lang_decl): inlined_fns is now a TREE_VEC.
+ (DECL_DISCRIMINATOR_P, DECL_DISCRIMINATOR): Define.
+ * optimize.c (inlinable_function_p): DECL_INLINED_FNS is now a
+ TREE_VEC, not a custom structure.
+ (optimize_function): Likewise.
+ * mangle.c (discriminator_for_local_entity): Discriminate among
+ VAR_DECL local entities.
+ * search.c (dfs_access_in_type): If DECL_DISCRIMINATOR_P, DECL_ACCESS
+ is not valid.
+
+2001-03-22 Bryce McKinlay <bryce@albatross.co.nz>
+
+ Add support for Java interface method calls.
+ * cp-tree.h (struct lang_type): Add java_interface flag.
+ (TYPE_JAVA_INTERFACE): New macro.
+ * tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
+ by setting TYPE_JAVA_INTERFACE.
+ * call.c (java_iface_lookup_fn): New static.
+ (build_over_call): If calling a method declared in a
+ TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
+ expression which resolves the function address.
+ (build_java_interface_fn_ref): New function.
+
+2001-03-22 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (cp/except.o): Don't depend on insn-flags.h.
+ * except.c: Don't include it.
+
+2001-03-22 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ based on an idea from Joe Buck <jbuck@synopsys.com>
+
+ * parse.y (bad_decl, template_arg_list_ignore, arg_list_ignore):
+ New nonterminals.
+ (data_def, component_decl): Add reductions to bad_decl.
+
+2001-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (do_build_assign_ref): Don't use build_modify_expr for
+ anonymous aggregates, since they don't have assignment operator
+ method.
+ * decl.c (fixup_anonymous_aggr): Disallow ctors, dtors and copy
+ assignment operators for anonymous structure fields.
+
+2001-03-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (instantiate_decl): Abort if we see a member constant
+ instantiation that doesn't already have its initializer.
+ Downgrade explicit instantiation without definition to pedwarn.
+
+ * cp-tree.h (DECL_TINFO_FN_P, SET_DECL_TINFO_FN_P): Remove.
+ * class.c (build_vtable_entry): Don't check DECL_TINFO_FN_P.
+ (import_export_decl): Check tinfo_decl_p, not DECL_TINFO_FN_P.
+
+ * cp-tree.h (CLASSTYPE_VTABLE_NEEDS_WRITING): Remove.
+ (pending_vtables): Remove.
+ * decl2.c (pending_vtables): Remove.
+ (import_export_vtable): Use CLASSTYPE_INTERFACE_ONLY, not
+ CLASSTYPE_VTABLE_NEEDS_WRITING.
+ (import_export_class): Likewise.
+ (init_decl2): Don't mark pending_vtables.
+ * lex.c (handle_pragma_vtable): Just sorry.
+ * pt.c (instantiate_class_template): Don't mess with
+ CLASSTYPE_VTABLE_NEEDS_WRITING.
+ (mark_class_instantiated): Likewise.
+ * ptree.c (print_lang_type): Don't print it.
+ * semantics.c (begin_class_definition): Don't set it.
+
+ * pt.c (template_tail): Replace with last_pending_template.
+ (maybe_templates, maybe_template_tail): Remove.
+ (add_pending_template): Adjust.
+ (instantiate_pending_templates): Adjust.
+
+ * cp-tree.h (struct saved_scope): Remove lang_stack field.
+ (current_lang_stack): Remove.
+ * decl.c (maybe_push_to_top_level): Don't initialize it.
+ (duplicate_decls): Use current_lang_depth.
+ (xref_basetypes): Likewise.
+ * class.c (current_lang_depth): New fn.
+ (push_lang_context): Use more varray functionality.
+ (pop_lang_context): Likewise.
+
+ * error.c (GLOBAL_THING): Always use '__'.
+
+2001-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_clone): Clear DECL_ASSEMBLER_NAME.
+
+ * mangle.c (mangle_decl_string): Mangle the names of overloaded
+ operators, even when they have `extern "C"' linkage.
+
+2001-03-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (get_vtable_decl): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (add_method): Remove optimization involving comparison of
+ DECL_ASSEMBLER_NAME.
+ (build_vtbl_or_vbase_field): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (check_methods): Likewise.
+ (build_clone): Likewise.
+ (built_vtt): Likewise.
+ * cp-tree.h (DECL_NEEDED_P): Likewise.
+ * decl.c (pushtag): Likewise.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise.
+ (builtin_function): Likewise.
+ (build_library_fn_1): Set DECL_LANGUAGE for library functions.
+ (build_cp_library_fn): Likewise.
+ (maybe_commonize_var): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Likewise.
+ (grokdeclarator): Likewise.
+ (start_function): Likewise.
+ (cp_missing_return_ok_p): Likewise.
+ * decl2.c (grokclassfn): Likewise.
+ (check_classfn): Likewise.
+ (finish_static_data_member_decl): Likewise.
+ (grokfield): Likewise.
+ * error.c (GLOBAL_IORD_P): Remove.
+ (dump_global_iord): Improve output.
+ (dump_decl): Avoid using DECL_ASSEMBLER_NAME.
+ * except.c (nothrow_libfn_p): Summarily reject any function not in
+ namespace-scope.
+ * init.c (build_java_class_ref): Don't explicitly set
+ DECL_ASSEMBLER_NAME after calling mangle_decl.
+ * mangle.c (mangle_decl_string): Handle extern "C" functions.
+ (mangle_decl): Set the DECL_ASSEMBLER_NAME for the decl.
+ * method.c (set_mangled_name_for_decl): Don't explicitly set
+ DECL_ASSEMBLER_NAME after calling mangle_decl.
+ (make_thunk): Explicitly set the DECL_ASSEMBLER_NAME and
+ IDENTIFIER_GLOBAL_VALUE for the thunk.
+ * pt.c (set_mangled_name_for_template_decl): Remove.
+ (check_explicit_specialization): Don't use it.
+ (looup_template_class): Don't set DECL_ASSEMBLER_NAME.
+ (tsubst_friend_function): Likewise.
+ (tsubst_decl): Likewise.
+ (regenerate_decl_from_template): Use COPY_DECL_ASSEMBLER_NAME.
+ * rtti.c (get_tinfo_decl): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (tinfo_base_init): Likewise.
+ (create_real_tinfo_var): Likewise.
+ * search.c (looup_field_1): Likewise.
+ * semantics.c (finish_named_return_value): Likewise.
+ * tree.c (init_tree): Set lang_set_decl_assembler_name.
+
+2001-03-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ Correct semantics restrictions checking in throw-expression.
+ * except.c (is_admissible_throw_operand): New function.
+ (build_throw): Use it.
+
+2001-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_make_fnname_decl): Set DECL_IGNORED_P on __FUNCTION__
+ and its ilk.
+
+2001-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_clone): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
+ * cp-tree.h (DECL_IN_MEMORY_P): Likewise.
+ * decl.c (duplicate_decls): Likewise.
+ (builtin_function): Likewise.
+ (build_library_fn): Likewise.
+ (build_cp_library_fn): Likewise.
+ (check_initializer): Likewise.
+ (cp_finish_decl): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (grok_function_init): Remove #if 0'd code.
+ (finish_anon_union): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
+ * friend.c (do_friend): Likewise.
+ * init.c (get_temp_regvar): Likewise.
+ * method.c (make_thunk): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (tsubst_decl): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ * semantics.c (genrtl_named_return_value): Likewise.
+ (expand_body): Likewise.
+ (genrtl_finish_function): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+
+2001-03-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_like_real): Add extra semantics to INNER
+ parameter. Don't convert to temporary if a user conversion
+ gives us an lvalue that we're about to bind to a reference.
+ Set INNER to indicate pending reference binding on recursive
+ calls.
+
+2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c: Delete duplicate pending_lang_change.
+
+2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c (handle_pragma_interface, handle_pragma_implementation):
+ Similarly.
+ * cp/repo.c (get_base_filename, open_repo_file): Similarly.
+ * cp/cp-tree.h: Remove file_name_nondirectory prototype.
+
+2001-03-09 Zack Weinberg <zackw@stanford.edu>
+
+ * Make-lang.in: Add dependencies on $(TM_P_H) as appropriate.
+
+2001-03-08 Stan Shebs <shebs@apple.com>
+
+ * cp-tree.h (set_identifier_local_value): Remove unused decl.
+
+2001-03-06 Zack Weinberg <zackw@stanford.edu>
+
+ * spew.c: Remove references to CPP_OSTRING.
+
+2001-03-06 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (convert_arguments): Check that we have an fndecl.
+
+2001-03-05 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (convert_arguments): Don't do ellipsis conversion for
+ __built_in_constant_p.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_static_cast): Allow enum to enum conversions
+ as per DR 128.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (check_field_decls): Pointers to member do not a
+ non-pod struct make, as per DR 148.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (joust): cp_pedwarn when using gnu extension concerning
+ worst conversion sequences.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * decl.c: Replace all uses of 'boolean' with 'bool'.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * lang-specs.h: Add zero initializer for cpp_spec field to
+ all array elements that need one. Don't put an #ifdef inside
+ the initializer list; set a default for CPLUSPLUS_CPP_SPEC and
+ use it.
+
+2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement using decls inside template functions.
+ * decl2.c (validate_nonmember_using_decl): Don't special case
+ fake_std_node in the global namespace. Don't reject early when
+ processing a template.
+ (do_local_using_decl): Add to statement tree. Don't do further
+ processing when building a template.
+ * pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
+
+2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Don't complain if we find
+ same function. Do complain about ambiguating extern "C"
+ declarations.
+
+2001-02-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove floating point and complex type template constant parms.
+ * pt.c (convert_nontype_argument): Remove REAL_TYPE and
+ COMPLEX_TYPE extensions.
+ (invalid_nontype_parm_type_p): Likewise.
+
+2001-02-27 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * except.c (call_eh_info): Revert "match_function"'s type.
+
+2001-02-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix ctor vtable vcall offsets.
+ * class.c (struct vtbl_init_data_s): Add rtti_binfo member.
+ (build_rtt_vtbl_entries): Lose RTTI_BINFO parameter.
+ (get_matching_base): Remove.
+ (get_original_base): New function.
+ (build_vtbl_initializer): Initialize vid.rtti_binfo.
+ Use a virtual thunk for a ctor vtable with an index
+ (add_vcall_offset_vtbl_entries_1): Check if binfo has lost a
+ primary base within a constructor vtable. Only set
+ BV_VCALL_INDEX when not a constructor vtable. Adjust vcall offset
+ when primary base has been lost.
+ * cp-tree.h (BINFO_VIRTUALS): Remove ambiguity from comment.
+
+2001-02-26 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * call.c (joust): Ensure more_specialized()'s argument length
+ parameter has correct value for constructors.
+
+2001-02-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (call_eh_info): Cleanup generation of cp_eh_info struct.
+
+ * decl.c (mark_inlined_fns): Prototype.
+
+2001-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * spew.c (yylex): Correct handling of friends.
+
+2001-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_encoding): Pass write_function_type the
+ FUNCTION_DECL for the function being encoded.
+ (write_function_type): Pass it along to write_bare_function_type.
+ (write_bare_function_type): Pass it along to write_method_parms.
+ (write_method_parms): Don't mangle the compiler-generated
+ parameters to a constructor or destructor.
+
+2001-02-22 Andreas Jaeger <aj@suse.de>
+
+ * optimize.c: Include toplev.h for
+ note_deferral_of_defined_inline_function prototype.
+
+2001-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (struct lang_decl_inlined_fns): New.
+ (struct lang_decls): Add inlined_fns.
+ (DECL_INLINED_FNS): New macro.
+ * optimize.c (struct inline_data): Add inlined_fns.
+ (declare_return_variable): Use VARRAY_ACTIVE_SIZE macro.
+ (inlinable_function_p): Likewise, fix typo in comment,
+ function is not inlinable if it already inlined function currently
+ being optimized.
+ (expand_call_inline): Add fn to inlined_fns if necessary.
+ (optimize_function): Initialize inlined_fns.
+ Save inlined_fns into DECL_INLINED_FNS after expanding inlines.
+ * decl.c (mark_inlined_fns): New function.
+ (lang_mark_tree): Call it.
+
+2001-02-21 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (struct lang_decl_flags): Remove uninlinable flag.
+ (DECL_UNINLINABLE): Move to middle-end.
+
+ * class.c (clone_function_decl): Set DECL_ABSTRACT on original fn.
+ * decl.c (duplicate_decls): Preserve DECL_ABSTRACT.
+ * class.c (build_clone): Set DECL_ABSTRACT_ORIGIN for the clone.
+ * optimize.c (maybe_clone_body): Set DECL_ABSTRACT_ORIGIN for the
+ parms and outer BLOCK. note_deferral_of_defined_inline_function.
+
+ * method.c (implicitly_declare_fn): Don't set DECL_ARTIFICIAL on
+ second parm of op=.
+
+2001-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (set_decl_namespace): Allow explicit instantiations in
+ any namespace.
+
+2001-02-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * optimize.c (expand_call_inline): Don't walk subtrees of type
+ nodes.
+
+2001-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_vcall_offset_vtbl_entries_1): Only add one entry
+ for a destructor.
+
+2001-02-18 Jason Merrill <jason@redhat.com>
+
+ Do put the VTT parameter in DECL_ARGUMENTS.
+ * cp-tree.h (struct cp_language_function): Add x_vtt_parm.
+ (current_vtt_parm): New macro.
+ (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
+ (DECL_HAS_VTT_PARM_P): New macro.
+ (DECL_VTT_PARM): Remove.
+ (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
+ * decl.c (duplicate_decls): Only copy the operator code if
+ appropriate.
+ (start_function): Set current_vtt_parm.
+ (lang_mark_tree): Don't mark vtt_parm.
+ * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
+ DECL_ARGUMENTS. Set DECL_HAS_VTT_PARM_P.
+ * class.c (build_clone): Maybe remove the VTT parm.
+ * optimize.c (maybe_clone_body): Set up the VTT parm.
+ * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
+ * call.c (build_over_call): Just allow the VTT arg.
+ * method.c (make_thunk): Don't set DECL_VTT_PARM.
+ (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
+ (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
+ * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
+ * error.c (dump_function_decl): Likewise.
+ * call.c (build_user_type_conversion_1, convert_like_real): Abort
+ if we try to call a constructor with in-charge or VTT parms.
+ * method.c (skip_artificial_parms_for): New fn.
+ * call.c (add_function_candidate, build_over_call): Call it.
+ * call.c (build_new_method_call): Use current_vtt_parm.
+ * init.c (expand_virtual_init): Likewise.
+ * class.c (same_signature_p): No longer static.
+ * cp-tree.h: Declare it.
+ * search.c (look_for_overrides_r): Use it.
+
+2001-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (new_abi_rtti_p): Remove.
+ (name_mangling_version): Likewise.
+ (flag_do_squangling): Likewise.
+ * class.c (build_rtti_vtbl_entries): Remove old ABI support.
+ * decl.c (grokfndecl): Likewise.
+ * decl2.c (name_mangling_version): Remove.
+ (flag_do_squangling): Likewise.
+ (lang_f_options): Remove `squangle'.
+ (unsupported_options): Add `squangle'.
+ (cxx_decode_option): Issue a warning about uses of
+ -fname-mangling-version.
+ (finish_file): Remove old ABI support.
+ * pt.c (check_explicit_specialization): Likewise.
+ (tsubst_decl): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ (build_headof): Likewise.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_from_decl): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ * init.c (build_new): Allow enumeration types for the array-bounds
+ in a direct-new-declarator.
+
+ * semantics.c (finish_typeof): Resolve OFFSET_REFs.
+
+ * pt.c (check_explicit_specialization): Copy TREE_PRIVATE and
+ TREE_PROTECTED from the template being specialized.
+
+2001-02-17 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (build_artificial_parm): Set TREE_READONLY.
+
+ * decl.c (bad_specifiers): Allow throw specs on things with
+ pointer-to-function or -member-function type.
+ * init.c (build_default_init): Don't use a CONSTRUCTOR to initialize
+ a pmf.
+
+2001-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (check_dtor_name): Handle template names correctly.
+
+2001-02-16 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_USE_VTT_PARM): Remove.
+ * decl2.c (maybe_retrofit_in_chrg): Don't create it.
+ * optimize.c (maybe_clone_body): Don't substitute it.
+ * call.c (build_new_method_call): Check in_chrg instead.
+ * init.c (expand_virtual_init): Likewise.
+
+2001-02-16 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl.c (check_tag_decl): Make sure a typedef for an anonymous
+ class-type introduces at least a type-name.
+
+2001-02-16 Jakub Jelinek <jakub@redhat.com>
+
+ * call.c (convert_like_real): Create a temporary for non-lvalue.
+
+2001-02-16 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * cp-tree.h: Fix typos in comments.
+
+2001-02-16 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (remap_block): If we're compiling a clone, pass the
+ new block to insert_block.
+
+2001-02-16 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Robustify.
+
+2001-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (push_template_decl_real): Don't remangle the name of a
+ class template.
+
+2001-02-15 Jim Meyering <meyering@lucent.com>
+
+ * Make-lang.in (c++.install-common): Depend on installdirs.
+ (c++.install-info): Likewise.
+ (c++.install-man): Likewise.
+
+2001-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck2.c (build_m_component_ref): Robustify.
+
+2001-02-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * friend.c (do_friend): Don't take the nested [template] class
+ into account when deciding whether to warn about the friend
+ function not referring to a template function.
+
+2001-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (build_unary_op): Clarify error message.
+
+2001-02-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * parse.y (component_constructor_declarator): allow optional
+ parentheses around constructor class name.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (setup_vtbl_ptr): Move prototype to semantics.c
+ section.
+ * init.c (emit_base_init): Remove incorrect comment about
+ virtual bases.
+ * method.c (make_thunk): Fix comment alignment.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill remnants of this is variable.
+ * cp-tree.h (flag_this_is_variable): Remove.
+ * decl2.c (flag_this_is_variable): Remove.
+ * class.c (fixed_type_or_null): Add cdtor parm. Adjust.
+ (build_vbase_path): The path is non-static, even in a cdtor.
+ (resolves_to_fixed_type_p): Add additional return value.
+ * search.c (init_vbase_pointers): Adjust.
+ * tree.c (lvalue_p_1): Adjust.
+ * typeck.c (mark_addressable): Adjust.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Don't check cv quals of array types.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type_real): Use CP_TYPE_QUALS to
+ check whether we already have the type.
+
+2001-02-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_DESTRUCTORS): Fix typo in comment.
+ * call.c (build_op_delete_call): Simplify to remove duplicate
+ code.
+ * class.c (clone_function_decl): Don't build the deleting variant
+ of a non-virtual destructor.
+ * decl.c (finish_destructor_body): Don't call delete if this is a
+ non-virtual destructor.
+ * init.c (build_delete): Explicitly call `operator delete' when
+ deleting an object with a non-virtual destructor.
+
+2001-02-13 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Add more __EXCEPTIONS.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck2.c (process_init_constructor): Check
+ TREE_HAS_CONSTRUCTOR before issuing missing init warning.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (maybe_adjust_types_for_deduction, DEDUCE_ORDER case):
+ Remove spurious information in comment. Allow further
+ adjustments of REFERENCE_TYPE args.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * errfn.c (cp_deprecated): Tweak diagnostic text.
+ * parse.y (new_initializer): Deprecate initializer lists
+ extension.
+
+2001-02-12 Mark Mitchell <mark@codesourcery.com>
+
+ Remove old ABI support.
+
+2001-02-11 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (flag_vtable_thunks): Always set it to 1.
+ (flag_new_abi): Likewise.
+ * lang-specs.h: Remove conditional on ENABLE_NEW_GXX_ABI.
+
+ * Makefile.in (g++spec.o): Fix typo.
+
+2001-02-09 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Restore definition of __EXCEPTIONS.
+
+2001-02-08 Jason Merrill <jason@redhat.com>
+
+ * search.c (shared_member_p): New function.
+ (lookup_field_r): Use it.
+ * cp-tree.h (SHARED_MEMBER_P): Remove.
+
+ * method.c (process_overload_item): Handle template-dependent array
+ bounds.
+ * pt.c (type_unification_real): If we end up with undeduced nontype
+ parms, try again.
+
+ * decl.c (lookup_name_real): Tweak warning to refer to decls, not
+ types.
+
+ * typeck2.c (friendly_abort): Don't say anything if we have
+ earlier errors or sorries.
+
+ * decl.c (check_tag_decl): Notice attempts to redefine bool and
+ wchar_t. Ignore if in_system_header.
+
+ * decl.c (maybe_push_cleanup_level): New fn...
+ (start_decl_1): ...split out from here.
+ * cvt.c (build_up_reference): Use it.
+ * cp-tree.h: Declare it.
+
+2001-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * lang-specs.h: Use CPLUSPLUS_CPP_SPEC for the preprocessor
+ spec.
+
+2001-02-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Make sure it's a primary
+ template or template_template_parm when called from the parser.
+ (instantiate_template_class): Add assertion.
+
+2001-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * method.c (build_mangled_name) [old abi]: Protect flush_repeats()
+ from error_mark_node.
+
+2001-02-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix specification and implementation bugs in V3 ABI
+ construction vtables.
+ * cp-tree.h (flag_dump_class_layout): New flag.
+ (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P): Remove.
+ (BINFO_LOST_PRIMARY_P): New flag.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust asserts.
+ (BINFO_PRIMARY_MARKED_P): Rename to ...
+ (BINFO_PRIMARY_P): ... here.
+ (binfo_via_virtual): New prototype.
+ * decl2.c (flag_dump_class_layout): New flag.
+ (cxx_decode_option): Set it. Adjust -fdump-translation-unit to
+ use `=' as a file name separator.
+ * init.c (dfs_initialize_vtbl_ptrs): Walk into virtual primary
+ bases.
+ (build_vtbl_address): If this is a virtual primary base, then
+ get the vtbl of what it is ultimately primary for.
+ * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Adjust
+ for BINFO_PRIMARY_P.
+ (dfs_skip_nonprimary_vbases_markedp): Likewise.
+ (get_shared_vbase_if_not_primary): Likewise.
+ (dfs_get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (dfs_find_vbase_instance): Likewise.
+ (find_vbase_instance): Likewise.
+ (binfo_from_vbase): Adjust comment to reflect reality.
+ (binfo_via_virtual): New function.
+ * class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): New macros
+ for binfo walking during VTT construction.
+ (dfs_mark_primary_bases): Remove.
+ (force_canonical_binfo_r): New function.
+ (force_canonical_binfo): New function.
+ (mark_primary_virtual_base): New function.
+ (mark_primary_bases): Walk in inheritance graph order, use
+ mark_primary_virtual_base.
+ (determine_primary_base): Use some more intermediate variables.
+ (dfs_find_final_overrider): Don't check for overriding along a
+ virtual path.
+ (dfs_modify_vtables): Walk into primary virtual bases too.
+ (walk_subobject_offsets): Adjust for BINFO_PRIMARY_P.
+ (build_base_fields): Likewise.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Likewise.
+ (end_of_class): Likewise.
+ (finish_struct_1): Call dump_class_hierarchy, if requested.
+ (dfs_get_primary_binfo): Use BINFO_TYPE for binfos.
+ (dump_class_hierarchy_r): Add stream parameter. Emit more information.
+ (dump_class_hierarchy): Add file parameter. Append to file, if
+ required.
+ (finish_vtbls): Adjust accumulate_vtbl_inits call.
+ Use canonical base for virtual bases.
+ (build_vtt): Add more comments. Adjust build_vtt_inits call.
+ (build_vtt_inits): Remove VIRTUAL_VTTS_P parm.
+ Only set BINFO_VPTR_INDEX on top level. Use VTT_TOP_LEVEL_P,
+ VTT_MARKED_BINFO_P for binfo walking. Use canonical vbase for
+ virtual VTTs.
+ (dfs_build_secondary_vptr_vtt_inits): Extract VTT_TOP_LEVEL_P
+ from DATA. We want virtual primary bases and all bases via virtual.
+ Only set BINFO_VPTR_INDEX for top level. Look up from a primary
+ virtual base when not a construction vtable.
+ (dfs_ctor_vtable_bases_queue_p): New DFS predicate.
+ (build_ctor_vtbl_group): Adjust accumulate_vtbl_inits call.
+ Use canonical bases when processing virtual bases.
+ (accumulate_vtbl_inits): We're interested in any base via a
+ virtual path.
+ (dfs_accumulate_vtbl_inits): If this is a primary virtual base
+ within a construction vtable, determine what is being overridden.
+ (build_vtbl_initializer): Add more comments
+ (add_vcall_offset_vtbl_entries_1): Adjust comment.
+ (build_rtti_vtbl_entries): Check if the base has lost its
+ primary.
+
+2001-02-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (g++spec.o): Adjust use of DRIVER_DEFINES.
+
+2001-02-04 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (pushdecl): Call abort instead of fatal.
+ * except.c (decl_is_java_type): Call fatal_error instead of fatal.
+ * init.c (build_new_1): Likewise.
+ (build_java_class_ref): Call internal_error and fatal_error, not fatal.
+ * decl.c (build_typename_type): hash_table_init now returns void.
+ decl.c (init_decl_processing): Make an error non-fatal.
+
+2001-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting.
+ Document.
+ (CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ * decl.c (maybe_commonize_var): Use the new name-mangling where
+ appropriate.
+ * decl2.c (comdat_linkage): Enhance comments. Make all
+ compiler-generated things static, if COMDAT is not available.
+ (get_tinfo_decl): Do not make typeinfo objects that belong in the
+ library COMDAT.
+ (tinfo_base_init): Use the correct mangled name for typeinfo
+ strings, and push them into the global scope.
+ (typeinfo_in_lib_p): New function.
+ (synthesize_tinfo_var): Use it.
+ (create_real_tinfo_var): Likewise.
+
+2001-02-03 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (push_class_binding): Use context_for_name_lookup instead
+ of CP_DECL_CONTEXT.
+ * search.c (context_for_name_lookup): Remove static. Check for NULL
+ context in the loop.
+ * cp-tree.h (context_for_name_lookup): Add prototype.
+
+2001-02-02 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (build_expr_ptr_wrapper, can_free): Remove.
+ * tree.c (build_expr_ptr_wrapper, can_free, permanent_obstack):
+ Remove.
+ * call.c (convert_class_to_reference, build_user_type_conversion_1,
+ add_warning): Change build_expr_ptr_wrapper to build_ptr_wrapper.
+
+2001-02-02 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (g++spec.o): Add DRIVER_DEFINES to the list
+ of macros used when compiling g++spec.c.
+ * g++spec.c (lang_specific_driver): Link with the shared
+ libgcc by default.
+
+2001-01-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (build_expr_from_tree), lex.c (make_pointer_declarator,
+ make_reference_declarator, make_call_declarator), method.c
+ (implicitly_declare_fn), parse.y (namespace_using_decl,
+ notype_unqualified_id, expr_or_declarator, new_type_id,
+ after_type_declarator, direct_after_type_declarator,
+ notype_declarator, complex_notype_declarator,
+ complex_direct_notype_declarator, qualified_id,
+ notype_qualified_id, overqualified_id, direct_new_declarator,
+ absdcl, direct_abstract_declarator, conversion_declarator), pt.c
+ (tsubst), semantics.c (begin_constructor_declarator): Use build_nt
+ instead of build_parse_node.
+
+2001-01-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (cp_tree_index): Delete CPTI_MINUS_ONE.
+ (minus_one_node): Moved to top level gcc directory. Renamed
+ to integer_minus_one_node.
+
+ * init.c (init_init_processing): Don't set minus_one_node.
+ (build_vec_init): Use integer_minus_one_node.
+
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+
+2001-01-28 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (copy_body_r): If MODIFY_EXPR has both arguments
+ identical and they would be replaced with constant, remove
+ MODIFY_EXPR from the tree.
+
+2001-01-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Remove all dependencies on defaults.h.
+ * call.c: Don't include defaults.h.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2001-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (write_mangled_name, write_encoding): Mangle overloaded
+ operators even in "C" linkage.
+ * method.c (set_mangled_name_for_decl): Likewise.
+ * decl.c (grokfndecl): Call set_mangled_name_for_decl even for
+ overloaded operators in "C" linkage.
+
+2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_decl): Remove IN_DECL parameter.
+ (tsubst_arg_types): Check parameter is not void.
+ (tsubst): Adjust tsubst_decl call.
+
+2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (add_builtin_candidate): Quote std properly, from
+ previous change.
+
+2001-01-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (check_explicit_specialization): Clone constructors and
+ destructors.
+
+2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Don't presume DECL_LANG_SPECIFIC
+ indicates anything special about template depth. Make sure we
+ only count the user visible template classes.
+
+2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_conv): Typo in comment.
+ (add_builtin_candidate): Add more explanation.
+ Remove extra test for ENUMERAL_TYPE in {PRE,POST}INCREMENT_EXPR.
+ Allow ENUMERAL_TYPEs for relops and eqops. Add both candidates
+ when we have enumeral types.
+ (add_builtin_candidates): Add more explanation. Add ENUMERAL_TYPE
+ candidates for relops and eqops.
+ (joust): Simplify control flow. Allow a non-template user
+ function to hide a builtin.
+
+2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
+ (more_specialized): Add deduction parameter.
+ * call.c (joust): Adjust more_specialized call.
+ * pt.c (UNIFY_ALLOW_OUTER_MORE_CV_QUAL,
+ UNIFY_ALLOW_OUTER_LESS_CV_QUAL): New unify flags.
+ (get_bindings_order): Remove.
+ (get_bindings_real): Add DEDUCE parameter.
+ (maybe_adjust_types_for_deduction): Return extra unify flags. Do
+ REFERENCE_TYPE jig for DEDUCE_ORDER.
+ (type_unification_real): Deal with DEDUCE_ORDER. Use result of
+ maybe_adjust_types_for_deduction.
+ (more_specialized): Add DEDUCE parameter. Call get_bindings_real
+ directly.
+ (try_one_overload): Use result of maybe_adjust_types_for_deduction.
+ (check_cv_quals_for_unify): Use new unify qualifier flags.
+ (unify): Clear new unify qualifier flags.
+ (get_bindings_real): Add DEDUCE parameter.
+ (get_bindings): Adjust call to get_bindings_real.
+ (get_bindings_overload): Likewise.
+ (most_specialized_instantiation): Adjust call to
+ more_specialized.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI.
+
+ * decl.c (init_decl_processing): Just force -fvtable-thunks on if
+ -fnew-abi.
+
+2001-01-19 Ute Pelkmann <scope.muc@t-online.de>
+
+ * decl2.c (arg_assoc_class): Fix double iteration logic.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_delete): Always call convert_force to strip cv-quals.
+
+ * decl2.c (flag_new_abi): Depend on ENABLE_NEW_GXX_ABI.
+ * lang-specs.h: Default ABI depends on ENABLE_NEW_GXX_ABI.
+ * g++spec.c: Don't look at ENABLE_NEW_GXX_ABI.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (get_vbase_1): Count only virtual bases.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Robustify flag clearing.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (lookup_template_class): Add complain parm.
+ * decl.c (lookup_namespace_name): Adjust call to
+ lookup_template_class.
+ (make_typename_type): Likewise.
+ * semantics.c (finish_template_type): Likewise.
+ * pt.c (lookup_template_class): Add complain parm. Adjust.
+ (tsubst_aggr_type): Pass COMPLAIN down to lookup_template_class.
+ (tsubst): Likewise.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (copy_default_args_to_explicit_spec): Preserve
+ object's CV quals. Reorganize.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_modify_expr): Say `initialization' for
+ INIT_EXPRs.
+ * init.c (build_default_init): Convert to enumeral type, if
+ needed.
+
+2001-01-18 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (nomods_initdcl0): Properly set things up for
+ initdcl0_innards.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
+ (type_unification_real): Set it.
+ (unify): Use it.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (finish_destructor_body): Convert to vbase pointer here.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (begin_class_definition): Check we're not inside a
+ template parm list.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (walk_tree, TREE_LIST): Don't walk the TREE_PURPOSE of
+ BASELINK_P.
+
+2001-01-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck.c (build_function_call_real): Call fold on the CALL_EXPR.
+ * call.c (build_over_call): Add comment.
+
+2001-01-16 Daniel Berlin <dberlin@redhat.com>
+
+ * cvt.c (ocp_convert): Handle vector type conversion
+ * typeck2.c (digest_init): Handle vector type initializations
+
+2001-01-16 Phil Edwards <pme@sources.redhat.com>
+
+ * g++spec.c: Don't add libraries needlessly if -fsyntax-only
+ was given.
+
+2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (check_nontype_parm): Rename to ...
+ (invalid_nontype_parm_type_p): ... here.
+ (process_template_parm): Adjust.
+ (convert_template_argument): Adjust.
+
+2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (check_nontype_parm): New function.
+ (process_template_parm): Use it.
+ (convert_template_argument): Use it.
+ (convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
+ member.
+
+2001-01-14 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * tree.c: Add defaults.h
+ (cp_valid_lang_attribute): Incorporate SUPPORTS_INIT_PRIORITY.
+ * Make-lang.in (cp/tree.o): Add defaults.h.
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Add c-format.o.
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g++.1: Change to be ".so man1/gcc.1".
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.info, c++.install-info): Build and install g++
+ internals info.
+ (c++.uninstall, c++.maintainer-clean): Remove g++ internals info.
+ ($(srcdir)/cp/g++int.info): New target.
+ * gxxint.texi: Add info directory entry. Use @@ in email address.
+ * .cvsignore: Update.
+
+2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_c_cast): Do template processing earlier.
+ Always pedwarn on array casts.
+
+2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * friend.c (make_friend_class): Make sure a templated class is
+ actually a template.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (get_guard): Set linkage from guarded decl.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_default_arg): Check for unprocessed
+ DEFAULT_ARG.
+ * cp-tree.h (replace_defarg): Move to spew.c.
+ (maybe_snarf_defarg, add_defarg_fn, do_pending_defargs): Move to
+ spew.c, which is where they really are.
+ (done_pending_defargs): Declare.
+ (unprocessed_defarg_fn): Declare.
+ * decl.c (replace_defarg): Move to spew.c
+ * parse.y (structsp): Call done_pending_defargs.
+ * spew.c (defarg_fns): Rearrange list structure.
+ (defarg_fnsdone): New static variable.
+ (defarg_depfns): New static variable.
+ (init_spew): Adjust.
+ (add_defarg_fn): Store the type in TREE_TYPE.
+ (do_pending_defargs): Detect and deal with ordering constraints
+ and circularity.
+ (done_pending_defargs): New function.
+ (unprocessed_defarg_fn): New function.
+ (replace_defarg): Moved from decl.c. Robustify. Don't save
+ if circularity detected.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Check array has a domain, before checking
+ whether it is variable sized.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokparms): Unobfuscate and get correct diagnostic for
+ parameters with pointers to arrays of unknown bound.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (template_parm_header, template_spec_header): New
+ reductions. Split out from ...
+ (template_header): ... here. Use them.
+ (template_template_parm): Use template_parm_header.
+ * semantics.c (finish_template_template_parm): Add assert.
+
+2001-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_builtin_type): Fix thinko.
+
+ * pt.c (copy_default_args_to_explicit_spec_1): New function.
+ (copy_default_args_to_explicit_spec): Likewise.
+ (check_explicit_specialization): Use it.
+
+ * class.c (finish_struct_1): Remove last argument in call to
+ make_decl_rtl; use make_function_rtl instead of make_decl_rtl.
+ * decl.c (builtin_function): Likewise.
+ (build_cp_library_fn): Likewise.
+ (check_initializer): Likewise.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (start_function): Likewise.
+ * decl2.c (finish_anon_union): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_java_class_ref): Likewise.
+ * method.c (make_thunk): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ * semantics.c (expand_body): Likewise.
+
+2001-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CLONED_FUNCTION_P): Avoid wild reads by not
+ looking at DECL_CLONED_FUNCTION for non-functions.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_template_parameter): Use parm to determine how
+ to print default value.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Clear more flags.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_method_call): Use binfo_for_vbase.
+
+2001-01-10 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * cp-tree.h (flag_cond_mismatch): Don't declare.
+ * decl2.c (flag_cond_mismatch): Don't define.
+ (lang_f_options): Remove cond-mismatch.
+ (unsupported_options): Add cond-mismatch.
+
+2001-01-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (handle_using_decl): Reject using of constructor name
+ of sourcing class. Allow injecting of a method with same name as
+ nested class. Fixup error messages.
+
+2001-01-09 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (lang_decode_option): Handle -Wformat=2.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename defined_in_class to
+ initialized_in_class.
+ (DECL_DEFINED_IN_CLASS_P): Rename to ...
+ (DECL_INITIALIZED_IN_CLASS_P): ... here, to reflect true meaning.
+ * decl.c (duplicate_decls): Preseve DECL_INITIALIZED_IN_CLASS_P.
+ (cp_finish_decl): Adjust for DECL_INITIALIZED_IN_CLASS_P.
+ * pt.c (check_default_tmpl_args): Adjust for
+ DECL_INITIALIZED_IN_CLASS_P.
+ (instantiate_class_template): Likewise.
+ (instantiate_decl): Check DECL_INITIALIZED_IN_CLASS_P.
+
+ * class.c (finish_struct): Constify saved_filename.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Adjust diagnostic.
+ (finish_struct): Locally set location to start of struct.
+ * decl.c (fixup_anonymous_aggr): Use cp_error_at.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (struct binding_level): Adjust class_shadowed comments
+ to reflect reality.
+ (push_class_level_binding): Adjust comments to reflect reality.
+ Set IDENTIFIER_CLASS_VALUE when replacing an existing binding.
+ Don't set TREE_VALUE on the class_shadowed list.
+
+2001-01-07 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl2.c (acceptable_java_type): Allow references too.
+ * init.c (build_java_class_ref): When using the new ABI, search
+ `class$' and have it mangled with `mangle_decl.'
+ * mangle.c (write_java_integer_type_codes): New function.
+ (write_builtin_type): Detect and mangle Java integer and real
+ types.
+
+2001-01-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Don't accept `asm' specifiers for
+ non-static data members.
+
+2001-01-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * expr.c (cplus_expand_expr): Don't reset `target'.
+
+2001-01-07 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/decl2.c (cxx_post_options): Call cpp_post_options.
+
+2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (template_datadef): Check for error_mark_node.
+
+2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (DEFAULT_ARG): Make `x' class.
+
+2001-01-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
+ (record_builtin_type): Make non-static.
+ (flag_short_double): Don't declare.
+ (init_decl_processing): Remove the creation of many tree nodes now
+ in c_common_nodes_and_builtins.
+ (build_void_list_node): New function.
+ * decl2.c (flag_short_double, flag_short_wchar): Don't define.
+ * cp-tree.h (flag_short_wchar): Don't declare.
+
+2001-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conv): Don't use build1 for USER_CONV.
+ * pt.c (tsubst_copy): Or for PREINCREMENT_EXPR and similar nodes.
+
+2001-01-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lex.c (lang_init): Call c_common_lang_init.
+
+2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (lookup_fnfields_here): Remove.
+ (look_for_overrides_r): Use lookup_fnfields_1.
+ Ignore functions from using declarations.
+
+2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement exceptions specifiers for implicit member functions.
+ * cp-tree.h (merge_exceptions_specifiers): Declare new function.
+ * method.c (synthesize_exception_spec): New function.
+ (locate_dtor, locate_ctor, locate_copy): New functions.
+ (implicitly_declare_fn): Generate the exception spec too.
+ * search.c (check_final_overrider): Check artificial functions
+ too.
+ * typeck2.c (merge_exception_specifiers): New function.
+
+2001-01-03 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_default_init): New fn.
+ (perform_member_init): Split out from here.
+ (build_new_1): Use it. Simplify initialization logic.
+ (build_vec_init): Take an array, rather than a pointer and maxindex.
+ Speed up simple initializations. Don't clean up if we're assigning.
+ * cp-tree.h: Adjust.
+ * decl2.c (do_static_initialization): Remove TREE_VEC case.
+ * parse.y (new_initializer): Return void_zero_node for ().
+ * typeck.c (build_modify_expr): Handle getting a CONSTRUCTOR.
+ * typeck2.c (digest_init): Only complain about user-written
+ CONSTRUCTORs.
+
+2000-12-22 Mike Stump <mrs@wrs.com>
+
+ * decl2.c: (max_tinst_depth): Increase to 50.
+
+2001-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (invalidate_class_lookup_cache): Zero the
+ previous_class_values.
+ * cp-tree.h (TMPL_PARMS_DEPTH): Use TREE_INT_CST_LOW, not
+ TREE_INT_CST_HIGH.
+ (CLASSTYPE_TEMPLATE_LEVEL): Likewise.
+ * decl.c (free_bindings): New variable.
+ (push_binding): Don't create a new binding if we have one on the
+ free list.
+ (pop_binding): Put old bindings on the free list.
+ (init_decl_processing): Use size_int, not build_int_2.
+ Register free_bindings as a GC root.
+ (cp_make_fname_decl): Use size_int, not build_int_2.
+ (push_inline_template_parms_recursive): Likewise.
+ (end_template_parm_list): Likewise.
+ (for_each_template_parm): Do not use walk_tree_without_duplicates.
+ (tsubst_template_parms): Use size_int, not build_int_2.
+ (tsubst): Likewise.
+ * rtti.c (get_vmi_pseudo_type_info): Likewise.
+
+2001-01-02 Richard Henderson <rth@redhat.com>
+
+ * parse.y (asm): Set ASM_INPUT_P.
+
+2001-01-02 Jason Merrill <jason@redhat.com>
+
+ * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
+ for v3 ABI.
+
+ * typeck.c (cp_truthvalue_conversion): New fn.
+ * cvt.c (ocp_convert): Use it.
+
+ * cp-tree.h: Lose c-common.c decls.
+
+ * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
+ * cvt.c (convert_to_void): Use type_unknown_p.
+
+ * typeck.c (strip_all_pointer_quals): Also strip quals from
+ pointer-to-member types.
+
+ * Make-lang.in (cp/TAGS): Use --no-globals. Ignore parse.c, and treat
+ parse.y as C.
+
+ * call.c (build_new_method_call): Do evaluate the object parameter
+ when accessing a static member.
+ * typeck.c (build_component_ref): Likewise.
+
+2001-01-02 Andreas Jaeger <aj@suse.de>
+
+ * decl.c (cp_missing_noreturn_ok_p): New.
+ (init_decl_processing): Set lang_missing_noreturn_ok_p.
+
+2000-12-29 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (init_decl_processing): Fix sign of wchar_type_node.
+
+2000-12-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (pushclass): Remove #if 0'd code.
+ * cp-tree.h (overload_template_name): Remove.
+ * decl.c (store_bindings): Simplify.
+ (pop_from_top_level): Likewise.
+ * pt.c (overload_template_name): Remove.
+ (instantiate_decl): Don't call push_to_top_level if it's not
+ needed.
+
+2000-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (register_local_specialization): Don't return a value.
+ (lookup_template_class): Use move-to-front heuristic when looking
+ up template instantiations.
+ (instantiate_decl): Only push_to_top_level when we're actually
+ going to instantiate the template.
+
+2000-12-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * search.c (binfo_for_vtable): Return least derived class, not
+ most. Handle secondary vtables.
+
+2000-12-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (more_specialized): Don't optimize len==0.
+ (fn_type_unification): If we're adding the return type, increase len.
+
+ * typeck.c (build_binary_op): Fix pmf comparison logic.
+
+ * call.c (joust): Use DECL_NONSTATIC_MEMBER_FUNCTION_P, not
+ DECL_STATIC_FUNCTION_P.
+
+ * semantics.c (genrtl_finish_function): Don't try to jump to
+ return_label unless it exists.
+
+ In partial ordering for a call, ignore parms for which we don't have
+ a real argument.
+ * call.c (joust): Pass len to more_specialized.
+ (add_template_candidate_real): Strip 'this', pass len.
+ * pt.c (more_specialized): Pass len down. Lose explicit_args parm.
+ (get_bindings_order): New fn. Pass len down.
+ (get_bindings_real): Strip 'this', pass len.
+ (fn_type_unification): Likewise.
+ (type_unification_real): Succeed after checking 'len' args.
+ (most_specialized_instantiation): Lose explicit_args parm.
+ * class.c (resolve_address_of_overloaded_function): Strip 'this',
+ pass len.
+
+2000-12-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
+ DECL_TEMPLATE_RESULT.
+
+ * search.c (lookup_field_r): Call lookup_fnfields_1, not
+ lookup_fnfields_here.
+
+ * parse.y (typename_sub2): Return the TYPE_DECL, not the type.
+
+ * call.c (build_object_call): Also allow conversions that return
+ reference to pointer to function.
+ (add_conv_candidate): Handle totype being ref to ptr to fn.
+ (build_field_call): Also allow members of type reference to function.
+ Lose support for calling pointer to METHOD_TYPE fields.
+
+ * error.c (dump_expr): Handle *_CAST_EXPR.
+
+ * typeck2.c (build_scoped_ref): Always convert to the naming class.
+
+ * tree.c (break_out_cleanups): Lose.
+ * cp-tree.h: Remove prototype.
+ * typeck.c (build_component_ref): Don't break_out_cleanups.
+ (build_compound_expr): Likewise.
+ * semantics.c (finish_expr_stmt): Likewise.
+
+2000-12-20 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h: Update declarations.
+ * decl.c (finish_case_label): Return the new stmt node.
+ * semantics.c (finish_goto_stmt): Likewise.
+ (finish_expr_stmt, finish_return_stmt): Likewise.
+ (finish_break_stmt, finish_continue_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ * parse.y (already_scoped_stmt): Set STMT_LINENO.
+ (compstmt, implicitly_scoped_stmt, stmt): Likewise.
+ (simple_if, simple_stmt): Return the new stmt node.
+ (save_lineno): New.
+
+2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * cp-tree.h: Don't declare warn_long_long.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * tree.c (no_linkage_helper): Use CLASS_TYPE_P instead of
+ IS_AGGR_TYPE.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (unify): Handle when both ARG and PARM are
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (reduce_template_parm_level): Set DECL_ARTIFICIAL and
+ DECL_TEMPLATE_PARM_P.
+
+2000-12-15 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Reorganize. Now with 100% fewer SAVE_EXPRs!
+
+ * init.c (build_new_1): Don't strip quals from type.
+
+ * decl.c (pushdecl): Don't check for linkage on a non-decl.
+
+ * call.c (build_op_delete_call): See through ARRAY_TYPEs.
+
+ * call.c (build_new_function_call): Lose space before paren in
+ error message.
+ (build_new_method_call): Likewise.
+
+ * typeck2.c (build_m_component_ref): Propagate quals from datum.
+
+2000-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (check_explicit_specialization): Propagate default
+ function arguments to explicit specializations.
+
+2000-12-13 DJ Delorie <dj@redhat.com>
+
+ * typeck.c (build_binary_op): Do signed/unsigned warnings for >?
+ and <? operators.
+
+2000-12-08 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_function_name): Don't let the user see __comp_ctor.
+
+ Clean up copy-initialization in overloading code.
+ * call.c (build_user_type_conversion_1): Die if we are asked to
+ convert to the same or a base type.
+ (implicit_conversion): Avoid doing so. Lose reference binding code.
+ (convert_like_real): Treat BASE_CONV and RVALUE_CONV as implicit
+ direct-initialization. Also do direct-init part of copy-init.
+ (build_user_type_conversion): Don't provide context to convert_like.
+ * cvt.c (ocp_convert): build_user_type_conversion will now provide
+ the constructor call for copy-init.
+
+ * pt.c (tsubst_decl): Call clone_function_decl here if this is an
+ instantiation of a member template.
+ (do_decl_instantiation): Not here.
+
+2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (check_field_decls): Don't special case anonymous
+ fields in error messages.
+ (note_name_declared_in_class): Use %D on diagnostic.
+
+ * tree.c (pod_type_p): Use strip_array_types.
+ (cp_valid_lang_attribute): Likewise.
+ * typeck.c (cp_type_quals): Strip arrays separately, to avoid
+ multiple evaluations.
+ (cp_has_mutable_p): Use strip_array_types.
+
+2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (sufficient_parms_p): Declare new function.
+ * call.c (sufficient_parms_p): New function, broken out of ...
+ (add_function_candidate): ... here. Use it.
+ (add_conv_candidate): Use it.
+ * decl.c (grok_ctor_properties): Use it.
+
+2000-12-07 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (copy_body_r): Set STMT_IS_FULL_EXPR_P on EXPR_STMT.
+
+2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (lang_decode_option): Handle -Wformat-security.
+
+2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (verify_class_unification): New function.
+ (get_class_bindings): Use it.
+ (try_class_unification): Tidy.
+ (unify): Handle when argument of a template-id is not
+ template parameter dependent.
+ (template_args_equal): Handle when TREE_CODE's do not match.
+
+2000-12-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * lang-specs.h (c++): When invoking the stand-alone preprocessor
+ for -save-temps, pass all relevant -Defines to it, and then don't
+ pass them to cc1plus.
+
+2000-12-05 Will Cohen <wcohen@redhat.com>
+
+ * decl.c (finish_case_label): Cleared
+ more_cleanups_ok in surrounding function scopes.
+ (define_label): Likewise.
+
+2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
+ (get_matching_virtual): Remove.
+ (look_for_overrides): Declare new function.
+ * decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or
+ DECL_VINDEX here.
+ * class.c (check_for_override): Move base class iteration code
+ to look_for_overrides.
+ * search.c (next_baselink): Remove.
+ (get_virtuals_named_this): Remove.
+ (get_virtual_destructor): Remove.
+ (tree_has_any_destructors_p): Remove.
+ (struct gvnt_info): Remove.
+ (check_final_overrider): Remove `virtual' from error messages.
+ (get_matching_virtuals): Remove. Move functionality to ...
+ (look_for_overrides): ... here, and ...
+ (look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found
+ to be overriding.
+
+2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (get_delta_difference): If via a virtual base,
+ return zero.
+ * cvt.c (cp_convert_to_pointer): If via a virtual base, do no
+ adjustment.
+
+2000-12-04 Richard Henderson <rth@redhat.com>
+
+ * error.c (dump_tree): Use output_add_string not OB_PUTS.
+
+2000-12-04 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_type): Mangle VECTOR_TYPE with "U8__vector".
+ (write_builtin_type): Pass intSI_type_node and the like through
+ type_for_mode.
+ * method.c (process_overload_item): Mangle VECTOR_TYPEs with 'o'.
+ Pass intSI_type_node and the like through type_for_mode.
+ * decl2.c (arg_assoc_type): Handle VECTOR_TYPE like COMPLEX_TYPE.
+ * pt.c (tsubst, unify): Likewise.
+ * tree.c (walk_tree): Likewise.
+ * error.c (dump_type): Likewise.
+ (dump_type_prefix, dump_type_suffix): Don't bother with VECTOR_TYPE.
+
+ * Make-lang.in: Tweak top comment for emacs.
+ (cp/TAGS): Restore.
+
+ * except.c (expand_throw): Use push_throw_library_fn for _Jv_Throw.
+
+ * class.c (clone_function_decl): Robustify.
+
+2000-12-04 Michael Matz <matzmich@cs.tu-berlin.de>
+
+ * decl.c (store_bindings): Only search in the non modified
+ old_bindings for duplicates.
+
+2000-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_function_decl): Use DECL_VIRTUAL_P, not
+ TYPE_POLYMORPHIC_P.
+
+ * typeck.c (build_static_cast): Remove unused variable.
+
+2000-12-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c: Fix typo in comment.
+
+2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (warn_format): Remove definition.
+ (lang_decode_option): Handle -Wformat-nonliteral,
+ -Wno-format-extra-args and -Wno-format-y2k. Use set_Wformat.
+
+2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
+ (init_decl_processing): Don't create string_type_node,
+ const_string_type_node, wint_type_node, intmax_type_node,
+ uintmax_type_node, default_function_type, ptrdiff_type_node and
+ unsigned_ptrdiff_type_node. Adjust position of call to
+ c_common_nodes_and_builtins.
+ (identifier_global_value): New function.
+
+2000-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (standard_conversion): Reject pointer to member
+ conversions from ambiguous, inaccessible or virtual bases.
+ * typeck.c (build_static_cast): Don't check pointers to members
+ specially.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (do_build_copy_constructor): Preserve cv
+ qualifications when accessing source object members.
+ (do_build_assign_ref): Likewise. Remove separate diagnostics for
+ unnamed fields.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (do_build_assign_ref): Construct appropriately
+ CV-qualified base reference. Don't allow const casts in base
+ conversion.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_over_call): Use VOID_TYPE_P. Don't die on
+ incomplete return type.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (base_class.1): Produce a _TYPE not a _DECL.
+ * semantics.c (finish_base_specifier): Accept a _TYPE not a
+ _DECL.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (yyerror): Cope if yylval.ttype is NULL.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Diagnose undefined template contexts.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Do type access control on friend
+ class.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokfndecl): Undo COMPONENT_REF damage caused by
+ bison parser ickiness.
+ * pt.c (tsubst_friend_function): Enter namespace scope when
+ tsubsting the function name.
+ * cp-tree.h (DECL_TI_TEMPLATE): Update comment to reflect reality.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (binfo_from_vbase): Return the virtual base's binfo.
+ * cvt.c (cp_convert_to_pointer): Add force parameter.
+ Allow conversions via virtual base if forced.
+ (convert_to_pointer_force): Adjust call to cp_convert_to_pointer.
+ (ocp_convert): Likewise.
+ * search.c (binfo_from_vbase): Return the virtual base's binfo.
+ * typeck.c (get_delta_difference): Adjust handling of virtual
+ bases.
+
+2000-11-26 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (struct list_hash): Remove.
+ (list_hash_table): Make it be an htab.
+ (struct list_proxy): New type.
+ (list_hash_eq): New function.
+ (list_hash_pieces): Renamed from ...
+ (list_hash): ... this.
+ (list_hash_lookup): Remove.
+ (list_hash_add): Remove.
+ (hash_tree_cons): Use the generic hashtable.
+ (mark_list_hash): Remove.
+ (init_tree): Create the hashtable.
+
+2000-11-25 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * method.c (build_mangled_C9x_name): Rename to
+ build_mangled_C99_name. Change C9X references in comments to
+ refer to C99.
+
+2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (unary_expr): Move VA_ARG from here ...
+ (primary): ... to here.
+
+2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (finish_id_expr): If type is error_mark, return
+ error_mark.
+
+2000-11-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Simplify loop exit constructs.
+ Cope when there is no partial instantiation of a template
+ template member.
+
+2000-11-23 J"orn Rennecke <amylaar@redhat.com>
+
+ * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H).
+
+2000-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Don't use `__op'
+ prefix.
+
+ * pt.c (do_decl_instantiate): Explicitly clone constructors and
+ destructors that haven't already been cloned.
+
+2000-11-20 Richard Henderson <rth@redhat.com>
+
+ * parse.y (yyparse_1): Rename the parser entry point.
+
+2000-11-20 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (write_name): Use <unscoped-name> for names directly in
+ function scope.
+ (write_unscoped_name): Accept names directly in function scope.
+
+2000-11-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (rid_to_yy, RID_EXPORT): Make unique keyword.
+ * parse.y (extdef): Add EXPORT reduction.
+ * spew.c (yylex): Don't skip export here.
+
+2000-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Correct name of pure virtual
+ function under the new ABI.
+ * rtti.c (throw_bad_cast): Likewise, for bad cast function.
+ (throw_bad_typeid): Likewise for bad typeid function.
+
+2000-11-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokparms): Don't even function types of `void' type,
+ either.
+ * mangle.c (write_type): Don't crash when confronted with the
+ error_mark_node.
+
+ * decl.c (grokparms): Don't create parameters of `void' type.
+
+2000-11-17 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (mark_impl_file_chain): Delete.
+ (init_parse): Remove call to ggc_add_string_root. No need to
+ ggc_strdup a string constant. Do not add impl_file_chain to GC
+ roots.
+ (handle_pragma_implementation): No need to ggc_strdup main_filename.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_expr, DECL_STMT): Instantiate decl's type.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (PARMLIST_ELLIPSIS_P): New macro.
+ * decl.c (grokdeclarator): Don't reject void parms here.
+ (require_complete_types_for_parms): Simplify, use
+ complete_type_or_else.
+ (grokparms): Remove bitrot. Remove funcdef parm.
+ Deal with ellipsis parm lists here.
+ * semantics.c (finish_parmlist): Don't append void_list_node
+ here. Set PARMLIST_ELLIPSIS_P.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck2.c (incomplete_type_error): Reorganize to avoid
+ excessive diagnostics.
+
+2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (struct impl_files, internal_filename): Constify a char *.
+
+2000-11-16 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_special_name_constructor): Don't generate
+ assembler junk when confronted with an old-style constructor.
+ (write_special_name_destructor): Likewise.
+ (mangle_decl_string): Do it here instead.
+
+2000-11-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (op_error): Make error messages clearer.
+
+2000-11-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (wrapup_globals_for_namespace): Don't mark things
+ TREE_ASM_WRITTEN when they're not.
+
+2000-11-15 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (friendly_abort): Uncount the error before handing
+ off to fancy_abort.
+
+2000-11-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (lookup_anon_field): Cope with qv qualifiers.
+
+2000-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Fix typo in comment.
+ * typeck.c (expr_sizeof): Don't crash on errors.
+
+2000-11-14 Jim Wilson <wilson@redhat.com>
+
+ * lang-specs.h: Add %2 after %(cc1_options).
+
+2000-11-14 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (c_sizeof): Be strict about casting result value
+ back to c_size_type_node.
+ (expr_sizeof, c_sizeof_nowarn, c_alignof): Likewise.
+
+2000-11-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * typeck.c (build_unary_op): Use boolean_increment from
+ c-common.c, moving the relevant code there.
+
+2000-11-11 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (mark_addressable): Don't call put_var_into_stack.
+
+ * decl.c (maybe_commonize_var): Set DECL_UNINLINABLE for statics
+ in inlines.
+
+2000-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (grokdeclarator, save_function_data): Use memcpy, not bcopy.
+ * lex.c (copy_lang_decl): Likewise.
+
+2000-11-09 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (cp_dump_tree): Don't dump function bodies here.
+
+ * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
+ (dump.o): Update dependency list.
+ * cp-tree.h (DECL_MAYBE_TEMPLATE): Remove.
+ (flag_dump_translation_unit): Likewise.
+ (CP_TYPE_QUALS): Adjust definition.
+ (DECL_C_BIT_FIELD): Remove.
+ (SET_DECL_C_BIT_FIELD): Likewise.
+ (CLEAR_DECL_C_BIT_FIELD): Likewise.
+ (add_maybe_template): Likewise.
+ (strip_array_types): Likewise.
+ (dump_node_to_file): Likewise.
+ (cp_dump_tree): New function.
+ * decl.c (init_decl_processing): Set lang_dump_tree.
+ * decl2.c (flag_dump_translation_unit): Remove.
+ * dump.c: Move most of it to ../c-dump.c.
+ (cp_dump_tree): New function.
+ * pt.c (add_maybe_template): Remove.
+ * typeck.c (strip_array_types): Likewise.
+
+2000-11-07 Eric Christopher <echristo@redhat.com>
+
+ * decl.c (init_decl_processing): Change definition of
+ __wchar_t to wchar_t. Remove artificial declaration of
+ wchar_t.
+ * lex.c: Change instances of __wchar_t to wchar_t.
+
+2000-11-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (do_identifier): Don't lookup_name for operators.
+ * parse.y (operator): Save looking_for_typename.
+ (unoperator): Restore it.
+ * spew.c (frob_opname): Use nth_token for lookahead.
+
+2000-11-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grok_op_properties): Always use coerce_new_type and
+ coerce_delete_type.
+ * decl2.c (coerce_new_type): Use c_size_type_node. Preserve
+ exception specification. Tidy up.
+ (coerce_delete_type): Preserve exception specification. Tidy up.
+
+2000-11-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
+ (push_binding_level), error.c (cp_tree_printer), pt.c
+ (process_partial_specialization, tsubst_template_arg_vector),
+ search.c (lookup_member): Use memset () instead of bzero ().
+
+2000-11-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (build_ptrmemfunc_type): Allow error_mark_node.
+
+2000-11-05 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.distdir): Remove.
+
+2000-11-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Allow `extern "C"'
+ declarations from different namespaces to be combined.
+
+2000-11-03 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * decl.c: Include tm_p.h.
+
+2000-11-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * tree.c (cp_tree_equal): Use memcmp () instead of bcmp ().
+
+2000-11-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * dump.c (dequeue_and_dump), lex.c (interface_strcmp), method.c
+ (build_overload_value), repo.c (open_repo_file), xref.c
+ (open_xref_file): Use strchr () and strrchr () instead of index ()
+ and rindex ().
+
+2000-11-01 Bernd Schmidt <bernds@redhat.co.uk>
+
+ * call.c (build_over_call): Call fold on the CALL_EXPR.
+
+2000-11-01 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (dump_template_decl): Separate template hearders with
+ space not comma.
+
+2000-10-31 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Move TFF_ macros into cp-tree.h. Throughout, replace
+ TS_* flags with corresponding TFF_*. Adjust prototypes of
+ functions (which used to take a tree_string_flags) to take an int.
+
+ * cp-tree.h (enum tree_string_flags): Remove
+ (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE,
+ TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPEDEF, TFF_DECL_SPECIFIERS,
+ TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
+ TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
+ TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS,
+ TFF_TEMPLATE_NAME, TFF_EXPR_IN_PARENS, TFF_SCOPE): New macros.
+ (type_as_string, decl_as_string, expr_as_string,
+ context_as_string): Adjust prototype.
+
+ * class.c (dump_class_hierarchy_r): Use TFF_PLAIN_IDENTIFIER
+ instead of TS_PLAIN.
+
+ * pt.c (mangle_class_name_for_template): Use TFF_CHASE_TYPEDEF
+ instead of TF_CHASE_TYPEDEFS. Use TFF_PLAIN_IDENTIFIER instead of
+ plain `0'.
+
+2000-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_EXTERNAL_LINKAGE_P): New macro.
+ (linkage_kind): New enumeration.
+ (decl_linkage): New function.
+ * decl2.c (comdat_linkage): Extend comment.
+ * error.c (dump_function_decl): Print the arguments used to
+ instantiate a template, even when not printing the type of the
+ function.
+ * pt.c (convert_nontype_argument): Use DECL_EXTERNAL_LINKAGE_P,
+ not TREE_PUBLIC, to test for external linkage.
+ * tree.c (decl_linkage): New function.
+
+2000-10-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (instantiate_decl): Always instantiate static data members
+ initialized in-class.
+
+2000-10-27 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * Make-lang.in: Move all build rules here from Makefile.in,
+ adapt to new context. Wrap all rules that change the current
+ directory in parentheses. Expunge all references to $(P).
+ When one command depends on another and they're run all at
+ once, use && to separate them, not ;. Add OUTPUT_OPTION to
+ all object-file generation rules. Delete obsolete variables.
+
+ * Makefile.in: Delete.
+ * config-lang.in: Delete outputs= line.
+
+2000-10-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (dump_function_decl): Print no space between
+ `ptr-operator' the `type-specifier' of the return type.
+ (dump_type_prefix): Make sure we put space at the appropriate
+ place.
+
+2000-10-23 Jason Merrill <jason@redhat.com>
+
+ * call.c (equal_functions): Also call decls_match for extern "C" fns.
+
+2000-10-22 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Use ocp_convert to force
+ rvalue conversion.
+
+2000-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Use RVALUE_CONVs for all
+ expressions that satisfy lvalue_p, not just those that satisfy
+ real_lvalue_p.
+
+ * optimize.c (copy_body_r): Don't treat CALL_EXPRs specially.
+
+ * typeck.c (c_sizeof): Return an expression of `size_t' type,
+ not one with TYPE_IS_SIZETYPE set.
+ (dubious_conversion_warnings): Remove special-case code.
+
+2000-10-21 Geoffrey Keating <geoffk@cygnus.com>
+
+ * decl2.c (arg_assoc_type): Handle VECTOR_TYPE.
+ * error.c (dump_type): Handle VECTOR_TYPE like POINTER_TYPE.
+ (dump_type_prefix): Print vector-of-int as 'int vector'.
+ (dump_type_suffix): Handle VECTOR_TYPE like POINTER_TYPE.
+ * tree.c (walk_tree): Handle VECTOR_TYPE.
+
+ * decl.c (init_decl_processing): Call MD_INIT_BUILTINS.
+
+2000-10-21 Jason Merrill <jason@redhat.com>
+
+ * parse.y (operator): Set got_object from got_scope.
+ Set looking_for_typename.
+ * decl.c (lookup_name_real): Clear val after setting from_obj.
+ Reorganize diagnostic.
+
+2000-10-20 Jason Merrill <jason@redhat.com>
+
+ * tree.c (walk_tree): Don't walk into default args.
+
+ * error.c (dump_expr): Use host_integerp.
+
+2000-10-20 David Edelsohn <edelsohn@gnu.org>
+
+ * typeck2.c (abstract_virtuals_error): Use "because" instead of
+ "since" in error message.
+
+2000-10-20 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (dubious_conversion_warning): Suppress if TYPE_IS_SIZETYPE.
+
+2000-10-20 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * decl.c (revert_static_member_fn): Fixed typo.
+
+2000-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (subobject_offset_fn): New type.
+ (dfs_record_base_offsets): Remove.
+ (record_base_offsets): Likewise.
+ (dfs_search_base_offsets): Likewise.
+ (record_subobject_offset): New function.
+ (check_subobject_offset): Likewise.
+ (walk_subobject_offsets): Likewise.
+ (record_subobject_offsets): Likewise.
+ (layout_conflict_p): Reimplement.
+ (layout_nonempty_base_or_field): Correct handling of type
+ conflicts during layout.
+ (layout_empty_base): Likewise.
+ (build_base_field): Adjust to handle new representation of empty
+ base offset table.
+ (build_base_fields): Likewise.
+ (layout_virtual_bases): Likewise.
+ (splay_tree_compare_integer_csts): New function.
+ (layout_class_type): Use a splay_tree, rather than a varray, to
+ represent the offsets of empty bases.
+
+ * cp-tree.h (DECL_ANTICIPATED): Don't require a FUNCTION_DECL.
+ * decl.c (select_decl): Don't return declarations that are
+ DECL_ANTICIPATED.
+
+2000-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_FAKE_STD.
+ (fake_std_node): New macro.
+ * decl.c (in_std): Rename to ...
+ (in_fake_std): ... this.
+ (flag_no_builtin): Remove.
+ (flag_no_nonansi_builtin): Likewise.
+ (walk_namespaces_r): Use fake_std_node.
+ (push_namespace): Use std_identifier.
+ (pop_namespace): Use in_fake_std.
+ (lookup_name_real): Use fake_std_node.
+ (init_decl_processing): When -fhonor-std, create the `std'
+ namespace. Don't create a dummy fake_std_node in that case.
+ Adjust call to c_common_nodes_and_builtins. Use std_identifier.
+ (builtin_function): Put builtins whose names don't begin
+ with `_' in the std namespace.
+ * decl2.c (flag_no_builtin): Remove.
+ (flag_no_nonansi_builtin): Likewise.
+ (set_decl_namespace): Use fake_std_node.
+ (validate_nonmember_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (handle_class_head): Likewise.
+ * dump.c (dequeue_and_dump): Likewise.
+ * except.c (init_exception_processing): Use std_identifier.
+ * init.c (build_member_call): Use fake_std_node.
+ * rtti.c (init_rtti_processing): Use std_identifier.
+
+2000-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (back_end_hook): Remove declaration.
+ * decl2.c (back_end_hook): Remove definition.
+
+ * dump.c (dequeue_and_dump): Dump TREE_USED.
+
+2000-10-17 Brad Lucier <lucier@math.purdue.edu>
+
+ * spew.c (snarf_defarg): Cast 2nd arg to obstack_blank to (int).
+
+2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (WINT_TYPE): Define.
+ (init_decl_processing): Create types unsigned_ptrdiff_type_node,
+ c_size_type_node, signed_size_type_node and wint_type_node.
+
+2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (warn_missing_format_attribute): New variable.
+ (lang_decode_option): Decode -Wmissing-format-attribute.
+
+2000-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (qualify_type): Remove.
+ (composite_pointer_type): Fix handling of conversions to `cv void*'.
+
+2000-10-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.c, parse.h): Fix think-o in last patch.
+
+2000-10-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.c, parse.h): Create atomically.
+
+2000-10-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (current_obstack): Remove.
+ * decl.c (ggc_p): Remove.
+ (start_decl): Don't use decl_tree_cons.
+ (grokdeclarator): Don't use build_decl_list.
+ (start_function): Don't use decl_tree_cons.
+ (finish_function): Don't mess with obstacks.
+ * decl2.c (grok_x_components): Don't use build_decl_list.
+ * lex.c (make_call_declarator): Don't call decl_tree_cons.
+ (implicitly_declare_fn): Don't call build_decl_list.
+ * parse.y (frob_specs): Don't call build_decl_list or
+ decl_tree_cons.
+ (expr_or_declarator_intern): Don't call decl_tree_cons.
+ (primary): Don't call build_decl_list.
+ (fcast_or_absdcl): Likewise.
+ (typed_declspecs): Don't call decl_tree_cons.
+ (reserved_declspecs): Don't call build_decl_list.
+ (declmods): Likewise.
+ (reserved_typespecquals): Likewise.
+ (aggr): Likewise.
+ (new_type_id): Likewise.
+ (cv_qualifiers): Likewise.
+ (after_type_declarator_intern): Likewise.
+ (notype_declarator_intern): Likewise.
+ (absdcl_intern): Likewise.
+ (named_parm): Likewise.
+ * pt.c (most_specialized_class): Likewise.
+ * repo.c (temporary_obstack): Make it a structure, not a pointer.
+ (init_repo): Initialize it.
+ * search.c (current_obstack): Remove.
+ * typeck2.c (add_exception_specifier): Don't call build_decl_list.
+
+2000-10-09 Richard Henderson <rth@cygnus.com>
+
+ * Make-lang.in (CXX_EXTRA_HEADERS): Remove.
+ (c++ language support bits for libgcc): Remove.
+ (c++.clean): Remove cplib2.txt cleanup.
+ * config-lang.in (headers, lib2funcs): Remove.
+
+ * exception.cc, new.cc, new1.cc, new2.cc: Remove files.
+ * tinfo.cc, tinfo.h, tinfo2.cc, vec.cc: Remove files.
+ * inc/cxxabi.h, inc/exception, inc/new: Remove files.
+ * inc/new.h, inc/typeinfo: Remove files.
+
+2000-10-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
+ defined.
+ (init_decl_processing): Initialize intmax_type_node and
+ uintmax_type_node.
+
+2000-10-06 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (struct cp_language_function): Remove x_result_rtx.
+ (original_result_rtx): Remove.
+ * decl.c (save_function_data): Don't clear x_result_rtx.
+ (mark_lang_function): Don't mark it either.
+ * expr.c (fixup_result_decl): Remove.
+ * semantics.c (genrtl_named_return_value): Frob the return decl
+ before calling emit_local_var.
+ (genrtl_finish_function): Don't call fixup_result_decl.
+ Always emit the jump to return_label.
+
+2000-10-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Set current access for enum.
+ (tsubst_enum): Set file & line for enum decl.
+
+ * spew.c (yylex): Remove unused variable.
+
+2000-10-05 Richard Henderson <rth@cygnus.com>
+
+ * semantics.c (genrtl_finish_function): Don't init or check
+ can_reach_end; remove noreturn and return value checks.
+
+2000-10-05 Tom Tromey <tromey@cygnus.com>
+
+ * init.c (build_java_class_ref): Use `build_static_name' with a
+ suffix, not a prefix, to build the class object's name.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (access_kind): Fix comment typo.
+ * decl2.c (grokfield): Fix diagnostic typo.
+ * semantics.c (finish_template_type): Fix comment typo.
+ (finish_qualified_object_call_expr): Likewise.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_expr, DECL_STMT case): Don't process if
+ tsubsting fails.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (frob_id): New static function.
+ (frob_opname): Use it.
+ (yylex): Use it.
+
+2000-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lang_mark_false_label_stack): Remove.
+ * lex.c (cp_mang_lang_type): Use ggc_alloc_cleared.
+
+2000-09-30 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * gxxint.texi: Use @email for formatting email addresses.
+
+2000-09-29 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Remove direct obstack manipulation. Replace with
+ output_buffer-based formatting. Adjust calls to removed macros.
+ (obstack_chunk_alloc, obstack_chunk_free): Remove.
+ (OB_INIT, OB_PUTC, OB_PUTC2, OB_PUTS, OB_PUTID, OB_PUTCP,
+ OB_FINISH, OB_PUTI, OB_END_TEMPLATE): Likewise.
+
+2000-09-24 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Move to ../c-tree.texi.
+
+2000-09-20 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (get_guard): Check DECL_FUNCTION_SCOPE_P.
+
+2000-09-21 Andreas Jaeger <aj@suse.de>
+
+ * errfn.c: Move declaration of cp_printer and cp_printers to ...
+ * cp-tree.h: ... here.
+
+ * error.c: Remove declaration of cp_printer.
+
+2000-09-20 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (mark_local_for_remap_r): Handle CASE_LABELs.
+
+2000-09-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * except.c: Delete #if 0:d EXCEPTION_SECTION_ASM_OP-default and
+ users.
+
+2000-09-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_function): Robustify.
+
+2000-09-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (check_function_format): Accept a `status' parameter.
+
+ * call.c, typeck.c: Updates calls to `check_function_format'.
+
+2000-09-17 Geoffrey Keating <geoffk@cygnus.com>
+
+ * decl2.c (handle_class_head): Always push some scope even
+ in the error case.
+
+2000-09-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct cp_language_function): Remove
+ x_scope_stmt_stack and name_declared.
+ (current_scope_stmt_stack): Remove.
+ (function_name_declared_p): New macro.
+ (struct lang_decl_flags): Use c_lang_decl as a base class.
+ (context): Remove.
+ (struct lang_decl): Replace saved_tree with context.
+ (DECL_FRIEND_CONTEXT): Adjust accordingly.
+ (SET_DECL_FRIEND_CONTEXT): Likewise.
+ (DECL_VIRTUAL_CONTEXT): Likewise.
+ (DECL_SAVED_TREE): Remove.
+ (C_DECLARED_LABEL_FLAG): Likewise.
+ (cplus_expand_expr_stmt): Don't declare.
+ (add_decl_stmt): Likewise.
+ (add_scope_stmt): Likewise.
+ * decl.c (mark_stmt_tree): Remove.
+ (case_compare): Likewise.
+ (finish_case_label): Use c_add_case_label.
+ (init_decl_processing): Set more language-specific hooks.
+ (build_enumerator): Fix typo in comment.
+ (cplus_expand_expr_stmt): Remove.
+ (mark_lang_function): Use mark_c_language_function.
+ (lang_mark_tree): Use c_mark_lang_decl.
+ * decl2.c: Change order of inclusion.
+ * except.c: Likewise.
+ * expr.c (cplus_expand_expr): Remove handling of STMT_EXPR. Fall
+ back on c_expand_expr.
+ * friend.c: Include expr.h.
+ * init.c: Change order of inclusion.
+ * Makefile.in: Update dependencies.
+ * lex.h (free_lang_decl_chain): Remove.
+ * optimize.c (maybe_clone_body): Use function_name_declared_p.
+ * pt.c (build_template_decl): Don't copy DECL_VIRTUAL_CONTEXT if
+ it doesn't exist.
+ (instantiate_decl): Use function_name_declared_p.
+ * semantics.c (lang_expand_expr_stmt): Remove.
+ (set_current_function_name_declared): Likewise.
+ (current_function_name_declared): Likewise.
+ (begin_compound_stmt): Use function_name_declared_p.
+ (add_decl_stmt): Remove.
+ (setup_vtbl_ptr): Use function_name_declared_p.
+ (add_scope_stmt): Remove.
+ (current_scope_stmt_stack): New function.
+ (cp_expand_stmt): Don't handle SCOPE_STMTs.
+ (expand_body): Use function_name_declared_p.
+ * tree.c (cp_statement_code_p): Don't include SCOPE_STMT.
+ * typeck.c: Change order of includes.
+ (convert_sequence): Remove.
+
+2000-09-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lex.c (reswords): Add _Complex.
+
+2000-09-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (cplib2.txt): Depend on cp/Makefile.
+
+2000-09-13 J. David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * init.c (begin_init_stmts): Don't use // comments.
+
+2000-09-12 Jason Merrill <jason@redhat.com>
+
+ * decl.c (maybe_deduce_size_from_array_init): Set do_default for
+ all non-extern arrays.
+
+ * decl.c (grokdeclarator): Complain about 'friend T' for implicit
+ typenames, too. Downgrade complaint to pedwarn.
+ (xref_tag): Warn about surprising behavior of 'friend struct T'.
+ * decl2.c (handle_class_head): Generate a TYPENAME_TYPE for
+ 'class This::Inherited'.
+
+2000-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (finish_case_label): Given the LABEL_DECL a
+ DECL_CONTEXT.
+
+2000-09-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE,
+ TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPDEF,
+ TFF_DECL_SPECIFIERS, TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
+ TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
+ TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS, TFF_SCOPE):
+ New macros.
+ (sorry_for_unsupported_tree, print_scope_operator,
+ print_left_paren, print_right_paren, print_left_bracket,
+ print_right_bracket, print_whitespace): Likewise.
+ (aggr_variety): Rename to class_key_or_enum.
+ (print_type): Rename to print_type_id.
+ (print_type_specifier_seq, print_simple_type_specifier,
+ print_elaborated_type_specifier,
+ print_rest_of_abstract_declarator,
+ print_parameter_declaration_clause, print_exception_specification,
+ print_nested_name_specifier, print_template_id,
+ typedef_original_name, print_template_argument_list_start,
+ print_template_argument_list_end): New functions.
+
+2000-09-11 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Add more documentation.
+
+2000-09-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct saved_scope): Remove x_function_parms.
+ (current_function_parms): Don't define.
+ (struct cp_language_function): Remove parms_stored.
+ (current_function_just_assigned_this): Don't define.
+ (current_function_parms_stored): Likewise.
+ (static_ctors): Declare.
+ (static_dtors): Likewise.
+ (SF_EXPAND): Don't define.
+ (expand_start_early_try_stmts): Remove declaration.
+ (store_parm_decls): Likewise.
+ * decl.c (static_ctors): Don't declare.
+ (static_dtors): Likewise.
+ (struct binding_level): Remove this_block.
+ (poplevel): Remove dead code.
+ (set_block): Likewise.
+ (mark_binding_level): Don't mark this_block.
+ (mark_saved_scope): Don't mark x_function_parms.
+ (init_decl_processing): Don't add current_function_parms as a GC
+ root.
+ (check_function_type): Change prototype.
+ (start_function): Remove RTL-generation code.
+ (expand_start_early_try_stmts): Remove.
+ (store_parm_decls): Give it internal linkage. Remove
+ RTL-generation code.
+ (finish_function): Remove RTL-generation code.
+ * decl2.c (static_ctors): Fix formatting.
+ (static_dtors): Likewise.
+ * method.c (use_thunk): Don't call store_parm_decls.
+ (synthesize_method): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+ * parse.y (fn.def2): Likewise.
+ (.set_base_init): Likewise.
+ (nodecls): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (genrtl_try_block): Simplify.
+ (expand_body): Use genrtl_start_function and
+ genrtl_finish_function.
+ (genrtl_start_function): New function.
+ (genrtl_finish_function): Likewise.
+
+2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (cp_tree_printer, case 'P'): Append break.
+
+2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (frob_opname): Declare.
+ * parse.y (saved_scopes): New static variable.
+ (cp_parse_init): Adjust.
+ (do_id): If lastiddecl is NULL, do do_identifier.
+ (operator): Save scope information.
+ (unoperator): New reduction. Restore scope information.
+ (operator_name): Append unoperator. Call frob_opname.
+ * spew.c (frob_opname): Define.
+
+2000-09-10 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl.c, rtti.c: Include defaults.h if not already included.
+ Don't define the *_TYPE_SIZE macros.
+
+2000-09-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (push_switch): Change prototype.
+ (check_cp_case_value): Remove declaration.
+ (decl_constant_value): Likewise.
+ * decl.c (struct cp_switch): Add switch_stmt and cases.
+ (case_compare): New function.
+ (push_switch): Set switch_stmt. Initialize cases.
+ (pop_switch): Clean up cases.
+ (define_case_label): Rename to ...
+ (finish_case_label): ... this. Do semantic analysis for case
+ labels here.
+ (start_function): Correct comment.
+ * decl2.c (check_cp_case_value): Remove.
+ * expr.c (do_case): Remove.
+ * pt.c (tsubst_expr): Adjust call to finish_case_label.
+ * semantics.c (genrtl_do_poplevel): Remove declaration.
+ (RECHAIN_STMTS): Remove.
+ (finish_break_stmt): Use build_break_stmt.
+ (finish_continue_stmt): Use build_continue_stmt.
+ (finish_switch_cond): Adjust condition here, rater than in
+ c_expand_start_case.
+ (finish_case_label): Remove.
+ * typeck.c (c_expand_return): Remove.
+ (c_expand_start_case): Likewise.
+
+2000-09-07 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Document type nodes.
+
+2000-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (init_cp_semantics): Declare.
+ (genrtl_try_block): Don't declare.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_named_return_value): Likewise.
+ * lex.c (init_parse): Call init_cp_semantics.
+ * semantics.c (genrtl_try_block): Give it internal linkage.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (lang_expand_stmt): Rename to ...
+ (cp_expand_stmt): ... this. Only handle C++-specific nodes.
+ (init_cp_semantics): Define.
+
+ * decl.c (initialize_local_var): Remove RTL-generating code.
+ * semantics.c (genrtl_try_block): Fix formatting.
+
+ Move statement-tree facilities from C++ to C front-end.
+ * cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
+ (void_zero_node): Remove.
+ (stmt_tree): Likewise.
+ (scope_chain): Adjust.
+ (language_function): Rename to cp_language_function.
+ (cp_function_chain): Adjust.
+ (current_stmt_tree): Remove.
+ (last_tree): Likewise.
+ (last_expr_type): Likewise.
+ (struct lang_decl): Adjust.
+ (STMT_IS_FULL_EXPR_P): Remove.
+ (add_tree): Remove.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (walk_tree_fn): Likewise.
+ (walk_stmt_tree): Likewise.
+ * class.c (finish_struct): Replace use of add_tree with add_stmt.
+ * decl.c (mark_stmt_tree): Adjust type.
+ (init_decl_processing): Don't build void_zero_node.
+ (initialize_local_var): Adjust usage of current_stmt_tree.
+ (finish_enum): Use add_stmt, not add_tree.
+ (save_function_data): Adjust use of language_function.
+ (finish_constructor_body): Use add_stmt, not add_tree.
+ (finish_destructor_body): Likewise.
+ (push_cp_function_context): Adjust use of language_function.
+ (pop_cp_function_context): Likewise.
+ (mark_lang_function): Likewise.
+ (mark_cp_function_context): Likewise.
+ * init.c (build_aggr_init): Adjust use of current_stmt_tree.
+ (build_vec_init): Likewise.
+ * semantics.c (SET_LAST_STMT): Remove.
+ (RECHAIN_STMTS): Don't use it.
+ (stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
+ (current_stmt_tree): Define.
+ (add_tree): Remove.
+ (finish_goto_stmt): Use add_stmt, not add_tree.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_while_stmt): Likewise.
+ (begin_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_case_label): Likewise.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (begin_handler): Likewise.
+ (begin_catch_block): Likewise.
+ (begin_compound_stmt): Likewise.
+ (begin_asm_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (setup_vtbl_ptr): Likewise.
+ (add_scope_stmt): Likewise.
+ (finish_stmt_expr): Likewise.
+ (prune_unused_decls): Remove.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (prep_stmt): Adjust use of current_stmt_tree.
+ (lang_expand_stmt): Likewise.
+ * tree.c (statement_code_p): Remove.
+ (cp_statement_code_p): New function.
+ (walk_stmt_tree): Remove.
+ (init_tree): Set lang_statement_code_p.
+
+2000-09-06 Zack Weinberg <zack@wolery.cumb.org>
+
+ Integrated preprocessor.
+
+ * Make-lang.in, Makefile.in: Remove all references to input.c,
+ gxx.gperf, and hash.h. Add ../c-lex.o to C_OBJS.
+ * gxx.gperf, hash.h, input.c: Delete.
+ * lang-specs.h: Pass -lang-c++ to cc1plus so cpplib is
+ initialized properly.
+
+ * class.c (fixup_pending_inline): Take a tree, not a
+ struct pending_inline *. All callers changed.
+ (init_class_processing): Set RID_PUBLIC, RID_PRIVATE,
+ RID_PROTECTED entries in ridpointers[] array here.
+ * decl.c (duplicate_decls): Do not refer to struct
+ pending_inline.
+ (record_builtin_type, init_decl_processing): Use RID_MAX not
+ CP_RID_MAX.
+ (grokdeclarator): Use C_IS_RESERVED_WORD.
+ * decl2.c (lang_decode_option): Ignore -lang-c++ for sake of
+ cpplib.
+ (grok_x_components): Do not inspect pending_inlines chain.
+
+ * cp-tree.h (struct lang_identifier): Add rid_code entry.
+ (C_IS_RESERVED_WORD, C_RID_CODE, C_RID_YYCODE): New.
+ (flag_no_gnu_keywords, flag_operator_names, rid_to_yy): Declare.
+ (DEFARG_LENGTH, struct pending_inline, TIME_IDENTIFIER_TIME,
+ TIME_IDENTIFIER_FILEINFO): Kill.
+ Update prototypes.
+ * lex.h: Expunge cp_rid. Rewrite RIDBIT macros to use just a
+ single 32-bit word.
+ * parse.y: Call do_pending_inlines unconditionally.
+ reinit_parse_for_method is now snarf_method. fn.defpen is no
+ longer necessary. Remove unnecessary <itype> annotation on
+ SCOPE. Do not refer to end_of_file or struct pending_inline.
+ * semantics.c (begin_inline_definitions): Call
+ do_pending_inlines unconditionally.
+
+ * lex.c: Remove all code now shared with C front end.
+ Initialize cpplib properly if USE_CPPLIB. Put reserved words
+ into the get_identifier table. Rewrite pragma handling to
+ work with the registry. Move code to save tokens for later
+ processing to spew.c.
+
+ * spew.c: Rewrite everything in terms of token streams instead
+ of text. Move routines here from lex.c / input.c as
+ appropriate. GC-mark trees hanging off the pending inlines
+ chain.
+
+2000-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Mention that the named return value extension has been
+ deprecated.
+ * cp-tree.h (original_result_rtx): Define.
+ (TREE_REFERENCE_EXPR): Remove.
+ (DECL_VPARENT): Likewise.
+ (pushdecl_nonclass_level): Likewise.
+ (store_return_init): Likewise.
+ (reinit_lang_specific): Likewise.
+ (genrtl_named_return_value): Change prototype.
+ * decl.c (original_result_rtx): Remove.
+ (cp_finish_decl): Don't build DECL_STMTs for RESULT_DECLs.
+ Do not generate RTL for local variables here.
+ (store_return_init): Remove.
+ * semantics.c (genrtl_named_return_value): Simplify. Fold in
+ store_return_init.
+ (finish_named_return_value): Adjust accordingly. Warn that this
+ extension is deprecated.
+ (lang_expand_stmt): Adjust call to genrtl_named_return_value.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (type_unification_real): Replace switch with if.
+ (unify): Tsubst non-type parms before comparing.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_typename): New function, broken out of ...
+ (dump_type): ... here. Use it.
+ * typeck.c (same_type_p): Use cp_tree_equal for TYPENAME_TYPE.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_offset_ref): Deal with namespace scoped
+ TEMPLATE_ID_EXPRs.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (resolve_address_of_overloaded_function): Add
+ explanation message.
+ * decl.c (define_case_label): Reformat explanation.
+ * decl2.c (finish_static_data_member_decl): Likewise.
+ (grokfield): Likewise.
+ * friend.c (do_friend): Likewise.
+
+2000-09-05 Zack Weinberg <zack@wolery.cumb.org>
+
+ * tree.c (walk_tree): Expose tail recursion.
+ (walk_stmt_tree): New function.
+ * cp-tree.h: Prototype walk_stmt_tree.
+ * semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not
+ the BLOCKs directly. If a BLOCK has no variables after
+ pruning, discard it.
+ (finish_stmt_tree): Use walk_stmt_tree. No need to save and
+ restore the line number.
+
+2000-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (CXX_TREE_H): Add dependency on HTAB_H.
+ (pt.o): Remove dependency on HTAB_H.
+ * cp-tree.h: Include hashtab.h.
+ (walk_tree): Change prototype.
+ (walk_tree_without_duplicates): New function.
+ * decl.c (check_default_argument): Use it.
+ * optimize.c (remap_decl): Adjust calls to walk_tree.
+ (copy_body): Likewise.
+ (expand_calls_inline): Likewise.
+ (calls_setjmp_p): Use walk_tree_without_duplicates.
+ * pt.c: Don't include hashtab.h.
+ (for_each_template_parm): Use walk_tree_without_duplicates.
+ * semantics.c (finish-stmt_tree): Likewise.
+ (expand_body): Likewise.
+ * tree.c (walk_tree): Add additional parameter.
+ (walk_tree_without_duplicates): New function.
+ (count_trees): Use it.
+ (verify_stmt_tree): Adjust call to walk_tree.
+ (find_tree): Use walk_tree_without_duplicates.
+ (no_linkage_check): Likewise.
+ (break_out_target_exprs): Adjust call to walk_tree.
+ (cp_unsave): Likewise.
+
+2000-09-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
+ (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+ * cp-tree.h (TYPE_BINFO): Adjust comment.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
+ (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+ (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+ (TYPE_TEMPLATE_INFO): Likewise.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
+ * class.c (push_nested_class): Likewise.
+ * decl.c (lookup_name_real): Likewise.
+ (grokdeclarator): Likewise.
+ (grok_op_properties): Likewise.
+ (xref_tag): Likewise.
+ (xref_basetypes): Likewise.
+ * decl2.c (constructor_name_full): Likewise.
+ (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
+ (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+ * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
+ (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (dump_type_suffix): Likewise.
+ * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
+ instead.
+ (get_aggr_from_typedef): Likewise.
+ * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
+ (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (write_template_parm): Likewise.
+ (write_template_template_parm): Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ * method.c (build_overload_nested_name): Add
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
+ * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (convert_template_argument): Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
+ (for_each_template_parm): Adjust comment.
+ (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize.
+ (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize. Use
+ template_args_equal to compare template template parameter cases.
+ * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
+ instead.
+ * tree.c (copy_template_template_parm): Decide whether to create
+ a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
+ (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (copy_tree_r): Likewise.
+ * typeck.c (comptypes): Likewise. Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+
+2000-09-04 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * decl.c (finish_function): Move the code for handling functions
+ marked with the constructor and destructor attributes inside the
+ expand_p block.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (resolve_offset_ref): Deal with TEMPLATE_ID_EXPR.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Remove abort.
+ * tree.c (get_type_decl): Allow error_mark_node.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (arg_assoc): Deal with COMPONENT_REFs inside
+ TEMPLATE_ID_EXPRs.
+
+2000-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ * operators.def (ALIGNOF_EXPR, MAX_EXPR, MIN_EXPR): Change
+ new ABI mangling.
+
+2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (named_class_head): Check for TYPENAME_TYPE. Simplify
+ union tag mismatch error reporting.
+
+2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_scoped_method_call): Check it is not a namespace.
+
+2000-08-30 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (LOCAL_CLASS_P): Use decl_function_context.
+
+ * tree.c (bot_manip): Check TREE_CONSTANT rather than
+ !TREE_SIDE_EFFECTS. Call break_out_target_exprs and
+ build_target_expr_with_type for the non-AGGR_INIT_EXPR case.
+
+ * decl.c (start_function): Always call make_function_rtl.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * semantics.c (prune_unused_decls): New function.
+ (finish_stmt_tree): Call it via walk_tree.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * class.c (build_secondary_vtable): Constify a char *.
+ * decl.c (init_decl_processing): Initialize function_id_node,
+ pretty_function_id_node, and func_id_node.
+ * input.c (struct input_source): Constify 'str'.
+ (feed_input): Constify first argument.
+ * mangle.c (write_identifier): Constify argument.
+ * pt.c (mangle_class_name_for_template): Constify argument.
+
+2000-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (mark_addressable): Remove code that pokes around in
+ RTL.
+
+2000-08-28 Jason Merrill <jason@redhat.com>
+
+ * lex.c (file_name_nondirectory): Move to toplev.c.
+
+ * cp-tree.h (LOCAL_CLASS_P): New macro.
+ * class.c (finish_struct_1): Use it.
+
+2000-08-27 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo.
+ (write_encoding): Pass another argument to write_name.
+ (write_name): Add ignore_local_scope parameter. Fix handling of
+ local names.
+ (write_nested_name): Use write_unqualified_name.
+ (write_prefix): Likewise. Skip out on FUNCTION_DECLs.
+ (write_template_prefix): Use write_unqualified_name.
+ (write_component): Remove.
+ (write_local_name): Add parameter. Use direct local entity to
+ discriminator calculation.
+ (write_class_enum_type): Pass another argument to write_name.
+ (write_template_template_arg): Likewise.
+ (make_guard_variable): Likewise.
+
+2000-08-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (pushdecl): Matching decls for local externs are found in
+ the current level. Propagate linkage information from previous
+ declarations.
+
+2000-08-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi (Expressions): Fix typo.
+
+2000-08-25 Greg McGary <greg@mcgary.org>
+
+ * tree.c (init_tree): Use ARRAY_SIZE.
+
+2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_tree_printer): Rework.
+
+2000-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Remove cp-demangle.o and
+ dyn-string.o.
+ (CXX_LIB2SRCS): Remove cp-demangle.c and dyn-string.c.
+ (cp-demangle.o): Remove target.
+ (dyn-string.o): Likewise.
+
+ * decl.c (grokfndecl): Require that `main' return an `int'.
+ * mangle.c (write_encoding): Don't mangle return types for
+ conversion functions.
+
+2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (tree_formatting_info): New data type.
+ (tree_being_formatted): New macro.
+ (tree_formatting_flags): Likewise.
+ (put_whitespace): Likewise.
+ (print_tree_identifier): Likewise.
+ (print_identifier): Likewise.
+ (cp_tree_printer, print_function_argument_list, print_declaration,
+ print_expression, print_function_declaration,
+ print_function_parameter, print_type, print_cv_qualifier): New
+ functions.
+ (init_error): Initialize lang_printer.
+
+2000-08-24 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_ptrmemfunc): Just reinterpret if there's no
+ adjustment necessary.
+
+2000-08-24 Greg McGary <greg@mcgary.org>
+
+ * cp-tree.h (MAIN_NAME_P): Remove macro.
+
+2000-08-24 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (print_instantiation_context): Don't forget to flush the
+ buffer.
+
+2000-08-23 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_ptrmemfunc): Save the input pmf.
+
+ * method.c (process_modifiers): Use same_type_p.
+
+2000-08-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CLONED_FUNCTION_P): Check DECL_LANG_SPECIFIC.
+ * mangle.c (write_function_type): Change prototype.
+ (write_encoding): Don't mangle return types for
+ constructors or destructors.
+ (write_type): Adjust call to write_function_type.
+ * pt.c (instantiate_template): Instantiate alternate entry points
+ when instantiating the main function.
+
+2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_print_error_function): Don't use embedded '\n' in
+ output_printf.
+
+2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl.c (init_decl_processing): Remove bogus initialization.
+ * error.c (lang_print_error_function): Restore here.
+ (init_error): Initialize print_error_function.
+
+2000-08-22 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (arg_assoc): Revert my 2000-08-11 change.
+
+2000-08-22 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Makefile.in (error.o): Depends on diagnostic.h
+
+ * cp-tree.h (problematic_instantiation_changed,
+ record_last_problematic_instantiation, current_instantiation,
+ print_instantiation_context): Declare.
+ (maybe_print_template_context): Remove.
+
+ * decl.c (init_decl_processing): Set print_error_function to NULL.
+ (lang_print_error_function): Remove, since we're using a new
+ machinery.
+
+ * error.c: #include diagnostic.h
+ (function_category): New function.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (maybe_print_instantiation_context): Likewise.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (print_instantiation_context): Define.
+ (init_error): Initialize diagnostic pager and finalizer.
+
+ * pt.c (problematic_instantiation_changed): Define.
+ (record_last_problematic_instantiation): Likewise.
+ (current_instantiation): Likewise.
+ (maybe_print_template_context): Remove.
+ (print_template_context): Likewise.
+ (current_tinst_level): Make static to reflect Brendan Kehoe's
+ change of 1995-04-13.
+ (push_tinst_level): Call print_instantiation_context.
+
+2000-08-21 Nix <nix@esperi.demon.co.uk>
+
+ * lang-specs.h: Do not process -o or run the assembler if
+ -fsyntax-only.
+
+2000-08-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (flag_hosted, flag_noniso_default_format_attributes): New
+ variables.
+ * decl2.c (lang_decode_option): Disable gettext attributes for
+ -ansi.
+
+2000-08-21 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (lang_init_options): Default diagnostic message maximum
+ length to 80, when line-wrapping.
+
+2000-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Clear the entire
+ vtbl_init_data. Start keeping track of the functions for which we
+ have created vcall offsets here.
+ (dfs_build_vcall_offset_vtbl_entries): Remove.
+ (build_vcall_offset_vtbl_entries): Reimplement.
+ (add_vcall_offset_vtbl_entries_r): New function.
+ (add_vcall_offset_vtbl_entries_1): Likewise. Tweak logic for
+ computing when vcall offsets are necessary.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (member_function_or_else): Use cp_error ... %T.
+ (grokdeclarator): Likewise.
+ (start_method): Likewise.
+ * friend.c (make_friend_class): Use cp_pedwarn ... %T.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (grokfield): Set CLASSTYPE_GOT_SEMICOLON on class
+ TYPE_DECLs.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (PTRMEM_OK_P): New macro.
+ (itf_ptrmem_ok): New enumeration value.
+ * class.c (resolve_address_of_overloaded_function): Add PTRMEM
+ argument. Diagnose implicit pointer to member.
+ (instantiate_type): Don't diagnose implicit pointer to member
+ here. Pass itf_ptrmem_ok if ok. Adjust calls to
+ resolve_address_of_overloaded_function.
+ * init.c (build_offset_ref): Set PTRMEM_OK_P.
+ (resolve_offset_ref): Don't diagnose implicit pointer to member here.
+ * semantics.c (finish_parenthesized_expr): Clear OFFSET_REFs here.
+ * typeck.c (build_x_unary_op): Calculate PTRMEM_OK_P.
+ (build_unary_op): Deal with single non-static member in
+ microsoft-land.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (arg_assoc_type): Cope with TYPENAME_TYPE.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum_name_string): Remove prototype.
+ (report_case_error): Remove prototype.
+ * cp/typeck2.c (enum_name_string): Remove.
+ (report_case_error): Remove.
+ * error.c (dump_expr): Deal with enum values directly.
+ Correctly negate integer constant.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare.
+ (__cxa_vec_delete2, __cxa_vec_delete3): Declare.
+ * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement.
+ (__cxa_vec_delete2, __cxa_vec_delete3): Implement.
+ (__cxa_vec_new): Use __cxa_vec_new2.
+ (__cxa_vec_delete): Use __cxa_vec_delete2.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc (__cxa_vec_new): Set "C" linkage.
+ (__cxa_vec_ctor): Likewise.
+ (__cxa_vec_cctor): Likewise.
+ (__cxa_vec_dtor): Likewise.
+ (__cxa_vec_delete): Likewise.
+ * inc/cxxabi.h (__cxa_vec_new): Set "C" linkage.
+ (__cxa_vec_ctor): Likewise.
+ (__cxa_vec_cctor): Likewise.
+ (__cxa_vec_dtor): Likewise.
+ (__cxa_vec_delete): Likewise.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (instantiate_type): Reinstate local variable
+ deleted in previous change.
+
+ * cvt.c (cp_convert_to_pointer): Pass itf_complain, not
+ itf_no_attributes.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (instantiate_type_flags): New enumeration.
+ (instantiate_type): Change parameter.
+ * class.c (instantiate_type): Adjust prototype. Adjust.
+ * call.c (standard_conversion): Adjust instantiate_type call.
+ (reference_binding): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ * typeck.c (build_binary_op): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTR_AGGR_TAG): New global tree node.
+ (current_aggr): Define.
+ * decl.c (grokdeclarator): Make sure a friend class is an
+ elaborated type specifier.
+ * parse.y (current_aggr): Remove static definition.
+ (cp_parse_init): Adjust.
+ (structsp): Clear and restore current_aggr.
+ (component_decl_list): Clear current_aggr.
+
+ * error.c (dump_type, case TYPENAME_TYPE): Don't emit the
+ aggregate tag on the typename's context.
+
+ * pt.c (tsubst_friend_class): Return error_mark_node, if
+ parms becomes NULL.
+ (instantiate_class_template): Ignore error_mark_node friend types.
+
+2000-08-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (warn_ref_binding): New static function, broken out of ...
+ (convert_to_reference): ... here. Use it.
+
+2000-08-11 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * parse.y (template_arg): Add rule for template qualified with
+ global scope.
+
+2000-08-11 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (add_function): Reorganize.
+ (arg_assoc): Do not consider function template decls.
+
+2000-08-11 Jason Merrill <jason@redhat.com>
+
+ * decl.c (lookup_name_real): Don't forget the TYPENAME_TYPE we're
+ looking inside.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (resolve_scope_to_name): Remove unused prototype.
+ (lookup_nested_tag): Likewise.
+
+ * decl2.c (grokfield): Fix comment to reflect many types of _DECLs
+ can be produced.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (named_complex_class_head_sans_basetype): Remove
+ always true if.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Build
+ explicit TEMPLATE_ID_EXPR args.
+ (build_expr_from_tree, case CALL_EXPR): Likewise.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (check_tag_decl): Diagnose typename's which don't
+ declare anything.
+
+2000-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_aggr_init): Reject bogus array initializers
+ early.
+
+2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (build_dynamic_cast_1): Set "C" linkage for new abi
+ runtime.
+ * cp/tinfo.cc (__dynamic_cast): Likewise.
+ * cp/inc/cxxabi.h (__dynamic_cast): Likewise.
+
+2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (convert_to_pointer_force): Fix error message when
+ attempting to cast from ambiguous base.
+
+2000-08-08 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_aggr_type): Bail if creating the argvec fails.
+ (tsubst_template_arg_vector): Likewise.
+
+ * decl2.c (build_anon_union_vars): Choose the largest field; don't
+ assume that one will be as large as the union.
+
+2000-08-07 Kazu Hirata <kazu@hxi.com>
+
+ * cp-tree.h (CLASSTYPE_HAS_PRIMARY_BASE_P): Fix a comment typo.
+ * decl.c (pop_labels): Likewise.
+
+2000-08-04 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * inc/cxxabi.h (__pbase_type_info): Changed member names to match
+ specifications.
+ (__pointer_to_member_type_info): Likewise.
+ (__base_class_info): Likewise.
+ (__class_type_info): Likewise.
+ (__si_class_type_info): Likewise.
+ (__vmi_class_type_info): Likewise.
+ * tinfo.cc (__si_class_type_info::__do_find_public_src):
+ Changed member names to match specifications.
+ (__vmi_class_type_info::__do_find_public_src): Likewise.
+ (__si_class_type_info::__do_dyncast): Likewise.
+ (__vmi_class_type_info::__do_dyncast): Likewise.
+ (__si_class_type_info::__do_upcast): Likewise.
+ (__vmi_class_type_info::__do_upcast): Likewise.
+ * tinfo2.cc (__pbase_type_info::__do_catch): Likewise.
+ (__pbase_type_info::__pointer_catch): Likewise.
+ (__pointer_type_info::__pointer_catch): Likewise.
+ (__pointer_to_member_type_info::__pointer_catch): Likewise.
+
+2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (cc1plus): Depend on $(BACKEND), not stamp-objlist.
+ * Makefile.in: Add C_OBJS, BACKEND; delete OBJS, OBJDEPS.
+ (cc1plus): Link with $(BACKEND) and $(C_OBJS).
+
+2000-08-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (add_method): Change prototype.
+ * class.c (add_method): Remove FIELDS parameter. Add ERROR_P.
+ Don't double the size of the method vector in the error case.
+ (handle_using_decl): Adjust call to add_method.
+ (add_implicitly_declared_members): Likewise.
+ (clone_function_decl): Likewise.
+ * decl2.c (check_classfn): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+
+2000-08-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (flag_isoc94): New variable.
+
+2000-08-02 Jason Merrill <jason@redhat.com>
+
+ * pt.c (do_type_instantiation): Add complain parm; don't complain
+ if called recursively.
+ * cp-tree.h, parse.y: Adjust.
+
+2000-08-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl2.c: Silently ignore -Wstrict-prototypes; warn about
+ -Wno-strict-prototypes.
+
+ * g++spec.c: Adjust type of second argument to
+ lang_specific_driver, and update code as necessary.
+
+ * cp-tree.h: Don't prototype min_precision here.
+ (my_friendly_assert): Cast expression to void.
+ * semantics.c (do_poplevel): Initialize scope_stmts.
+
+2000-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak.
+
+2000-07-28 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Use %i in rule for .ii files.
+
+2000-07-31 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Rename cpp to cpp0 and/or tradcpp to tradcpp0.
+
+2000-07-30 Mark Mitchell <mark@codesourcery.com>
+
+ Allow indirect primary bases.
+ * cp-tree.h (struct lang_type): Remove vfield_parent. Add
+ primary_base.
+ (CLASSTYPE_VFIELD_PARENT): Remove.
+ (CLASSTYPE_PRIMARY_BINFO): Reimplement.
+ (BINFO_PRIMARY_BINFO): Remove.
+ (CLASSTYPE_HAS_PRIMARY_BASE_P): Reimplement.
+ (BINFO_VBASE_PRIMARY_P): Likewise.
+ (BINFO_PRIMARY_BASE_OF): New macro.
+ (BINFO_INDIRECT_PRIMARY_P): Likewise.
+ (get_primary_binfo): New function.
+ * decl.c (lang_mark_tree): Make lang_type::primary_base.
+ * class.c (vcall_offset_data_s): Rename to ...
+ (vtbl_init_data_s): ... this. Rename primary_p to primary_vtbl_p,
+ and add ctor_vtbl_p.
+ (get_derived_offset): Use get_primary_binfo.
+ (dfs_mark_primary_bases): Adjust handling of virtual primary
+ bases.
+ (mark_primary_bases): Likewise.
+ (set_primary_base): Take a binfo, not an integer, as a
+ representation of the primary base.
+ (indirect_primary_base_p): Remove.
+ (determine_primary_base): Adjust for indirect primary bases.
+ (dfs_find_final_overrider): Fix typo in coment.
+ (update_vtable_entry_for_fn): Use get_primary_binfo.
+ (layout_nonempty_base_or_field): Tweak.
+ (build_base_fields): Adjust for new primary base semantics.
+ (dfs_propagate_binfo_offsets): Remove.
+ (propagate_binfo_offsets): Rewrite.
+ (dfs_set_offset_for_shared_vbases): Remove.
+ (layout_virtual_bases): Don't use it.
+ (layout_class_type): Set CLASSTYPE_SIZE correctly under the new
+ ABI.
+ (finish_struct_1): Set CLASSTYPE_PRIMARY_BINFO, not
+ CLASSTYPE_VFIELD_PARENT.
+ (dfs_get_primary_binfo): New function.
+ (get_primary_binfo): Likewise.
+ (dump_class_hierarchy_r): Tweak printing of primary bases.
+ (build_vtbl_initializer): Fix typo in comments. Use
+ vtbl_init_data.
+ (build_vcall_and_vbase_vtbl_entries): Likewise.
+ (build_vbaes_offset_vtbl_entries): Likewise.
+ (dfs_build_vcall_offset_vtbl_entries): Adjust setting of
+ BV_VCALL_INDEX to handle indirect primary bases.
+ (build_vcall_offset_vtbl_entries): Use vtbl_init_data.
+ (build_rtti_vtbl_entries): Likewise.
+ * search.c (get_shared_vbase_if_not_primary): Tweak.
+ (find_vbase_instance): Likewise.
+ (binfo_for_vtable): Simplify.
+ * tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF.
+ (make_binfo): Make it have 11 entries.
+
+2000-07-30 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (DECL_TEMPLATE_ID_P): Remove.
+ (CLASSTYEP_TEMPLATE_ID_P): Check template info, and context when
+ ascertaining primaryness.
+ (G): Remove template_args.
+ (decl_is_template_id): New function.
+ (write_encoding): Use decl_is_template_id.
+ (write_name): Likewise. Handle type_decls. Get main variant of
+ type decls.
+ (write_nested_name): Likewise.
+ (write_prefix): Likewise.
+ (write_template_prefix): Likewise.
+ (write_special_name_constructor): Remove defunct production from
+ comment.
+ (write_bare_function_type): Remove comment about absent parameter.
+ (write_template_template_arg): Add missing grammar production to
+ comment.
+
+2000-07-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (duplicate_decls): If common_type produces a non-typedef
+ type for a typedef, just use the old type.
+
+2000-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (function_depth): Declare.
+ (verify_stmt_tree): Likewise.
+ (find_tree): Likewise.
+ * decl.c (function_depth): Give it external linkage.
+ * optimize.c (optimize_function): Increment and decrement it.
+ * tree.c (verify_stmt_tree_r): New function.
+ (verify_stmt_tree): Likewise.
+ (find_tree_r): Likewise.
+ (find_tree): Likewise.
+
+2000-07-27 Jason Merrill <jason@redhat.com>
+
+ * pt.c (for_each_template_parm_r, case RECORD_TYPE): Use
+ TYPE_PTRMEMFUNC_P.
+ * cp-tree.h (TYPE_TEMPLATE_INFO): Check for TYPE_LANG_SPECIFIC.
+
+2000-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_cleanup_fn): Mark the function as `inline'.
+ * decl2.c (get_guard): Call cp_finish_decl, not
+ rest_of_decl_compilation, for local guards.
+ * lex.c (do_identifier): Remove unused variable.
+
+2000-07-26 Marc Espie <espie@cvs.openbsd.org>
+
+ * parse.y: Add missing ';'.
+
+2000-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y (empty_parms): Use `()', not `(...)', when in the scope
+ of `extern "C++"'.
+
+2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill strict_prototype. Backwards compatibility only for
+ non NO_IMPLICIT_EXTERN_C systems.
+ * cp-tree.h (flag_strict_prototype): Remove.
+ (strict_prototype): Remove.
+ (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
+ * decl.c (maybe_push_to_top_level): Adjust.
+ (pop_from_top_level): Adjust.
+ (decls_match): Only allow sloppy parm matching for ancient
+ system headers.
+ (init_decl_processing): Adjust.
+ (grokdeclarator): Adjust.
+ * decl2.c (flag_strict_prototype): Remove.
+ (strict_prototype): Remove.
+ (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
+ (lang_f_options): Remove "strict-prototype".
+ (unsupported-options): Add "strict-prototype".
+ * lex.c (do_identifier): Adjust.
+ (do_scoped_id): Adjust.
+ * parse.y (empty_parms): Adjust.
+ * class.c (push_lang_context): Adjust.
+ (pop_lang_context): Adjust.
+ * typeck.c (comp_target_parms): Adjust.
+
+2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (poplevel): Deal with anonymous variables at for scope.
+ (maybe_inject_for_scope_var): Likewise.
+
+2000-07-25 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl.c: Remove all signal handling code, now done in toplev.c.
+
+2000-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Rework.
+
+ * pt.c (lookup_template_class): Ensure that TYPE_CONTEXT is set
+ correctly.
+
+2000-07-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Use __FUNCTION__ not __PRETTY_FUNCTION__.
+ Define my_friendly_assert and my_friendly_abort as macros
+ which may call friendly_abort. Prototype friendly abort, not
+ my_friendly_abort or my_friendly_assert.
+ * decl.c (signal_catch): Report the signal caught in the error
+ message. Call fatal directly.
+ * typeck2.c (ack, my_friendly_assert): Delete.
+ (my_friendly_abort): Rename to friendly_abort. Expect file,
+ line, and function parameters. Report the abort code, then
+ call fancy_abort. Do not mask an abort if errors have
+ already occurred.
+
+2000-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (comp_target_parms): Remove obsolete parameter.
+ (comp_target_types): Adjust.
+
+2000-07-17 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (mark_addressable): Never set TREE_USED.
+ * call.c (build_call): Don't abort on calls to library functions
+ that have been declared normally.
+
+ * typeck.c (build_binary_op): Fix grammar in warning.
+
+ * exception.cc (__eh_free): Fix prototype.
+
+ * decl2.c (finish_decl_parsing): Handle TEMPLATE_ID_EXPR.
+
+ * decl.c (pushdecl): Handle seeing an OVERLOAD in
+ IDENTIFIER_NAMESPACE_VALUE.
+
+2000-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (THUNK_VCALL_OFFSET): Update documentation.
+ * method.c (use_thunk): Correct handling of vcall offsets.
+
+2000-07-14 Zack Weinberg <zack@wolery.cumb.org>
+
+ * .cvsignore: parse.h and parse.c have no cp- prefix.
+
+2000-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ * .cvsignore: New file.
+
+2000-07-13 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Use the new named specs. Remove unnecessary braces.
+
+2000-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(PARSE_H)): Depend directly on parse.y.
+ * parse.c: Remove.
+ * parse.h: Likewise.
+
+2000-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Add pointers to virtual bases after
+ base classes under the old ABI.
+
+2000-07-10 Benjamin Chelf <chelf@codesourcery.com>
+
+ * semantics.c (finish_for_stmt): Remove call to emit_line_note.
+ (finish_continue_stmt): Likewise.
+ (begin_for_stmt): Remove call to note_level_for_for.
+ (finish_goto_stmt): Change call from build_min_nt
+ to build_stmt.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_case_label): Likewise.
+ (genrtl_try_block): Likewise.
+ (begin_try_block): Likewise.
+ (begin_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (setup_vtbl_ptr): Likewise.
+ (add_scope_stmt): Likewise.
+ * decl.c (finish_constructor_body): Likewise.
+ (finish_destructor_body): Likewise.
+ * optimize.c (copy_body_r): Likewise.
+ (initialize_inlined_parameters): Likewise.
+ (declare_return_variable): Likewise.
+ (expand_call_inline): Likewise.
+
+2000-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (expand_body): Sync interface information
+ at the end of function body expansion.
+
+2000-07-09 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Bail early if the call to new fails.
+
+ * decl.c (compute_array_index_type): Check specifically for
+ an INTEGER_CST, not just TREE_CONSTANT.
+
+ * decl.c (duplicate_decls): Don't call duplicate_decls on
+ the DECL_TEMPLATE_RESULT.
+ (decls_match): Return 0 if the DECL_TEMPLATE_RESULTs have different
+ codes.
+
+ * error.c (dump_template_bindings): Don't crash if we had an
+ invalid argument list.
+
+ * typeck.c (c_expand_start_case): Do narrowing here.
+ * semantics.c (finish_switch_cond): Not here.
+
+2000-07-09 Hidvegi Zoli <hzoli@austin.ibm.com>
+
+ * parse.y (asm_clobbers): Do string concatenation.
+
+2000-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushtag): Don't put local classes in template functions
+ on the local_classes list.
+
+2000-07-04 Scott Snyder <snyder@fnal.gov>
+
+ * decl2.c (get_guard): Add missing return for old ABI local
+ variable case.
+
+2000-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (char_type_p): New function.
+ * decl.c (init_decl_processing): Don't initialize
+ signed_wchar_type_node or unsigned_wchar_type_node.
+ (complete_array_type): Handle brace-enclosed string-constants.
+ * rtti.c (emit_support_tinfos): Remove #if 0'd code.
+ * tree.c (char_type_p): New function.
+ * typeck2.c (digest_init): Use char_type_p.
+
+2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst): Don't layout type, if it's error_mark.
+
+2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_pending_templates): Reset template level.
+
+2000-07-05 Jason Merrill <jason@redhat.com>
+
+ * call.c (joust): Don't complain about `operator char *()' beating
+ `operator const char *() const'.
+
+2000-07-04 scott snyder <snyder@fnal.gov>
+ Jason Merrill <jason@redhat.com>
+
+ * repo.c (repo_get_id): Handle the case where a class with virtual
+ bases has a null TYPE_BINFO_VTABLE.
+
+2000-07-04 Kevin Buhr <buhr@stat.wisc.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * parse.y (member_init): Just pass in the type.
+ * init.c (expand_member_init): Handle getting a type.
+
+2000-07-04 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+ Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_function): Warn if a function has no return
+ statement.
+ Suggested by Andrew Koenig.
+ * typeck.c (check_return_expr): Do set current_function_returns_value
+ if we got an error_mark_node.
+
+2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (push_decl_namespace): Push the original namespace.
+
+2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_class_template): Set CLASSTYPE_VBASECLASSES.
+ * semantics.c (begin_class_definition): Clear it.
+
+2000-07-02 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (genrtl_goto_stmt): Remove declaration.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+
+ * init.c (begin_init_stmts): Remove call to
+ genrtl_begin_compound_stmt.
+ (finish_init_stmts): Remove call to genrtl_finish_compound_stmt.
+
+ * semantics.c (lang_expand_stmt): Changed call to
+ genrtl_compound_stmt to ignore return value.
+
+2000-07-02 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (canonicalize_for_substitution): Return the canonical
+ variant of a type.
+
+ * decl.c (duplicate_decls): Preserve DECL_ORIGINAL_TYPE for a
+ TYPE_DECL.
+ * typeck.c (commonparms): Remove obstack manipulations.
+
+2000-07-01 Benjamin Chelf <chelf@codesourcery.com>
+
+ * Make-lang.in (cc1plus$(exeext)): Added c-semantics.o.
+
+ * Makefile.in (OBJS): Added ../c-semantics.o.
+ (OBJDEPS): Likewise.
+
+ * cp-tree.h (TREE_LANG_FLAG_?): Moved common documentation to
+ ../c-common.h.
+ (struct stmt_tree): Added comment.
+ (current_function_name_declared): Removed.
+ (stmts_are_full_exprs_p): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (COMPOUND_STMT_NO_SCOPE): Moved to ../c-common.h.
+ (DECL_ANON_UNION_ELEMS): Likewise.
+ (emit_local_var): Likewise.
+ (make_rtl_for_local_static): Likewise.
+ (do_case): Likewise.
+ (expand_stmt): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (c_expand_asm_operands): Likewise.
+ (c_expand_return): Likewise.
+ (c_expand_start_case): Likewise.
+
+ * decl.c (make_rtl_for_local_static): Moved to c-semantics.c.
+ (emit_local_var): Likewise.
+ (initialize_local_var): Change reference to
+ stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
+ Change reference to stmts_are_full_exprs_p to
+ current_stmt_tree->stmts_are_full_exprs_p.
+ (push_cp_function_context): Likewise.
+
+ * expect.c (expand_throw): Change reference to
+ stmts_are_full_exprs_p.
+
+ * init.c (build_aggr_init): Change reference to
+ stmts_are_full_exprs_p.
+ (build_vec_init): Likewise.
+
+ * optimize.c (maybe_clone_body): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared.
+
+ * pt.c (instantiate_decl): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared.
+
+ * semantics.c (expand_cond): Moved declaration to c-common.h.
+ (genrtl_do_pushlevel): Moved to c-semantics.c.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (gerntl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (expand_cond): Likewise.
+ (expand_stmt): Renamed to ...
+ (lang_expand_stmt): ... this.
+ (lang_expand_expr_stmt): Initialize.
+ (set_current_function_name_declared): Likewise.
+ (stmts_are_full_exprs_p): Likewise.
+ (current_function_name_declared): Likewise.
+ (anon_aggr_type_p): Likewise.
+ (do_poplevel): Change reference to
+ stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
+ Change reference to stmts_are_full_exprs_p to
+ current_stmt_tree->stmts_are_full_exprs_p.
+ (add_tree): Likewise.
+ (finish_expr_stmt): Likewise.
+ (prep_stmt): Likewise.
+ (lang_expand_stmt): Likewise.
+ (begin_compound_stmt): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared and call to
+ current_function_name_declared().
+ (setup_vtbl_ptr): Likewise.
+ (genrtl_do_poplevel): Removed.
+
+2000-06-30 Jason Merrill <jason@redhat.com>
+
+ * init.c (init_init_processing): Go back to aligning like
+ double_type_node for old ABI.
+ (get_cookie_size): Make cookie larger if we get a type that needs
+ more alignment.
+ (build_vec_delete): Call it.
+
+ * typeck.c (qualify_type_recursive): New fn.
+ (composite_pointer_type): Use it.
+ (build_binary_op): Use composite_pointer_type.
+
+2000-06-24 Carlos O'Ryan <coryan@cs.wustl.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * typeck.c (check_return_expr): Don't complain about returning
+ NULL from operator new if -fcheck-new.
+ * cp-tree.h: Declare flag_check_new here.
+ * init.c: Not here.
+
+2000-06-28 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (find_substitution): Use same_type_p.
+ (write_encoding): Don't check for substitutions.
+
+2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (expr_no_comma_rangle): New non-terminal.
+ (template_parm): Use it for default parameter case.
+ (template_arg): Use it.
+ (expr_no_commas): Remove commented out undefined extensions.
+ * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
+ * parse.h, parse.c: Rebuilt.
+
+2000-06-30 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (genrtl_asm_stmt): Don't decay input operands here.
+ (finish_asm_stmt): Do it here, instead.
+
+ * cp-tree.h (ridpointers): Don't declare.
+ * decl.c (record_builtin_type): Use CP_RID_MAX instead of RID_MAX.
+ (record_builtin_java_type): Likewise.
+ (init_decl_processing): Likewise.
+ * lex.c: Move inclusion of lex.h.
+ (ridpointers): Don't define.
+ (init_parse): Initialize ripdointers. Use CP_RID_MAX instead of
+ RID_MAX.
+ * lex.h (enum rid): Rename to ...
+ (enum cp_rid): ... this.
+ (ridpointers): Don't declare.
+ * parse.y: Move inclusion of lex.h.
+ * parse.c: Regenerated.
+ * spew.c: Move inclusion of lex.h.
+
+ * cp-tree.h (struct language_function): Remove temp_name_counter.
+ (temp_name_counter): Remove.
+ (get_temp_name): Change prototype.
+ (get_guard): New function.
+ (get_guard_cond): Likewise.
+ (set_guard): Likewise.
+ * cvt.c (build_up_reference): Adjust call to get_temp_name.
+ * decl.c (expand_static_init): Use get_guard and friends to
+ implement guard variables.
+ * decl2.c (get_temp_name): Assume that the variables created are
+ always static.
+ (get_sentry): Rename to ...
+ (get_guard): ... this. Implement new ABI guard variables.
+ (get_guard_bits): New function.
+ (get_guard_cond): Likewise.
+ (set_guard): Likewise.
+ (start_static_initialization_or_destruction): Use them.
+ (do_static_initialization): Replace sentry with guard throughout.
+ (do_static_destruction): Likewise.
+ * init.c (create_temporary_var): Add comment.
+
+2000-06-28 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (find_substitution): Use same_type_p.
+ (write_encoding): Don't check for substitutions.
+
+2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (expr_no_comma_rangle): New non-terminal.
+ (template_parm): Use it for default parameter case.
+ (template_arg): Use it.
+ (expr_no_commas): Remove commented out undefined extensions.
+ * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
+ * parse.h, parse.c: Rebuilt.
+
+2000-06-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (flag_const_strings): Remove.
+ (warn_parentheses): Likewise.
+ (warn_format): Likewise.
+ (common_type): Likewise.
+ (default_conversion): Likewise.
+ (build_binary_op): Likewise.
+ (cp_build_binary_op): New macro.
+ * call.c (build_new_op): Use cp_build_binary_op instead of
+ build_binary_op.
+ * class.c (build_vtable_entry_ref): Likewise.
+ * decl.c (expand_static_init): Likewise.
+ (compute_array_index_type): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ (start_static_initialization_or_destruction): Likewise.
+ * error.c (dump_type_suffix): Likewise.
+ * init.c (resolve_offset_ref): Likewise.
+ (build_new): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_vec_init): Likewise.
+ (build_delete): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ * typeck.c (build_array_ref): Likewise.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_binary_op): Add parameter.
+ (pointer_int_sum): Use cp_build_binary_op.
+ (pointer_diff): Likewise.
+ (build_modify_expr): Likewise.
+ (get_delta_difference): Likewise.
+ (build_ptrmemfunc): Likewise.
+
+2000-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (SET_DECL_ARTIFICIAL): Remove.
+ * decl.c (create_implicit_typedef): Adjust.
+ * decl2.c (build_artificial_parm): Adjust.
+ * method.c (implicitly_declare_fn): Adjust.
+ * pt.c (push_inline_template_parms_recursive): Adjust.
+ (process_template_parm): Adjust.
+ (overloaded_template_name): Adjust.
+ * semantics.c (finish_template_template_parm): Adjust.
+
+2000-06-28 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
+ * class.c (update_vtable_entry_for_fn): Correct logic for deciding
+ where to emit thunks.
+ (build_vtt): Adjust call to build_vtt_inits.
+ (build_vtt_inits): Add parameter to indicate whether or not
+ sub-VTTs for virtual bases should be included. Adjust handling of
+ construction vtables.
+ (get_matching_base): New function.
+ (dfs_build_vtt_inits): Rename to ...
+ (dfs_build_secondary_vptr_vtt_inits): Adjust handling of
+ construction vtables.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_groups): Build construction vtables for virtual
+ bases, too.
+ (accumulate_vtbl_inits): Tweak logic for deciding whether or not
+ to build construction vtbls.
+ (dfs_accumulate_vtbl_inits): Adjust handling of
+ construction vtables.
+
+ * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
+ types correctly.
+
+2000-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokfndecl): Set DECL_CONTEXT for static functions too.
+
+2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (hides): Remove.
+ (is_subobject_of_p): Add most_derived parameter. Use
+ CANONICAL_BINFO.
+ (lookup_field_queue_p): Adjust.
+ (lookup_field_r): Adjust.
+
+2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (handle_class_head): Bash typedefs to the type's main
+ decl.
+
+2000-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (genrtl_begin_stmt_expr): Rename to ...
+ (begin_global_stmt_expr): ... this.
+ (genrtl_finish_stmt_expr): Rename to ...
+ (finish_global_stmt_expr): ... this.
+ * init.c (begin_init_stmts): Adjust calls.
+ (finish_init_stmts): Likewise.
+ * semantics.c (genrtl_begin_stmt_expr): Rename to ...
+ (begin_global_stmt_expr): ... this.
+ (genrtl_finish_stmt_expr): Rename to ...
+ (finish_global_stmt_expr): ... this.
+
+2000-06-25 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * search.c (lookup_member): Fix typo in comment.
+
+2000-06-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c (pushdecl): Don't set DECL_CONTEXT from current_namespace.
+ (push_namespace): Set DECL_CONTEXT for a new NAMESPACE_DECL.
+
+2000-06-24 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (complex_direct_notype_declarator): Support global_scope.
+ * Makefile.in: Adjust conflict count.
+
+2000-06-23 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * parse.y (template_arg): Convert TEMPLATE_DECL
+ that is a template template parameter to
+ TEMPLATE_TEMPLATE_PARM here.
+
+ * cp-tree.def (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+ * cp-tree.h (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): New macro.
+ (copy_template_template_parm): Adjust prototype.
+ * decl.c (grokdeclarator): Remove dead code.
+ * pt.c (process_template_parm): Tidy.
+ (lookup_template_class): Construct nodes in
+ copy_template_template_parm.
+ (tsubst): Pass TEMPLATE_DECL rather than IDENTIFIER_NODE to
+ lookup_template_class. Use TYPE_TI_TEMPLATE.
+ * tree.c (copy_template_template_parm): Add NEWARGS
+ parameter.
+ (mapcar): Adjust call to copy_template_template_parm.
+ * typeck.c (comptypes): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL.
+ * method.c (build_template_template_parm_names): Change error
+ code to avoid compilation warning.
+
+ * gxxint.texi: Document template template parameter
+ name mangling.
+
+2000-06-21 Alex Samuel <samuel@codesourcery.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Add cp-demangle.o and dyn-string.o.
+ (CXX_LIB2SRCS): Add cp-demangle.c and dyn-string.c.
+ (cp-demangle.o): New rule.
+ (dyn-string.o): Likewise.
+ * inc/cxxabi.h (__cxa_demangle): New declaration.
+
+2000-06-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BV_USE_VCALL_INDEX_P): New macro.
+ (BV_GENERATE_THUNK_WITH_VTABLE_P): Likewise.
+ (lang_decl_flags): Add generate_with_vtable_p. Make vcall_offset
+ a tree, not an int.
+ (THUNK_GENERATE_WITH_VTABLE_P): New macro.
+ (make_thunk): Change prototype.
+ (emit_thunk): Rename to use_thunk.
+ (mangle_thunk): Change prototype.
+ * class.c (get_derived_offset): Simplify.
+ (copy_virtuals): Clear BV_USE_VCALL_INDEX_P and
+ BV_GENERATE_THUNK_WITH_VTABLE_P.
+ (build_primary_vtable): Simplify.
+ (add_virtual_function): Use BV_FN, rather than TREE_VALUE.
+ (dfs_find_base): Remove.
+ (update_vtable_entry_for_fn): Correct bug in finding the base
+ where a virtual function was first declared. Figure out whether
+ or not to emit a vcall-thunk with the vtables in which it appears.
+ Correct logic for deciding whether to use an ordinary thunk, or a
+ vcall thunk.
+ (finish_struct_1): Remove unnecssary code.
+ (build_vtbl_initializer): Use ssize_int for the running counter of
+ negative indices.
+ (build_vtbl_initializer): Only use vcall thunks where necessary.
+ Mark thunks as needing to be emitted with their vtables, or not.
+ (build_vbase_offset_vtbl_entries): Adjust for use of ssize_int in
+ indices. Use size_binop.
+ (dfs_build_vcall_offset_vtbl_entries): Don't rely on
+ BINFO_PRIMARY_MARKED_P here. Use BV_FN consistently. Use
+ size_binop.
+ (build_rtti_vtbl_entries): Adjust call to build_vtable_entry.
+ (build_vtable_entry): Mark thunks as needing to be emitted with
+ their vtables, or not.
+ * decl.c (lang_mark_tree): Mark the vcall_offset in a thunk.
+ * decl2.c (mark_vtable_entries): Use use_thunk instead of
+ emit_thunk.
+ * dump.c (dequeue_and_dump): Remove dead code. Dump new thunk
+ information.
+ * error.c (dump_expr): Use BV_FN.
+ * mangle.c (mangle_thunk): Adjust now that vcall_offset is a tree,
+ not an int.
+ * method.c (make_thunk): Likewise.
+ (emit_thunk): Rename to use_thunk. Allow callers to decide
+ whether or not to actually emit the thunk. Adjust for changes in
+ representation of vcall offsets.
+ * search.c (dfs_get_pure_virtuals): Use BV_FN.
+ * semantics.c (emit_associated_thunks): New function.
+ (expand_body): Use it.
+ * ir.texi: Adjust descriptions of thunks.
+
+2000-06-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl, case FUNCTION_DECL): Clear DECL_SAVED_TREE.
+ (tsubst_friend_function): Copy it here.
+
+ * decl.c (grok_op_properties): Fix typo.
+
+ * decl2.c (delete_sanity): Clarify warning, avoid failure on
+ deleting void*.
+
+ * pt.c (check_explicit_specialization): Clarify error.
+
+ * decl.c (pushdecl): Also pull out one of the FUNCTION_DECLs from
+ an old OVERLOAD when we're declaring a non-function.
+ (pushdecl, destroy_local_var): Check for error_mark_node.
+ (warn_extern_redeclared_static): Also bail early if
+ we're a CONST_DECL.
+ (push_overloaded_decl): Ignore an old error_mark_node.
+
+2000-06-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_x_va_arg): Check if in a template decl.
+ * pt.c (tsubst_copy, case VA_ARG_EXPR): Use build_x_va_arg.
+
+2000-06-20 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (push_lang_context): TYPE_NAME gets you to the Java
+ types DECLs.
+ * decl.c (check_goto): Computed gotos assumed OK.
+
+2000-06-20 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl, case TYPE_DECL): Fix test for TYPE_DECLs
+ for which we don't need to look for instantiations.
+
+2000-06-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (program): Always call finish_translation_unit.
+ * parse.c, parse.h: Rebuilt.
+
+2000-06-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * method.c: Don't include hard-reg-set.h.
+
+2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_base_offset): Cope when vbase field is in a base.
+
+2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_conditional_expr): Use VOID_TYPE_P.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_void): Likewise.
+ * error.c (dump_expr): Likewise.
+ * except.c (complete_ptr_ref_or_void_ptr_p): Likewise.
+ * init.c (build_delete): Likewise.
+ * method.c (emit_thunk): Likewise.
+ * optmize.c (declare_return_variable): Likewise.
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+ (get_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (composite_pointer_type): Likewise.
+ (common_type): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_binary_op): Likewise.
+ (build_x_compound_expr): Likewise.
+ (check_return_expr): Likewise.
+ * typeck2.c (add_exception_specifier): Likewise.
+
+ * mangle.c (write_method_parms): Use direct comparison for end
+ of parmlist.
+
+2000-06-19 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (genrtl_try_block): Declare function.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (genrtl_begin_stmt_expr): Likewise.
+ (genrtl_finish_stmt_expr): Likewise.
+ (finish_for_stmt): Removed first argument.
+ (finish_switch_stmt): Likewise.
+
+ * semantics.c (genrtl_try_block): Define function.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (genrtl_begin_stmt_expr): Likewise.
+ (genrtl_finish_stmt_expr): Likewise.
+ (finish_for_stmt): Removed first argument and generate rtl
+ specific code.
+ (finish_switch_stmt): Likewise.
+ (do_poplevel): Removed generate rtl specific code.
+ (do_pushlevel): Likewise.
+ (add_tree): Likewise.
+ (finish_goto_stmt): Likewise.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (finish_if_stmt_cond): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_else_clause): Likewise.
+ (finish_else_clause): Likewise.
+ (finish_if_stmt): Likewise.
+ (clear_out_block): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt_cond): Likewise.
+ (finish_while_stmt): Likewise.
+ (begin_do_stmt): Likewise.
+ (finish_do_body): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_init_stmt): Likewise.
+ (finish_for_cond): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_switch_cond): Likewise.
+ (finish_case_label): Likewise.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (finish_try_block): Likewise.
+ (finish_cleanup_try_block): Likewise.
+ (finish_cleanup): Likewise.
+ (finish_function_try_block): Likewise.
+ (finish_handler_sequence): Likewise.
+ (finish_function_handler_sequence): Likewise.
+ (begin_handler): Likewise.
+ (finish_handler_parms): Likewise.
+ (begin_catch_block): Likewise.
+ (finish_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (finish_label_decl): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (begin_stmt_expr): Likewise.
+ (finish_stmt_expr): Likewise.
+
+ * decl.c (initialize_local_var): Changed call to finish_expr_stmt
+ to call genrtl_expr_stmt when appropriate.
+
+ * init.c (begin_init_stmts): Changed calls to begin_stmt_expr and
+ begin_compound_expr to call genrtl_begin_stmt_expr and
+ genrtl_begin_compound_expr when appropriate.
+ (finish_init_stmts): Changed calls to finish_compound_expr and
+ finish_stmt_expr to call genrtl_finish_compound_expr and
+ genrtl_finish_stmt_expr when appropriate.
+ (expand_default_init): Changed call to finish_expr_stmt to call
+ genrtl_expr_stmt when appropriate.
+ (build_vec_init): Likewise.
+
+ * parse.y (simple_stmt): Removed first argument from call to
+ finish_for_stmt. Removed first argument from call to
+ finish_switch_stmt.
+
+ * parse.c: Regenerated.
+
+ * pt.c (tsubst_expr): Removed first argument from call to
+ finish_for_stmt. Removed first argument from call to
+ finish_switch_stmt.
+
+2000-06-16 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (enum cplus_tree_code): Changed __DUMMY to
+ CP_DUMMY_TREE_CODE. Remove #include "c-common.def".
+
+ * lex.c (cplus_tree_code_type[]): Removed #include "c-common.def".
+ (cplus_tree_code_length[]): Likewise.
+ (cplus_tree_code_name[]): Likewise.
+ (init_parse): Added call to add_c_tree_codes. Changed
+ LAST_AND_UNUSED_TREE_CODE to LAST_C_TREE_CODE.
+
+2000-06-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_mem_initializers): Declare.
+ (count_trees): Likewise.
+ * parse.y (base_init): Use finish_mem_initializers.
+ * semantics.c (finish_mem_initializers): New function.
+
+ * tree.c (count_trees_r): Prototype. Use DATA parameter to store
+ the number of trees.
+ (n_trees): Remove.
+ (count_trees): Don't use it.
+
+2000-06-15 Jason Merrill <jason@redhat.com>
+
+ * tree.c (count_trees): New debugging function.
+
+ * typeck.c (build_x_function_call): Use DECL_FUNCTION_TEMPLATE_P.
+ * init.c (build_member_call): Pull out the name of a DECL.
+
+ * Makefile.in (semantics.o, pt.o): Depend on TIMEVAR_H.
+ * semantics.c (expand_body): Push to TV_INTEGRATION here.
+ * optimize.c (optimize_function): Not here.
+ * pt.c (instantiate_decl): Push to TV_PARSE.
+
+2000-06-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct language_function): Remove x_base_init_list
+ and x_member_init_list.
+ (current_base_init_list): Remove.
+ (current_member_init_list): Likewise.
+ (setup_vtbl_ptr): Change prototype.
+ (emit_base_init): Likewise.
+ (expand_member_init): Likewise.
+ (reinit_parse_for_function): Remove.
+ * decl.c (save_function_data): Don't clear x_base_init_list and
+ x_member_init_list.
+ (mark_language_function): Don't mark them.
+ * init.c (perform_member_init): Tweak comment.
+ (sort_member_init): Take the list of initializers as an argument.
+ (sort_base_init): Likewise.
+ (emit_base_init): Likewise.
+ (expand_member_init): Return the initializer. Don't use global
+ variables.
+ * lex.c (reinit_parse_for_function): Remove.
+ * method.c (build_template_parm_names): Correct substitution.
+ (do_build_copy_constructor): Don't use current_member_init_list
+ and current_base_init_list.
+ (synthesize_method): Likewise.
+ * parse.y (base_init): Split mem-initializers into
+ base-initializers and field-initializers.
+ (member_init_list): Build up the list here.
+ (member_init): Return the initializer.
+ (fn.depfn): Don't use reinit_parse_for_function.
+ * parse.c: Regenerated.
+ * pt.c (convert_nontype_argument): Don't make an ADDR_EXPR of the
+ ERROR_MARK.
+ (tsubst_expr): Don't use current_member_init_list
+ and current_base_init_list.
+ (tsubst_expr_values): Rename to ...
+ (tsubst_initializer_list): ... this. Use convert_from_reference.
+ * semantics.c (setup_vtbl_ptr): Don't use current_member_init_list
+ and current_base_init_list.
+ (begin_function_definition): Don't call reinit_parse_for_function.
+
+ * dump.c (dequeue_and_dump): Use TREE_VEC_LENGTH with vectors.
+
+ * error.c (dump_expr): Handle ADDR_EXPRs with REFERENCE_TYPE
+ correctly.
+
+ * cp-tree.h (DECL_PENDING_INLINE_P): Relax checking.
+
+2000-06-14 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (IF_COND): Move to c-common.h.
+ (THEN_CLAUSE): Likewise.
+ (ELSE_CLAUSE): Likewise.
+ (WHILE_COND): Likewise.
+ (WHILE_BODY): Likewise.
+ (DO_COND): Likewise.
+ (DO_BODY): Likewise.
+ (RETURN_EXPR): Likewise.
+ (EXPR_STMT_EXPR): Likewise.
+ (FOR_INIT_STMT): Likewise.
+ (FOR_COND): Likewise.
+ (FOR_EXPR): Likewise.
+ (FOR_BODY): Likewise.
+ (SWITCH_COND): Likewise.
+ (SWITCH_BODY): Likewise.
+ (CASE_LOW): Likewise.
+ (CASE_HIGH): Likewise.
+ (GOTO_DESTINATION): Likewise.
+ (COMPOUND_BODY): Likewise.
+ (ASM_CV_QUAL): Likewise.
+ (ASM_STRING): Likewise.
+ (ASM_OUTPUTS): Likewise.
+ (ASM_INPUTS): Likewise.
+ (ASM_CLOBBERS): Likewise.
+ (DECL_STMT_DECL): Likewise.
+ (STMT_EXPR_STMT): Likewise.
+ (LABEL_STMT_LABEL): Likewise.
+ (SCOPE_BEGIN_P): Likewise.
+ (SCOPE_END_P): Likewise.
+ (SCOPE_STMT_BLOCK): Likewise.
+ (SCOPE_NULLIFIED_P): Likewise.
+ (SCOPE_NO_CLEANUPS_P): Likewise.
+ (SCOPE_PARTIAL_P): Likewise.
+ (ASM_VOLATILE_P): Likewise.
+ (STMT_LINENO): Likewise.
+ (STMT_LINENO_FOR_FN_P): Likewise.
+
+ * cp-tree.def: Removed SRCLOC, SIZEOF_EXPR, ARROW_EXPR,
+ ALIGNOF_EXPR, EXPR_STMT, COMPOUND_STMT, DECL_STMT, IF_STMT,
+ FOR_STMT, WHILE_STMT, DO_STMT, RETURN_STMT, BREAK_STMT,
+ CONTINUE_STMT, SWITCH_STMT, GOTO_STMT, LABEL_STMT, ASM_STMT,
+ SCOPE_STMT, CASE_LABEL, STMT_EXPR.
+
+ * Makefile.in (CXX_TREE_H): Added $(srcdir)/../c-common.def.
+
+ * Make-lang.in (CXX_SRCS): Added $(srcdir)/c-common.def.
+ (cc1plus$(exeext)): Added $(srcdir)/c-common.def.
+
+ * lex.c (cplus_tree_code_type[]): Added '#include "c-common.def"'.
+ (cplus_tree_code_length[]): Added '#include "c-common.def"'.
+ (cplus_tree_code_name[]): Added '#include "c-common.def"'.
+
+2000-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH): New macro.
+ * class.c (dfs_find_final_overrider): Set it appropriately.
+ (dfs_built_vtt_inits): Check BINFO_OVERRIDE_ALONG_VIRTUAL_PATH to
+ avoid unneeded secondary vptrs.
+
+2000-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ * class.c (build_secondary_vtable): Set DECL_USER_ALIGN.
+ (check_bitfield_decl, check_field_decl): Likewise.
+ (build_vtbl_or_vbase_field, build_base_field): Likewise.
+ (layout_class_type): Set DECL_USER_ALIGN resp. CLASSTYPE_USER_ALIGN.
+ * decl.c (record_unknown_type): Set TYPE_USER_ALIGN.
+ (xfer_tag, finish_enum): Likewise.
+ * decl2.c (finish_builtin_type): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ * rtti.c (get_tinfo_decl, synthesize_tinfo_fn): Set DECL_USER_ALIGN.
+ * cp-tree.h (struct lang_type): Add user_align member.
+ (CLASSTYPE_USER_ALIGN): Define.
+
+2000-06-13 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * Make-lang.in (c++.install-common): Install g++-cross in
+ $(gcc_tooldir)/bin as g++ and c++; g++ in $(bindir) as
+ $(target_alias)-g++ and $(target_alias)-c++.
+
+2000-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (vcall_offset_data_s): Add last_init and fns.
+ (overrides): Rename to same_signature_p.
+ (dfs_find_final_overrider): Adjust accordingly.
+ (mark_overriders): Likewise.
+ (warn_hidden): Likewise.
+ (build_vtbl_initializer): Reorganize machinery for building things
+ at negative offsets.
+ (build_vcall_and_vbase_vtbl_entries): Likewise.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (dfs_build_vcall_offset_vtbl_entries): Correct order of vcall
+ offset entries. Do not create two entries for functions with the
+ same signature.
+ (build_vcall_offset_vtbl_entries): Initialize vod->fns.
+ (build_rtti_vtbl_entries): Reorganize machinery for building things
+ at negative offsets.
+
+ * optimize.c (expand_call_inline): Don't recurse into the code
+ used to initialize the parameters more than once.
+
+2000-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.
+ (is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here.
+ (find_substitution): Only use the `Sa' substitution for
+ std::allocator, not instantiations of it.
+ (write_template_prefix): Move comment. Only use a TREE_LIST to
+ represent substitutions for a member template.
+ (write_array_type): Mangle array dimensions correctly.
+ * optimize.c (maybe_clone_body): Copy more information from the
+ cloned function.
+ * pt.c (regenerate_decl_from_template): Preserve DECL_USE_TEMPLATE
+ on the regenerated declaration.
+
+2000-06-11 Chip Salzenberg <chip@valinux.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable): Clarify comment.
+ (build_ctor_vtbl_group): Pass the most derived type to
+ build_vtable.
+
+2000-06-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (compare_options): Don't needlessly cast away const-ness.
+
+2000-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (add_binding): Handle duplicate declarations of external
+ variables.
+
+2000-06-09 Chip Salzenberg <chip@valinux.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
+ argument.
+ (write_signed_number): New macro.
+ (write_unsigned_number): Likewise.
+ (write_source_name): Use them.
+ (write_number): Handle signed and unsigned values.
+ (write_integer_cst): Use tree_int_cst_sgn, and use
+ write_unsigned_number or write_signed_number as appropriate.
+ (write_discriminator): Use write_unsigned_number or
+ write_signed_number as appropriate.
+ (write_template_arg_literal): Likewise.
+ (write_array_type): Use tree_low_cst.
+ (write_template_parm): Use write_unsigned_number or
+ write_signed_number as appropriate.
+ (write_substitution): Adjust call to write_number.
+ (write_type): Get the TYPE_MAIN_VARIANT before mangling it.
+ (write_expression): Handle non-type template arguments of
+ reference type correctly.
+ (mangle_thunk): Use write_signed_number.
+
+2000-06-09 Chip Salzenberg <chip@valinux.com>
+
+ * mangle.c (find_substition): Don't mangle objects with typename
+ substitutions (e.g. "cin" as "Si").
+
+2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * call.c (add_candidate): Use ggc_alloc_cleared.
+ * decl.c (lookup_label): Likewise.
+ * lex.c (retrofit_lang_decl): Likewise.
+
+2000-06-09 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * semantics.c (expand_body): Push to TV_EXPAND.
+ * optimize.c (optimize_function): Push to TV_INTEGRATION.
+ * decl.c (start_function): Always call announce_function.
+
+ * tinfo2.cc: Just declare abort.
+
+2000-06-09 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (DEF_OPERATOR): Say `operator@' -not- `operator @'
+ whenever @ is a symbolic name.
+
+2000-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (make_thunk): Clear DECL_VTT_PARM in thunk.
+
+2000-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl): Look up functions by DECL_NAME, not
+ DECL_ASSEMBLER_NAME.
+
+2000-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (c_language): Define.
+
+2000-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (lang_init_options): Tweak.
+
+ * decl2.c: Remove #inclusion of diagnostic.h
+ (lang_decode_option): Move diagnostic formatting options to
+ toplevel.
+
+ * lang-options.h: Remove documentation for diagnostic options.
+
+ * Makefile.in (lex.o): Depends upon diagnostic.h
+
+2000-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (redeclaration_error_message): If two TEMPLATE_DECLs have
+ the same DECL_RESULT, it's not a redefinition.
+ * pt.c (tsubst_decl): Remove code to handle illegal
+ specializations.
+
+2000-06-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * exception.cc: (__eh_alloc, __eh_free): Moved to libgcc2.c
+
+2000-06-05 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * search.c (maybe_suppress_debug_info): Don't check
+ CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set.
+
+ * pt.c (mark_decl_instantiated): Do SET_DECL_EXPLICIT_INSTANTIATION
+ here if extern_p.
+
+ Remember instantiation context in deferred instantiations.
+ * cp-tree.h (struct tinst_level): Remove.
+ (TINST_DECL, TINST_LINE, TINST_FILE): New macros.
+ * pt.c (current_tinst_level): Now a tree.
+ (print_template_context, push_tinst_level, pop_tinst_level,
+ tinst_for_decl): Adjust.
+ (reopen_tinst_level): New fn.
+ (init_pt): Register current_tinst_level as a root.
+ (add_pending_template): Put current_tinst_level in TREE_PURPOSE
+ of the pending templates list.
+ (instantiate_pending_templates): Adjust. Call reopen_tinst_level.
+ * lex.c (extract_interface_info): Adjust.
+ * decl2.c (warn_if_unknown_interface): Adjust.
+
+2000-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (indirect_primary_base_p): New function.
+ (determine_primary_base): Use it.
+
+2000-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Update new-abi dynamic cast algorithm.
+ * tinfo.cc (__class_type_info::__dyncast_result): Add
+ whole_details. Adjust constructor.
+ (__vmi_class_type_info::__do_dyncast): Adjust for vmi_flags.
+ Avoid unnecessary searching.
+ (__dynamic_cast): Adjust for __dyncast_result::whole_details.
+
+2000-06-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (init_decl_processing): Don't call record_component_aliases.
+ * tree.c (build_cplus_array_type_1): Likewise.
+
+2000-06-04 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Correct typo.
+ * mangle.c (write_expression): Handle non-type template arguments
+ with reference type.
+ * method.c (build_overload_value): Likewise.
+ * pt.c (convert_nontype_argument): Explicitly represent conversion
+ to a reference with an ADDR_EXPR.
+ (unify): Always unify arguments in left-to-right order.
+
+2000-06-03 Alex Samuel <samuel@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_SRCS): Add mangle.c.
+ * Makefile.in (CXX_OBJS): Add mangle.o.
+ (mangle.o): New rule.
+
+ * class.c (local_classes): New variable.
+ * class.c (get_vtable_name): Use mangle_vtable_for_type for new ABI.
+ (get_vtt_name): Use mangle_vtt_name for new ABI.
+ (init_class_processing): Initialize local_classes.
+ (build_ctor_vtbl_group): Use mangle_ctor_vtbl_for_type for new ABI.
+ * cp-tree.h (cp_tree_index): Add CPTI_STD_IDENTIFIER.
+ (std_identifier): New macro.
+ (DECL_VOLATILE_MEMFUNC_P): New macro.
+ (DECL_NAMESPACE_STD_P): Likewise.
+ (local_classes): Declare.
+ (get_mostly_instantiated_function_type): Declare.
+ (init_mangle): Declare.
+ (mangle_decl): Likewise.
+ (mangle_type_string): Likewise.
+ (mangle_type): Likewise.
+ (mangle_typeinfo_for_type): Likewise.
+ (mangle_typeinfo_string_for_type): Likewise.
+ (mangle_vtbl_for_type): Likewise.
+ (mangle_vtt_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_conv_op_name_for_type): Likewise.
+ (mangle_guard_variable): Likewise.
+ * decl.c (pushtag): Keep track of local classes.
+ (initialize_predefined_identifiers): Initialize std_identifier.
+ (init_decl_processing): Use std_identifier.
+ (start_decl): Don't treat instantiations as specializations.
+ (grokdeclarator): Likewise.
+ (grokvardecl): Call mangle_decl for new ABI. Only set mangled
+ name for fully-instantiated templates.
+ * decl2.c (grokclassfn): Use set_mangled_name_for_decl for
+ destructors with the new ABI.
+ (finish_static_data_member_decl): Use mangle_decl under the new ABI.
+ (grokfield): Use mangle_type for new ABI.
+ (grokoptypename): Use mangle_conv_op_for_type for new ABI.
+ (get_sentry): Use mangle_guard_variable for new ABI.
+ (start_static_initialization_or_destruction): Likewise.
+ * expr.c (extract_aggr_init): Remove.
+ (extract_scalar_init): Likewise.
+ (extract_init): Remove #if 0'd code.
+ * mangle.c: New function.
+ * method.c (build_mangled_name): Assert not flag_new_abi.
+ (build_static_name): Likewise.
+ (build_decl_overload_real): Likewise.
+ (build_typename_overload): Likewise.
+ (build_overload_with_type): Likewise.
+ (build_overload_name): Likewise.
+ (get_ctor_vtbl_name): Likewise.
+ (start_squangling): Likewise.
+ (get_id_2): Likewise.
+ (set_mangled_name_for_decl): Call mangle_decl for new ABI.
+ (init_method): Call init_mangle for new ABI.
+ (make_thunk): Call mangle_thunk for new ABI.
+ * operators.def: Correct new ABI manglings for the `%' operator.
+ Add `::' operator.
+ * pt.c (build_template_decl): Copy DECL_OVERLOADED_OPERATOR_P and
+ DECL_ASSIGNMENT_OPERATOR_P to the TEMPLATE_DECL.
+ (lookup_template_class): Call mangle_decl for new ABI.
+ (get_mostly_instantiated_function_type): New function.
+ (set_mangled_name_for_template_decl): Use it.
+ (tsubst_decl): Use set_mangled_name_for_decl for destructors with
+ the new ABI. Use mangle_conv_op_name_for_type for instantiated
+ conversion op names.
+ * rtti.c (tinfo_name): Call mangle_type_string for new ABI.
+ (get_tinfo_decl): Call mangle_typeinfo_for_type for new ABI.
+ (tinfo_base_init): Likewise. Mangle typeinfo string name with
+ mangle_typeinfo_string_for_type.
+
+2000-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_LEVEL): Clarify comment.
+ (INNERMOST_TEMPLATE_ARGS): New macro.
+ (innermost_args): Remove.
+ (get_innermost_template_args): New function.
+ * decl2.c (arg_assoc_class): Use INNERMOST_TEMPLATE_ARGS.
+ * error.c (dump_function_decl): Be caution when using
+ most_general_template.
+ * method.c (build_template_parm_names): Use
+ INNERMOST_TEMPLATE_ARGS.
+ * pt.c (add_to_template_args): Tidy comment
+ (get_innermost_template_args): New function.
+ (check_explicit_specialization): Clear DECL_INITIAL for a new
+ specialization.
+ (process_partial_specialization): Use INNERMOST_TEMPLATE_ARGS.
+ Tidy.
+ (push_template_decl): Always register specializations of the most
+ general template.
+ (convert_template_argument): Use INNERMOST_TEMPLATE_ARGS.
+ (coerce_template_parms): Likewise.
+ (lookup_template_class): Likewise.
+ (innermost_args): Remove.
+ (tsubst_decl): Use INNERMOST_TEMPLATE_ARGS.
+ (tsubst_decl): Handle tricky specializations. Use
+ get_innermost_template_args.
+ (instantiate_template): Simplify handling of partial
+ instantiations.
+ (get_class_bindings): Use INNERMOST_TEMPLATE_ARGS.
+ (most_general_template): Reimplement, in a more straightforward
+ manner.
+ (regenerate_decl_from_template): Tweak formatting. Use
+ TMPL_ARGS_DEPTH for clarity.
+ (set_mangled_name_for_template_decl): Use INNERMOST_ARGS.
+
+ * dump.c (dequeue_and_dump): Dump information about thunks.
+
+2000-06-01 Richard Henderson <rth@cygnus.com>
+
+ * decl.c (init_decl_processing): Set lang_get_alias_set first thing.
+
+2000-06-01 Richard Henderson <rth@cygnus.com>
+
+ * decl2.c (unsupported_options): Fix typo, make const.
+ (lang_decode_option): Fix bsearch argument order.
+
+2000-06-01 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (resolve_offset_ref): Remove check for TREE_ADDRESSABLE
+ on FIELD_DECLs.
+
+2000-05-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-tree.h (c_get_alias_set): Deleted.
+ * Makefile.in (decl.o): Include ../expr.h.
+ * decl.c (expr.h): Include.
+ (init_decl_processing): Call record_component_aliases for arrays.
+ (grokdeclarator): Likewise.
+ Set TREE_ADDRESSABLE for fields that aren't bitfields.
+ * tree.c (build_cplus_array_type_1): Call record_component_aliases.
+
+2000-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ Remove guiding declaration support.
+ * cp/cp-tree.h (flag_dump_translation_unit): Make it const.
+ (flag_guiding_decls): Remove.
+ * call.c (build_user_type_conversion_1): Remove support for
+ guiding decls.
+ (build_new_function_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ * decl.c (start_function): Likewise.
+ * friend.c (is_friend): Likewise.
+ (do_friend): Likewise.
+ * decl2.c ((flag_dump_translation_unit): Make it const.
+ (flag_guiding_decls): Remove.
+ (unsupported_options): New variable
+ (compare_options): New function.
+ (lang_decode_option): Use them.
+
+ * decl.c (build_cp_library_fn): Set DECL_CONTEXT.
+
+ * method.c (mangle_expression): Adjust test for legal expression
+ operators.
+
+ * pt.c (instantiate_decl): Save and restore the local
+ specializations list.
+
+2000-05-30 Jason Merrill <jason@decepticon.cygnus.com>
+
+ * decl.c (grok_reference_init): Pass LOOKUP_ONLYCONVERTING.
+
+2000-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (add_template_candidate_real): Handle member template
+ constructors for classes with virtual bases.
+ (build_user_type_conversion_1): Use in_charge_arg_for_name.
+ (build_new_method_call): Use DECL_NONSTATIC_MEMBER_FUNCTION_P.
+
+ * ir.texi: Update thunk documentation.
+
+ * call.c (joust): Fix handling of overloaded builtin operators.
+
+2000-05-30 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h (DECL_ANTICIPATED): New macro.
+ Document new use of DECL_LANG_FLAG_7.
+ * decl.c (builtin_function): Set DECL_ANTICIPATED on builtins
+ in the user namespace.
+ * lex.c (do_identifier): If the identifier's declaration has
+ DECL_ANTICIPATED on, it has not yet been declared. But do not
+ replace it with an ordinary implicit declaration.
+
+ * tinfo2.cc: Include stdlib.h.
+
+2000-05-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_ALIGN_UNIT): New macro.
+ * class.c (layout_empty_base): Use CLASSTYPE_ALIGN_UNIT, not
+ CLASSTYPE_ALIGN.
+
+2000-05-28 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Use skip_leading_substring instead
+ of plain strncmp.
+
+2000-05-28 Alexandre Oliva <aoliva@cygnus.com>
+
+ * operators.def (<?): Duplicated, should have been...
+ (>?): this. Fixed.
+
+2000-05-27 Alex Samuel <samuel@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (ansi_opname): Make it a macro.
+ (ansi_assopname): Likewise.
+ (struct lang_decl_flags): Add assignment_operator_p.
+ (struct lang_decl): Add operator_code.
+ (DECL_VTT_PARM): Adjust.
+ (DECL_OVERLOADED_OPERATOR_P): Return the operator_code for an
+ overloaded operator.
+ (SET_OVERLOADED_OPERATOR_CODE): New macro.
+ (DECL_ASSIGNMENT_OPERATOR_P): New macro.
+ (DECL_ARRAY_DELETE_OPERATOR_P): Adjust.
+ (opname_tab): Remove.
+ (assignop_tab): Likewise.
+ (operator_name_info_t): New type.
+ (operator_name_info): New variable.
+ (assignment_operator_name_info): Likewise.
+ (build_cp_library_fn): Remove declaration.
+ (push_cp_library_fn): Likewise.
+ (operator_name_string): Likewise.
+ (build_decl_overload): Likewise.
+ * call.c (print_z_candidates): Simplify.
+ (build_object_call): Adjust usage of ansi_opname. Use
+ DECL_OVERLOADED_OPERATOR_P.
+ (op_error): Adjust operator name lookup.
+ (build_conditional_expr): Adjust usage of ansi_opname.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (build_over_call): Likewise.
+ (joust): Use DECL_OVERLOADED_OPERATOR_P.
+ * decl.c (duplicate_decls): Copy operator_code.
+ (init_decl_processing): Adjust parameters to push_cp_library_fn.
+ (builtin_function): Adjust parameters to build_library_fn_1.
+ (build_library_fn_1): Accept an overloaded operator code.
+ (build_library_fn): Pass ERROR_MARK.
+ (build_cp_library_fn): Accept an overloaded operator code.
+ (push_cp_library_fn): Likewise.
+ (grokfndecl): Tweak.
+ (grokdeclarator): Simplify code to compute names of overloaded
+ operators. Adjust use of ansi_opname.
+ (ambi_op_p): Work on tree_codes, not identifiers.
+ (unary_op_p): Likewise.
+ (grok_op_properties): Likewise.
+ (start_function): Use DECL_OVERLOADED_OPERATOR_P.
+ (lang_mark_tree): Don't try to mark the operator_code.
+ * decl2.c (grok_function_init): Use DECL_OVERLOADED_OPERATOR_P.
+ * error.c (dump_decl): Remove special handling for operator
+ names.
+ (dump_function_name): Likewise.
+ (dump_expr): Adjust name lookup of operators.
+ (op_to_string): Simplify.
+ (assop_to_string): Likewise.
+ * init.c (build_new_1): Adjust use of ansi_opname.
+ * lex.c (opname_tab): Remove.
+ (assignop_tab): Likewise.
+ (ansi_opname): Likewise.
+ (ansi_assopname): Likewise.
+ (operator_name_string): Likewise.
+ (reinit_lang_specific): Likewise.
+ (operator_name_info): New variable.
+ (assignment_operator_name_info): Likewise.
+ (init_operators): New function.
+ (init_parse): Use it.
+ (do_identifier): Adjust use of ansi_opname.
+ * method.c (mangle_expression): Don't use ansi_opname for
+ mangling.
+ (build_decl_overload_real): Use DECL_OVERLOADED_OPERATOR_P.
+ (build_decl_overload): Remove.
+ (build_typename_overload): Use OPERATOR_TYPENAME_FORMAT directly.
+ (do_build_assign_ref): Adjust use of ansi_opname.
+ (synthesize_method): Likewise.
+ (implicitly_declare_fn): Likewise.
+ * operators.def: New file.
+ * parse.y (operator): Adjust use of ansi_opname.
+ * pt.c (tsubst_decl): Use IDENTIFIER_OPNAME_P.
+ (set_mangled_name_for_template_decl): Don't play games with
+ current_namespace.
+ (special_function_p): Adjust use of ansi_opname.
+ * typeck.c (check_return_expr): Likewise.
+ * Make-lang.in (cc1plus): Depend on operators.def.
+ * Makefile.in (lex.o): Likewise.
+ (decl.o): Likewise.
+
+2000-05-27 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (cplib2.ready): Eradicate.
+
+2000-05-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * method.c (mangle_expression): Use TREE_CODE_LENGTH.
+ * tree.c (break_out_calls, build_min_nt): Use TREE_CODE_LENGTH.
+ (built_min, cp_tree_equal): Likewise.
+
+2000-05-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_nonempty_base_or_field): Replace
+ `record_layout_info' with `record_layout_info_s'.
+
+2000-05-26 Jason Merrill <jason@casey.soma.redhat.com>
+
+ Fix goto checking.
+ * cp-tree.h (struct language_function): x_named_labels is now
+ a struct named_label_list*.
+ * decl.c (struct named_label_use_list): Renamed from...
+ (struct named_label_list): ...this. New struct.
+ (push_binding_level): Don't set eh_region.
+ (note_level_for_eh): New fn.
+ (pop_label): Take label and old value directly.
+ (pop_labels): Adjust for new named_labels format.
+ (lookup_label): Likewise.
+ (poplevel): Note characteristics of a binding level containing a
+ named label. Mess with named label lists earlier.
+ (mark_named_label_lists): New fn.
+ (mark_lang_function): Call it.
+ (use_label): New fn, split out from...
+ (make_label_decl): ...here. Don't call it.
+ (decl_jump_unsafe, check_previous_goto, check_previous_goto_1,
+ check_previous_gotos): New fns, split out from...
+ (define_label): ...here.
+ (check_switch_goto): New fn.
+ (define_case_label): Call it.
+ (check_goto): New fn.
+ * semantics.c (finish_goto_stmt): Call it and use_label.
+ (begin_compound_stmt): If we're a try block, call note_level_for_eh.
+ (expand_stmt): Never pass 1 as DONT_JUMP_IN to expand_end_bindings.
+
+2000-05-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry_ref): Correct usage of
+ get_vtbl_decl_for_binfo.
+
+ * decl2.c (grokclassfn): Set DECL_LANGUAGE here.
+ * method.c (implicitly_declare_fn): Not here.
+
+2000-05-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_PTMD_DESC_TYPE): Rename to ...
+ (CPTI_PTMD_DESC_TYPE): ... here.
+ (ptmd_desc_type_node): Rename to ...
+ (ptm_desc_type_node): ... here.
+ * decl.c: Likewise.
+ * rtti.c (ptmd_initializer): Rename to ...
+ (ptm_initializer): ... here.
+ (sythesize_tinfo_var): Adjust. Deal with pointer to member
+ function.
+ (create_tinfo_types): Adjust.
+
+2000-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ Finish implementation of VTTs.
+ * cp-tree.h (cp_tree_index): Add CPTI_VTT_PARM_TYPE and
+ CPTI_VTT_PARM_IDENTIFIER.
+ (vtt_parm_identifier): New macro.
+ (vtt_parm_type): Likewise.
+ (BINFO_SUBVTT_INDEX): Likewise.
+ (BINFO_VPTR_INDEX): Likewise.
+ (struct lang_decl): Add vtt_parm.
+ (DECL_VTT_PARM): New macro.
+ (DECL_USE_VTT_PARM): Likewise.
+ (DECL_NEEDS_VTT_PARM_P): Likewise.
+ (get_vtt_name): Declare.
+ (build_artificial_parm): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ (expand_indirect_vtbls_init): Remove.
+ * call.c (build_new_method_call): Pass the vtt to subobject
+ constructors and destructors.
+ * class.c (get_vtt_name): Give it external linkage.
+ (build_clone): Handle the magic VTT parameters for clones.
+ (clone_function_decl): Fix typo in comment.
+ (build_vtt): Keep track of the indices in the VTTs where various
+ entities are stored.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (build_ctor_vtbl_group): Tweak type of construction vtables.
+ (dfs_accumulate_vtbl_inits): Build vtables for all bases, even
+ primary bases, when building construction vtables.
+ * decl.c (duplicate_decls): Handle DECL_VTT_PARM.
+ (initialize_predefined_identifiers): Add vtt_parm_identifier.
+ (init_decl_processing): Initialize vtt_parm_type.
+ (grokfndecl): Use DECL_OVERLOADED_OPERATOR_P.
+ (lang_mark_tree): Make vtt_parm.
+ * decl2.c (build_artificial_parm): New function.
+ (maybe_retrofit_in_chrg): Use it. Add VTT parameters.
+ (grokclassfn): Use build_artificial_parm.
+ * init.c (initialize_vtbl_ptrs): Call
+ fixup_all_virtual_upcast_offsets directly.
+ (perform_member_init): Use the complete subobject destructor for
+ member cleanups.
+ (build_vtbl_address): New function.
+ (expand_virtual_init): Handle VTTs.
+ * optimize (maybe_clone_body): Likewise.
+ * search.c (fixup_all_virtual_upcast_offsets): Give it external
+ linkage.
+ (expand_indirect_vtbls_init): Remove.
+ * semantics.c (setup_vtbl_ptr): Fix typos in comment.
+ * tree.c (make_binfo): Make them bigger.
+
+2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__pbase_type_info): Define, based on
+ __pointer_type_info.
+ (__pointer_type_info): Derive from __pbase_type_info. Adjust.
+ (__pointer_to_member_type_info): Likewise.
+ * tinfo2.cc (__pbase_type_info::~__pbase_type_info): Implement.
+ (__pointer_to_member_type_info::__is_pointer_p): Remove.
+ (__pointer_type_info::__do_catch): Rename to ...
+ (__pbase_type_info::__do_catch): ... here. Adjust.
+ (__pbase_type_info::__pointer_catch): Implement.
+ (__pointer_type_info::__pointer_catch): Adjust.
+ (__pointer_to_member_type_info::__pointer_catch): Adjust.
+
+2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.h (__user_type_info::contained_virtual_p): New
+ predicate.
+ * tinfo.cc (__user_type_info::do_upcast): Fix bug with diamond
+ shaped hierarchy.
+ (__vmi_class_type_info::__do_upcast): Fix bug with NULL pointer to
+ diamond shaped hierarchy. Add early out for mixed diamond and
+ duplicate shaped hierarchy.
+
+2000-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_delete): Change prototype.
+ (build_vec_delete): Likewise.
+ * call.c (build_scoped_method_call): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_method_call): Likewise.
+ * decl.c (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise. Rename to ...
+ (maybe_build_cleanup): ... this.
+ * decl2.c (delete_sanity): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_cleanup): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_dtor_call): Simplify.
+ (build_delete): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_vbase_delete): Likewise.
+ (build_vec_delete): Likewise.
+
+ * init.c (sort_member_init): Fix typo in error message generation
+ code.
+
+2000-05-15 Donald Lindsay <dlindsay@cygnus.com>
+
+ * semantics.c (begin_class_definition): make the packed
+ attribute be sensitive to the "-fpack-struct" command line flag
+
+2000-05-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Update new-abi upcast algorithm.
+ * inc/cxxabi.h (__class_type_info::__do_upcast): Change
+ prototype and meaning of return value.
+ (__si_class_type_info::__do_upcast): Likewise.
+ (__vmi_class_type_info::__do_upcast): Likewise.
+ * tinfo.cc (__class_type_info::__upcast_result): Replace
+ whole2dst with part2dst. Adjust ctor.
+ (__class_type_info::__do_upcast): Adjust call of worker function.
+ (__class_type_info::__do_upcast): Adjust.
+ (__si_class_type_info::__do_upcast): Adjust. Use parent's
+ __do_upcast.
+ (__vmi_class_type_info::__do_upcast): Likewise. Fix private
+ virtual base in diamond hierarchy bug.
+
+2000-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable
+ and bitfield to tinfo_fn_p.
+ (DECL_TINFO_FN_P): Adjust.
+ (SET_DECL_TINFO_FN_P): Likewise.
+ (DECL_MUTABLE_P): Likewise.
+ (DECL_C_BIT_FIELD): Likewise.
+ (SET_DECL_C_BIT_FIELD): Likewise.
+ (CLEAR_DECL_C_BIT_FIELD): Likewise.
+ (DECL_UNINLINABLE): Likewise.
+ * class.c (alter_access): Call retrofit_lang_decl if ncessary.
+ (handle_using_decl): Remove assertion.
+ (build_vtbl_or_vbase_field): Use build_decl, not build_lang_decl,
+ to build FIELD_DECLs.
+ (build_base_field): Likewise.
+ (layout_class_type): Likewise.
+ * decl.c (init_decl_processing): Likewise.
+ (build_ptrmemfunc_type): Likewise.
+ (grokdeclarator): Likewise.
+ * decl2.c (grok_x_components): Likewise.
+ * except.c (call_eh_info): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * rtti.c (expand_class_desc): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ * ptree.c (print_lang_decl): Adjust.
+ * typeck.c (build_component_ref): Don't check DECL_LANG_SPECIFIC
+ before checking DECL_MUTABLE_P.
+
+ * decl2.c (maybe_retrofit_in_chrg): Don't create in-charge
+ parameters for template functions.
+ * pt.c (tsubst_decl): Make sure we call maybe_retrofit_in_chrg for
+ destructors as well as constructors.
+
+2000-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_ctor_vtbl_group): Set inits.
+ * optimize.c (maybe_clone_body): Set DECL_INLINE and
+ DECL_THIS_INLINE appropriately for clones.
+
+ * cp-tree.h (IDENTIFIER_TYPENAME_P): Use a flag, not strncmp.
+ (DECL_CONV_FN_P): Simplify.
+ (DECL_OPERATOR): Remove.
+ (language_to_string): Declare.
+ * decl.c (duplicate_decls): Fix typo in comment.
+ (grokdeclarator): Adjust use of IDENTIFIER_TYPENAME_P.
+ (grok_op_properties): Use DECL_CONV_FN_P instead of
+ IDENTIFIER_TYPENAME_P.
+ * dump.c (dequeue_and_dump): Dump the language linkage of
+ declarations.
+ * error.c (language_to_string): Give it external linkage.
+ * method.c (build_typename_overload): Set IDENTIFIER_TYPENAME_P.
+ (implicitly_declare_fn): Set DECL_LANGUAGE.
+ * pt.c (check_explicit_specialization): Use DECL_CONV_FN_P, not
+ IDENTIFIER_TYPENAME_P.
+ (tsubst_decl): Likewise.
+ (tsubst_copy): Adjust use of IDENTIFIER_TYPENAME_P.
+ * semantics.c (finish_member_declaration): Don't mark members of
+ classes declared in an extern "C" region as extern "C".
+
+2000-05-22 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (qualified_lookup_using_namespace): Look through
+ namespace aliases.
+
+ * decl.c (push_using_decl): Return the old decl on namespace level.
+
+2000-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SET_BINFO_NEW_VTABLE_MARKED): Add sanity checks.
+ (VTT_NAME_PREFIX): New macro.
+ (CTOR_VTBL_NAME_PREFIX): Likewise.
+ (get_ctor_vtbl_name): New function.
+ * class.c (get_vtable_name): Simplify.
+ (get_vtt_name): New function.
+ (get_vtable_decl): Don't set IDENTIFIER_GLOBAL_VALUE.
+ (dfs_mark_primary_bases): Update the CLASSTYPE_VBASECLASSES list
+ when a virtual base becomes primary.
+ (finish_struct_1): Set CLASSTYPE_VFIELDS a little earlier. Build
+ VTTs.
+ (finish_vtbls): Adjust calls to accumulate_vtbl_inits to pass in
+ additional parameters.
+ (dfs_finish_vtbls): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (initialize_array): New function.
+ (build_vtt): Likewise.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+ (initialize_vtable): Use initialize_array.
+ (accumulate_vtbl_inits): Reimplement to handle construction
+ vtables.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (bulid_vtbl_initializer): Adjust parameter name.
+ * method.c (build_typename_overload): Remove #if 0'd code.
+ (get_ctor_vtbl_name): New function.
+ * search.c (dfs_walk_real): Use BINFO_N_BASETYPES.
+ (init_vbase_pointers): Don't mess with the TREE_CHAIN of a binfo.
+
+ * cp-tree.h (struct lang_type): Remove search_slot.
+ (CLASSTYPE_SEARCH_SLOT): Remove.
+ (emit_base_init): Change prototype.
+ (initialize_vtbl_ptrs): Likewise.
+ (expand_indirect_vtbls_init): Likewise.
+ (clear_search_slots): Remove.
+ * decl.c (lang_mark_tree): Don't mark search_slot.
+ * init.c (initialize_vtbl_ptrs): Simplify.
+ (emit_base_init): Likewise.
+ * search.c (struct vbase_info): Document decl_ptr.
+ (convert_pointer_to_single_level): Remove.
+ (dfs_find_vbases): Remove.
+ (dfs_init_base_pointers): Simplify.
+ (dfs_clear_vbase_slots): Remove.
+ (dfs_vtable_path_unmark): New function.
+ (init_vbase_pointers): Simplify.
+ (expand_upcast_fixups): Don't rely on CLASSTYPE_SEARCH_SLOT.
+ (expand_indirect_vtbls_init): Simplify. Don't call
+ mark_all_temps_used.
+ * semantics.c (setup_vtbl_ptr): Adjust calls to emit_base_init and
+ initialize_vtbl_ptrs.
+
+2000-05-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * except.c: Add static prototypes.
+
+2000-05-20 H.J. Lu <hjl@gnu.org>
+
+ * Make-lang.in (cplib2.ready): Also depend on cc1plus$(exeext).
+
+2000-05-19 Mark Mitchell <mark@codesourcery.com>
+
+ Don't create a separate copy of virtual bases for the
+ CLASSTYPE_VBASECLASSES list.
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Change documentation.
+ (BINFO_FOR_VBASE): Remove.
+ (CANONICAL_BINFO): Adjust.
+ (binfo_for_vbase): New function.
+ * class.c (build_vbase_pointer_fields): Use binfo_for_vbase
+ instead of BINFO_FOR_VBASE.
+ (build_vbase_pointer): Likewise.
+ (build_secondary_vtable): Likewise.
+ (dfs_mark_primary_bases): Likewise.
+ (mark_primary_bases): Likewise.
+ (layout_nonempty_base_or_field): Likewise.
+ (dfs_set_offset_for_shared_vbases): Likewise.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Likewise. Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (dump_class_hierarchy_r): Use binfo_for_vbase
+ instead of BINFO_FOR_VBASE.
+ (dump_class_hierarchy): Likewise.
+ (finish_vtbls): Likewise.
+ (build_vtbl_initializer): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (build_vbase_offset_vtbl_entries): Use binfo_for_vbase.
+ * decl.c (finish_destructor_body): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ * init.c (sort_base_init): Use binfo_for_vbase.
+ (construct_virtual_bases): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (expand_member_init): Use binfo_for_vbase.
+ (build_vbase_delete): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ * method.c (do_build_copy_constructor): Likewise.
+ * rtti.c (get_base_offset): Use binfo_for_vbase.
+ (expand_class_desc): Remove #if 0'd code.
+ * search.c (struct vbase_info): Remove vbase_types.
+ (get_base_distance): Use binfo_for_vbase.
+ (lookup_field_queue_p): Use CANONICAL_BINFO.
+ (get_shared_vbase_if_not_primary): Use binfo_for_vbase.
+ (get_pure_virtuals): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (dfs_find_vbases): Use binfo_for_vbase.
+ (dfs_init_vbase_pointers): Likewise.
+ (init_vbase_pointers): Don't initialize vi.vbase_types.
+ (virtual_context): Use binfo_for_vbase.
+ (fixup_all_virtual_upcast_offsets): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (expand_indirect_vtbls_init): Simplify.
+ (dfs_get_vbase_types): Don't replicate virtual bases.
+ (find_vbase_instance): Use binfo_for_vbase.
+ (binfo_for_vbase): New function.
+ * typeck.c (get_delta_difference): Use binfo_for_vbase.
+
+2000-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_anon_union): Generalize error messages to handle
+ anonymous structures.
+ * init.c (perform_member_init): Remove `name' parameter.
+ (build_field_list): New function.
+ (sort_member_init): Handle anonymous union initialization order
+ correctly. Check for multiple initializations of the same union.
+ (emit_base_init): Don't look up fields by name here.
+ (expand_member_init): Record the result of name lookup for future
+ reference.
+ * typeck.c (build_component_ref): Fix formatting.
+
+2000-05-17 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * decl.c (pop_label): Replace warn_unused with warn_unused_label.
+ * typeck.c (build_x_compound_expr): Replace warn_unused with
+ warn_unused_value.
+
+ * decl2.c (lang_decode_option): Update -Wall unused flags by
+ calling set_Wunused.
+
+2000-05-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-treeh (BINFO_NEW_VTABLE_MARKED): Update documentation.
+ * init.c (dfs_vtable_path_unmark): Remove.
+ * search.c (marked_new_vtable_p): Likewise.
+ (unmarked_new_vtable_p): Likewise.
+ (dfs_search_slot_nonempty_p): Likewise.
+ (dfs_mark): Likewise.
+ (dfs_vtable_path_unmark): Likewise.
+ (dfs_find_vbases): Don't set BINFO_NEW_VTABLE_MARKED.
+ (dfs_int_vbase_pointers): Don't clear BINFO_VTABLE_PATH_MARKED.
+ (dfs_init_vbase_pointers): Remove special-case new ABI code.
+ (dfs_clear_vbase_slots): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (init_vbase_pointers): Simplify.
+ (expand_indirect_vtbls_init): Likewise.
+
+ * class.c (copy_virtuals): New function.
+ (build_primary_table): Use it.
+ (build_secondary_vtable): Likewise.
+ (modify_vtable_entry): Use NULL_TREE, not integer_zero_node, to
+ indicate that no vcall offset is required.
+ (add_virtual_function): Likewise.
+ (modify_all_vtables): Likewise.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (build_vtbl_initializer): Make changes to handle construction
+ vtables.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_rtti_vtbl_entries): Likewise.
+ (build_vtable_entries): Handle a NULL vcall_index.
+
+2000-05-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Fix thinko.
+
+2000-05-14 Jason Merrill <jason@casey.cygnus.com>
+
+ * except.c (check_handlers): New fn.
+ * cp-tree.h: Declare it.
+ * semantics.c (finish_handler_sequence): Call it.
+ (finish_function_handler_sequence): Likewise.
+ (finish_handler_parms): Set TREE_TYPE on the handler.
+ * cp-tree.h (PUBLICLY_UNIQUELY_DERIVED_P): New macro.
+ * search.c (get_base_distance_recursive): If protect>1, ignore
+ special access.
+ (get_base_distance): Don't reduce watch_access.
+
+2000-05-13 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c: #include diagnostic.h.
+ (lang_init_options): Set default prefixing rules.
+
+ * lang-options.h: Add -fdiagnostics-show-location=.
+
+ * decl2.c: #include diagnostic.h.
+ (lang_decode_option): Handle -fdiagnostics-show-location=.
+
+2000-05-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc: Revert my 2000-05-08 and 2000-05-07 changes.
+ * vec.cc: Revert my 2000-05-07 change.
+
+2000-05-11 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (check_field_decls): Complain about non-static data
+ members with same name as class in class with constructor.
+
+2000-05-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokdeclarator): Allow non-static data members with
+ same name as class.
+
+2000-05-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Constify tree_srcloc.filename, tinst_level.file,
+ and pending_inline.filename. Update prototypes.
+ * decl.c (define_label): Constify filename parameter.
+ * decl2.c (warn_if_unknown_interface): Constify local char *.
+ * input.c Constify input_source.filename. Don't declare
+ input_filename or lineno. Constify filename parameter to feed_input.
+ * lex.c (init_parse): Constify parameter and return value.
+ (cp_pragma_interface, cp_pragma_implementation): Constify
+ filename argument.
+ (reinit_parse_for_method, reinit_parse_for_block,
+ reinit_parse_for_expr, feed_defarg, handle_cp_pragma):
+ Constify local char *.
+ * pt.c: Don't declare lineno or input_filename.
+ (print_template_context, tsubst_friend_function, tsubst_decl,
+ tsubst, instantiate_decl): Constify local char *.
+ * semantics.c (expand_body): Constify local char *.
+ * tree.c (build_srcloc): Constify filename parameter.
+ * typeck.c (c_expand_asm_operands): Constify filename
+ parameter.
+
+2000-05-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (__dynamic_cast): Use a reinterpret_cast. Fix
+ offsetof expansion.
+
+2000-05-08 Branko Cibej <branko.cibej@hermes.si>
+
+ * inc/cxxabi.h: Fix typos in comment.
+ (__base_class_info::__offset): Use a static_cast.
+
+2000-05-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h: Use __SIZE_TYPE_ and __PTRDIFF_TYPE__ in place
+ of std::size_t and std::ptrdiff_t respectively.
+ * tinfo.cc: Likewise.
+ * vec.cc: Likewise.
+
+2000-05-06 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_c_cast): Don't warn integer->pointer size
+ mismatch for constants.
+
+2000-05-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (ptmd_initializer): Set non-public, if class is
+ incomplete.
+
+ * inc/cxxabi.h (__dynamic_cast): Explicitly say extern "C++".
+ (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Likewise.
+ * tinfo.cc (__dynamic_cast): Likewise.
+ * vec.cc (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Likewise.
+
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
+ (SET_FNADDR_FROM_VTABLE_ENTRY): Likewise.
+ (lang_decl_flags): Add vcall_offset.
+ (THUNK_VCALL_OFFSET): Use it.
+ * decl.c (lang_mark_tree): Don't mark DECL_ACCESS for a thunk.
+ * method.c (make_thunk): Create the lang_decl here, not in
+ emit_thunk.
+ (emit_thunk): Make generic thunks into ordinary functions once
+ they have been fed to expand_body.
+ * semantics.c (expand_body): Set current_function_is_thunk here.
+
+2000-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (update_vtable_entry_for_fn): Prototype.
+
+ * pt.c (tsubst_decl): Initialize variables `argvec', `gen_tmpl'
+ and `tmpl'.
+
+ * search.c (dfs_build_inheritance_graph_order): Prototype.
+
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (special_function_kind): Add various kinds of
+ destructors.
+ (special_function_p): New function.
+ * class.c (overrides): Don't let one kind of destructor override
+ another.
+ * decl2.c (mark_used): Use DECL_NON_THUNK_FUNCTION_P when deciding
+ whether or not to instantiate a template.
+ * tree.c (special_function_p): Define.
+
+2000-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Remove.
+ * cp-tree.h (DECL_THUNK_P): New macro.
+ (DECL_NON_THUNK_FUNCTION_P): Likewise.
+ (DECL_EXTERN_C_FUNCTION_P): Likewise.
+ (SET_DECL_THUNK_P): Likewise.
+ (DELTA_FROM_VTABLE_ENTRY): Use DECL_THUNK_P.
+ (FNADDR_FROM_VTABLE_ENTRY): Likewise.
+ (DECL_MAIN_P): Use DECL_EXTERN_C_FUNCTION_P.
+ * decl.c (decls_match): Use DECL_EXTERN_C_P.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise. Adjust thunk handling.
+ (grokfndecl): Use DECL_EXTERN_C_P.
+ * decl2.c (mark_vtable_entries): Use DECL_THUNK_P.
+ * dump.c (dequeue_and_dump): Remove THUNK_DECL handling.
+ * except.c (nothrow_libfn_p): Use DECL_EXTERN_C_P.
+ * expr.c (cplus_expand_expr): Remove THUNK_DECL handling.
+ * method.c (make_thunk): Use SET_DECL_THUNK_P. Set
+ DECL_NO_STATIC_CHAIN.
+ (emit_thunk): Don't play games with TREE_CODE on thunks. Don't
+ set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk.
+ * search.c (covariant_return_p): Remove THUNK_DECL handling.
+ * ir.texi: Update.
+
+2000-05-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (walk_tree): Set lineno.
+
+2000-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * exception.cc: Update license notice.
+ * new.cc: Likewise.
+ * new1.cc: Likewise.
+ * new2.cc: Likewise.
+ * tinfo.cc: Likewise.
+ * tinfo2.cc: Likewise.
+ * vec.cc: Likewise.
+ * inc/cxxabi.h: Likewise.
+ * inc/exception: Likewise.
+ * inc/new: Likewise.
+ * inc/new.h: Likewise.
+ * inc/typeinfo: Likewise.
+
+2000-05-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (build_target_expr_with_type): If we already have a
+ TARGET_EXPR, just return it.
+
+ * optimize.c (initialize_inlined_parameters): Don't generate an
+ EXPR_STMT if we can just use DECL_INITIAL.
+ * decl.c (emit_local_var): Only make the initialization a
+ full-expression if stmts_are_full_exprs_p.
+
+2000-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): New
+ macro.
+ * call.c (standard_conversion): Use it.
+ (direct_reference_binding): Likewise.
+ (build_over_call): Likewise.
+ (is_properly_derived_from): Likewise.
+ (compare_ics): Likewise.
+ * class.c (resolves_to_fixed_type_p): Likewise.
+ * optimize.c (declare_return_variable): Likewise.
+ * pt.c (is_specialization_of): Likewise.
+ (unify): Likewise.
+ * typeck.c (comp_target_parms): Likeiwse.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (comp_ptr_ttypes_const): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+
+2000-04-30 Scott Snyder <snyder@fnal.gov>
+
+ * decl.c (finish_destructor_body): Use the base destructor when
+ destroying virtual bases.
+
+2000-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr): Preserve temporaries when expanding
+ STMT_EXPRs.
+ * optimize.c (struct inline_data): Add target_exprs field.
+ (declare_return_variable): When a function returns an aggregate,
+ use the variable declared in the TARGET_EXPR as the remapped
+ DECL_RESULT.
+ (expand_call_inline): Update the pending target_exprs stack.
+ (optimize_function): Initialize the stack.
+
+ * decl2.c (finish_file): Fix typo in comment.
+
+ * method.c (emit_thunk): Don't try to return a `void' value.
+
+ * optimize.c (initialize_inlined_parameters): If the parameter is
+ addressable, we need to make a new VAR_DECL, even if the
+ initializer is constant.
+
+2000-04-28 Cosmin Truta <cosmint@cs.ubbcluj.ro>
+
+ * decl.c (grok_op_properties): Add an extra check of argtypes.
+
+2000-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (copy_body_r): Use STRIP_TYPE_NOPS when copying
+ variables.
+ (initialize_inlined_parameters): Try to avoid creating new
+ VAR_DECLs.
+
+2000-04-27 Alex Samuel <samuel@codesourcery.com>
+
+ * lex.c (my_get_run_time): Remove.
+ (init_filename_times): Use get_run_time instead of my_get_run_time.
+ (check_newline): Likewise.
+ (dump_time_statistics): Likewise.
+ * decl2.c (finish_file): Push and pop timevar TV_VARCONST instead
+ of computing elapsed time explicitly.
+
+2000-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TREE_READONLY_DECL_P): Use DECL_P.
+ * init.c (decl_constant_value): Check TREE_READONLY_DECL_P.
+ * call.c (convert_like_real): Don't test TREE_READONLY_DECL_P
+ before calling decl_constant_value.
+ * class.c (check_bitfield_decl): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ (convert): Likewise.
+ * decl.c (compute_array_index_type): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (check_cp_case_value): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (tsubst): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (build_compound_expr): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_c_cast): Likewise.
+ (convert_for_assignment): Likewise.
+
+2000-04-26 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (finish_function): Don't play games with DECL_INLINE.
+
+2000-04-25 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
+
+ * ir.texi: Correct typo.
+
+2000-04-25 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Reject VLAs as members.
+
+2000-04-24 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * call.c (standard_conversion): Accept conversion between
+ COMPLEX_TYPEs.
+
+ * cvt.c (ocp_convert): Handle conversion to COMPLEX_TYPE.
+
+2000-04-24 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl2.c (finish_file): Remove double setup for accounting
+ compile time.
+
+2000-04-24 Robert Lipe <robertlipe@usa.net>
+
+ * cp-tree.h (lang_type): Member `language' now ENUM_BITFIELD.
+
+2000-04-23 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * new.cc (set_new_handler): Needs to be in std::.
+
+2000-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl): Remove pretty_function_p.
+ (DECL_PRETTY_FUNCTION_P): Use TREE_LANG_FLAG_0, not a bit in the
+ language-specific node.
+ * decl.c (cp_make_fname_decl): Use build_decl, not
+ build_lang_decl, to build the variables.
+ (grokvardecl): Don't call build_lang_decl for local variables in
+ templates.
+ (grokdeclarator): Don't call build_lang_decl for local type
+ declarations in templates.
+ * lex.c (retrofit_lang_decl): Use ggc_alloc_obj to allocated
+ zero'd memory, rather than calling memset.
+ * pt.c: Include hashtab.h.
+ (local_specializations): New variable.
+ (retrieve_local_specialization): Use it.
+ (register_local_specialization): Likewise.
+ (tsubst_decl): Don't assume local variables have
+ DECL_LANG_SPECIFIC.
+ (instantiate_decl): Set up local_specializations.
+ * Makefile.in (HTAB_H): New variable.
+
+2000-04-23 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (c_expand_asm_operands): Restore the original
+ contents of the output list.
+
+2000-04-22 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Document complex number representation.
+
+2000-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (init_rtti_processing): Set tinfo_var_id in new-abi.
+ (target_incomplete_p): New function.
+ (tinfo_base_init): Create comdat NTBS name variable.
+ (ptr_initializer): Add non_public parameter. Calculate it.
+ (ptmd_initializer): Likewise.
+ (synthesize_tinfo_var): Adjust. Emit incomplete class tinfo.
+ (create_real_tinfo_var): Add non_public parameter. Use it.
+ Push proxy into global namespace.
+ * inc/cxxabi.h (__pointer_type_info::incomplete_class_mask):
+ New enumeration.
+ * inc/typeinfo (type_info::before, type_info::operator==):
+ Compare __name addresses.
+
+ * tinfo2.cc: Remove new-abi builtins comment.
+
+2000-04-20 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (build_x_function_call): Resolve an OFFSET_REF.
+
+ * call.c (joust): Exit early if we get the same function, too.
+
+ * decl2.c (key_method): Return NULL_TREE for template classes.
+ (import_export_class): Don't need to check for template classes.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lex.c: Remove references to cccp.c.
+
+2000-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove const_memfunc and
+ volatile_memfunc. Add destructor_attr. Adjust dummy.
+ (DECL_DESTRUCTOR_P): Use destructor_attr.
+ (DECL_CONST_MEMFUNC_P): Reimplement.
+ (DECL_VOLATILE_MEMFUNC_P): Remove.
+ * class.c (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS.
+ (overrides): Use DECL_DESTRUCTOR_P.
+ (check_for_override): Likewise.
+ * decl.c (start_function): Likewise.
+ * decl2.c (grokfclassfn): Likewise.
+ (check_classfn): Likewise.
+ (grok_function_init): Likewise.
+
+2000-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Issue error on illegal data member
+ declaration.
+
+2000-04-17 Mark P Mitchell <mark@codesourcery.com>
+
+ * method.c (make_thunk): Set DECL_CONTEXT for a THUNK_DECL.
+
+2000-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry): Don't build thunks for type-info
+ functions.
+
+2000-04-16 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (decls_match): Allow a redeclaration of a builtin to
+ specify args while the builtin did not.
+
+2000-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Add to documentation.
+ * cp-tree.h (flag_huge_objects): Declare.
+ * class.c (modify_vtable_entry): Tidy.
+ (update_vtable_entry_for_fn): Split out from dfs_modify_vtables.
+ Calculate delta appropriately for the new ABI.
+ (dfs_modify_vtables): Use it.
+ (modify_all_vtables): Fix thinko in code to add overriding copies
+ of functions to primary vtables.
+ (build_clone): Fix typo in comment.
+ (clone_function_decl): Correct order of destructors in vtable.
+ (build_vbase_offset_vtbl_entries): Adjust comment.
+ (dfs_vcall_offset_queue_p): Remove.
+ (dfs_build_vcall_offset_vtbl_entries): Update BV_VCALL_INDEX.
+ (build_vcall_offset_vtbl_entries): Juse use dfs_skip_vbases.
+ (build_vtable_entry): Correct check for pure virtual functions.
+ Don't declare flag_huge_objects.
+ * decl.c (flag_huge_objects): Remove declaration.
+ * method.c (make_thunk): Tweak mangling for vcall offset thunks.
+ Use int_size_in_bytes.
+ (emit_thunk): Handle vcall offset thunks.
+
+2000-04-15 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl2.c (parse_time, varconst_time): Delete declarations.
+ (finish_file): Delete LINENO declaration.
+ START_TIME and THIS_TIME now long.
+
+2000-04-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_base_field): Reformat comment.
+
+ * inc/cxxabi.h (stddef.h): Comment inclusion.
+ (__base_class_info::__offset): Comment shift.
+
+2000-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_CTOR_OR_DTOR_P): New macro.
+ (cp_tree_index): Add CPTI_PUSH_EXCEPTION_IDENTIFIER.
+ (cp_push_exception_identifier): New macro.
+ (DECL_COMPLETE_DESTRUCTOR_P): New macro.
+ (DECL_BASE_DESTRUCTOR_P): Likewise.
+ (DECL_DELETING_DESTRUCTOR_P): Likewise.
+ (get_vtbl_decl_for_binfo): Fix formatting.
+ (in_charge_arg_for_name): New macro.
+ (maybe_build_cleanup_and_delete): Remove declaration.
+ * call.c (build_field_call): Use IDENTIFIER_CTOR_OR_DTOR_P.
+ (in_charge_arg_for_name): New function.
+ (build_new_method_call): Use it. Handle cloned destructors.
+ (build_clone): Don't make the base constructor virtual.
+ Automatically defer generated functions.
+ (clone_function_decl): Handle destructors, too.
+ (clone_constructors_and_destructors): Likewise.
+ (create_vtable_ptr): Don't create a vtable entry for a cloned
+ function.
+ * decl.c (predefined_identifier): Add ctor_or_dtor_p.
+ (initialize_predefined_identifiers): Update appropriately.
+ (finish_destructor_body): Simplify.
+ (maybe_build_cleanup_and_delete): Remove.
+ * except.c (expand_throw): Handle new-ABI destructors.
+ * init.c (expand_cleanup_for_base): Use base_dtor_identifier.
+ (build_dtor_call): New function.
+ (build_delete): Use it. Simplify.
+ * optimize.c (maybe_clone_body): Handle destructors.
+ * search.c (lookup_field_queue_p): Use IDENTIFIER_CTOR_OR_DTOR_P.
+
+ * exception.cc (cleanup_fn): New typedef.
+ (CALL_CLEANUP): New macro.
+ (cp_eh_info): Use them.
+ (__cp_push_exception): Likewise.
+ (__cp_pop_exception): Likewise.
+
+2000-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_DTOR_IDENTIFIER.
+ (complete_dtor_identifier): New macro.
+ (CLASSTYPE_FIRST_CONVERSION): Remove.
+ (CLASSTYPE_CONSTRUCTOR_SLOT): New macro.
+ (CLASSTYPE_DESTRUCTOR_SLOT): Likewise.
+ (CLASSTYPE_FIRST_CONVERSION_SLOT): Likewise.
+ (CLASSTYPE_CONSTRUCTORS): Likewise.
+ (CLASSTYPE_DESTRUCTORS): Likewise.
+ (lang_decl): Add cloned_function.
+ (DECL_COMPLETE_CONSTRUCTOR_P): New macro.
+ (DECL_BASE_CONSTRUCTOR_P): Likewise.
+ (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P): Likewise.
+ (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P): Likewise.
+ (DECL_CLONED_FUNCTION_P): Likewise.
+ (DECL_CLONED_FUNCTION): Likewise.
+ (clone_function_decl): Declare.
+ (maybe_clone_body): Likewise.
+ * call.c (build_user_type_conversion_1): Call complete object
+ constructors in the new ABI.
+ (build_new_method_call): Don't add in-charge parameters under the
+ new ABI.
+ * class.c (add_method): Use DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P,
+ DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P, CLASSTYPE_CONSTRUCTOR_SLOT, and
+ CLASSTYPE_DESTRUCTOR_SLOT.
+ (build_clone): New function.
+ (clone_function_decl): Likewise.
+ (clone_constructors_and_destructors): Likewise.
+ (check_bases_and_members): Use it.
+ * decl.c (iniitialize_predefined_identifiers): Initialize
+ complete_dtor_identifier.
+ (finish_function): Don't add extra code to a clone.
+ (lang_mark_tree): Mark cloned_function.
+ * decl2.c (mark_used): Don't bother trying to instantiate things
+ we synthesized.
+ * dump.c (dequeue_and_dump): Don't dump CP_DECL_CONTEXT twice.
+ * method.c (set_mangled_name_for_decl): Don't treat clones as
+ constructors.
+ (synthesize_method): Sythesize cloned functions, not the clones.
+ * optimize.c (inline_data): Update comment on ret_label.
+ (remap_block): Don't assume DECL_INITIAL exists.
+ (copy_body_r): Allow ret_label to be NULL.
+ (maybe_clone_body): Define.
+ * pt.c (tsubst_decl): Handle clones.
+ (instantiate_clone): New function.
+ (instantiate_template): Use it.
+ (set_mangled_name_for_template_decl): Don't treat clones as
+ constructors.
+ * search.c (lookup_fnfields_1): Use CLASSTYPE_CONSTRUCTOR_SLOT,
+ CLASSTYPE_DESTRUCTOR_SLOT, and CLASSTYPE_FIRST_CONVERSION_SLOT.
+ * semantics.c (expand_body): Clone function bodies as necessary.
+
+ * optimize.c (remap_decl): Avoid sharing structure for arrays
+ whose size is only known at run-time.
+ * tree.c (copy_tree_r): Don't copy PARM_DECLs.
+
+ * cp-tree.h (lang_decl_flags): Rename constructor_for_vbase_attr
+ to has_in_charge_parm_p.
+ (DECL_CONSTRUCTOR_FOR_VBASE_P): Rename to ...
+ (DECL_HAS_IN_CHARGE_PARM_P): ... this.
+ (DECL_COPY_CONSTRUCTOR_P): New macro.
+ * call.c (add_function_candidate): Use DECL_HAS_IN_CHARGE_PARM_P.
+ (build_user_type_conversion_1): Likewise.
+ (convert_like_real): Likewise.
+ (build_over_call): Likeiwse. Use DECL_COPY_CONSTRUCTOR_P.
+ * decl.c (grokdeclarator): Use DECL_HAS_IN_CHARGE_PARM_P.
+ (copy_args_p): Likewise.
+ (grok_ctor_properties): Likewise.
+ (start_function): Likewise.
+ * decl2.c (maybe_retrofit_in_charge): Likewise. Set it.
+ * error.c (dump_function_decl): Use DECL_HAS_IN_CHARGE_PARM_P.
+ * init.c (emit_base_init): Use DECL_COPY_CONSTRUCTOR_P.
+ * method.c (do_build_copy_constructor): Use
+ DECL_HAS_IN_CHARGE_PARM_P.
+ (synthesize_method): Likewise.
+ * pt.c (instantiate_template): Remove goto.
+ * tree.c (build_cplus_method_type): Remove mention of obstacks in
+ comment.
+
+ * cp-tre.h (finish_function): Change prototype.
+ * decl.c (end_cleanup_fn): Adjust caller.
+ (finish_function): Take only one parameter.
+ * decl2.c (finish_objects): Adjust caller.
+ (finish_static_storage_duration_function): Likewise.
+ * method.c (emit_thunk): Likewise.
+ * parse.y: Likewise.
+ * parse.c: Regenerated.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (expand_body): Likewise.
+
+ * cp-tree.h (copy_decl): New function.
+ * class.c (finish_struct_1): Use it.
+ * lex.c (copy_decl): Define it.
+ * pt.c (tsubst_decl): Likewise.
+ * tree.c (copy_template_template_parm): Likewise.
+
+ * cp-tree.h (lang_type): Remove has_nonpublic_ctor and
+ has_nonpublic_assign_ref.
+ (TYPE_HAS_NONPUBLIC_CTOR): Don't declare.
+ (TYPE_HAS_NONPUBLIC_ASSIGN_REF): Likewise.
+ * class.c (finish_struct_methods): Don't set
+ TYPE_HAS_NONPUBLIC_CTOR or TYPE_HAS_NONPUBLIC_ASSIGN_REF.
+ (interface_only): Don't declare.
+ (interface_unknown): Likewise.
+
+2000-04-11 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * tree.h (HAVE_TEMPLATES): Remove definition.
+ * lang-options.h (-fthis-is-variable): Remove documentation.
+
+2000-04-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (instantiate_type): Handle object-relative template-id.
+
+ * semantics.c (finish_expr_stmt): Call convert_to_void here.
+ * decl.c (cplus_expand_expr_stmt): Not here.
+
+ * rtti.c (build_dynamic_cast_1): Call non_lvalue.
+ Initialize exprtype earlier.
+
+ * parse.y (fn.def1): Check for defining types in return types.
+
+ * decl.c (check_tag_decl): Notice extra fundamental types.
+ Diagnose empty decls in classes, too.
+
+ * decl.c (grokdeclarator): Don't override an anonymous name if no
+ declarator was given.
+
+ * cvt.c (convert_to_void): Call resolve_offset_ref.
+
+ * typeck.c (build_x_function_call): Abort if we get an OFFSET_REF.
+
+ * decl2.c (decl_namespace): Handle getting a type.
+
+ * typeck.c (build_c_cast): Re-enable warning for cast between
+ pointer and integer of different size.
+
+2000-04-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__pointer_type_info): Add restrict and
+ incomplete flags.
+ (__pointer_type_info::__pointer_catch): New virtual function.
+ (__pointer_to_member_type_info): Derive from
+ __pointer_type_info. Adjust.
+ (__pointer_to_member_type_info::__do_catch): Remove.
+ (__pointer_to_member_type_info::__is_pointer_p): Declare.
+ (__pointer_to_member_type_info::__pointer_catch): Declare.
+ * rtti.c (qualifier_flags): Add restrict flag.
+ (ptmd_initializer): Reorder members.
+ (create_tinfo_types): Expand comments. Reorder
+ ptmd_desc_type_node members.
+ * tinfo2.cc (__pointer_to_member_type_info::__is_pointer_p):
+ Implement.
+ (__pointer_type_info::__do_catch): Move specific code into
+ __pointer_catch. Call it.
+ (__pointer_type_info::__pointer_catch): Non-pointer-to-member
+ specific catch checking. Fix void conversion check.
+ (__pointer_to_member_type_info::__do_catch): Remove.
+ (__pointer_to_member_type_info::__pointer_catch): Implement.
+
+2000-04-10 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * lex.c (init_parse): Remove traces of classof and headof.
+ * decl2.c (flag_operator_names): Default to 1.
+ (lang_decode_option): Do not set it for -ansi.
+
+2000-04-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct lang_decl): Remove main_decl_variant.
+ (DECL_MAIN_VARIANT): Remove.
+ * decl.c (duplicate_decls): Don't set it.
+ (start_function): Likewise.
+ (lang_mark_tree): Don't mark it.
+ * decl2.c (defer_fn): Don't use it.
+ * lex.c (retrofit_lang_decl): Don't set it.
+ * pt.c (tsubst_decl): Likewise.
+ * ptree.c (print_lang_decl): Don't print it.
+ * typeck.c (mark_addressable): Don't use it.
+
+2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: Include <new> and <exception>.
+ (__cxa_vec_ctor): Use __cxa_vec_dtor for cleanup.
+ (__cxa_vec_dtor): Catch dtor exceptions, and rethrow or
+ terminate.
+ (__cxa_vec_delete): Catch dtor exceptions.
+
+2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ Prepend __ to implementation defined names.
+ * inc/typeinfo (type_info): Rename _name to __name.
+ (type_info::type_info): Rename parameter.
+ (type_info::operator==, type_info::operator!=,
+ type_info::before): Likewise.
+ (type_info::is_pointer_p, type_info::is_function_p,
+ type_info::do_catch, type_info::do_upcast): Prepend __. Rename
+ parameters.
+ * inc/cxxabi.h
+ (__fundamental_type_info::__fundamental_type_info) Rename parameters.
+ (__pointer_type_info::__pointer_type_info): Likewise.
+ (__pointer_type_info::is_pointer_p,
+ __pointer_type_info::do_catch): Prepend __. Rename parameters.
+ (__array_type_info::__array_type_info): Rename parameters.
+ (__function_type_info::__function_type_info): Likewise.
+ (__function_type_info::is_function_p): Prepend __.
+ (__enum_type_info::__enum_type_info): Rename parameters.
+ (__pointer_to_member_type_info::__pointer_to_member_type_info):
+ Likewise.
+ (__pointer_to_member_type_info::do_catch): Prepend __. Rename
+ parameters.
+ (__base_class_info::is_virtual_p, is_public_p, offset): Prepend __.
+ (__class_type_info::__class_type_info): Rename parameters.
+ (__class_type_info::sub_kind): Prepend __. Adjust member names.
+ (__class_type_info::upcast_result,
+ __class_type_info::dyncast_result): Prepend __. Move definition
+ into tinfo.cc.
+ (__class_type_info::do_upcast, __class_type_info::do_catch,
+ __class_type_info::find_public_src,
+ __class_type_info::do_dyncast,
+ __class_type_info::do_find_public_src): Prepend __. Rename
+ parameters.
+ (__si_class_type_info::__si_class_type_info): Rename parameters.
+ (__si_class_type_info::do_upcast, __si_class_type_info::do_dyncast,
+ __si_class_type_info::do_find_public_src): Prepent __. Rename
+ parameters.
+ (__vmi_class_type_info::__vmi_class_type_info): Rename parameters.
+ (__vmi_class_type_info::do_upcast, __vmi_class_type_info::do_dyncast,
+ __vmi_class_type_info::do_find_public_src): Prepent __. Rename
+ parameters.
+ (__dynamic_cast): Rename parameters.
+ * tinfo.cc (type_info::is_pointer_p, type_info::is_function_p,
+ type_info::do_catch, type_info::do_upcast): Prepend __.
+ (contained_p, public_p, virtual_p, contained_public_p,
+ contained_nonpublic_p, contained_nonvirtual_p): Adjust.
+ (__class_type_info::do_catch,
+ __class_type_info::do_upcast): Prepend __. Adjust.
+ (__class_type_info::__upcast_result,
+ __class_type_info::__dyncast_result): Move from inc/cxxabi.h.
+ Adjust.
+ (__class_type_info::find_public_src): Prepend __. Adjust.
+ (__class_type_info::do_find_public_src,
+ __si_class_type_info::do_find_public_src,
+ __vmi_class_type_info::do_find_public_src): Likewise.
+ (__class_type_info::do_dyncast,
+ __si_class_type_info::do_dyncast,
+ __vmi_class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_upcast,
+ __si_class_type_info::do_upcast,
+ __vmi_class_type_info::do_upcast): Likewise.
+ (__dynamic_cast): Adjust.
+ * tinfo2.cc (__pointer_type_info::is_pointer_p): Prepend __.
+ (__function_type_info::is_function_p): Likewise.
+ (__pointer_type_info::do_catch): Likewise. Adjust.
+ (__pointer_to_member_type_info::do_catch): Likewise. Adjust.
+ (__throw_type_match_rtti_2): Adjust.
+ (__is_pointer): Adjust.
+
+2000-04-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_COMPLETE_CTOR_IDENTIFIER.
+ (complete_ctor_identifier): New macro.
+ (special_function_kind): Add sfk_copy_constructor and
+ sfk_assignment_operator.
+ (LOOKUP_HAS_IN_CHARGE): Remove.
+ (cons_up_default_function): Rename to ...
+ (implicitly_declare_fn): ... this.
+ * call.c (build_new_method_call): Add in-charge parameters for
+ constructors here.
+ * class.c (add_implicitly_declared_members): Change parameter name
+ from cant_have_assignment to cant_have_const_assignment.
+ Replace calls to cons_up_default_function to implicitly_declare_fn.
+ * cvt.c (ocp_convert): Use complete_ctor_identifier.
+ * decl.c (initialize_predefined_identifiers): Initialize it.
+ (start_function): Use DECL_CONSTRUCTOR_FOR_VBASE_P instead of
+ complex expression.
+ * init.c (expand_default_init): Don't calculate the in-charge
+ parameter here.
+ (build_new_1): Likewise.
+ * lex.c (cons_up_default_function): Move to method.c.
+ * method.c (synthesize_method): Use DECL_DESTRUCTOR_P.
+ (implicitly_declare_fn): New function.
+ * typeck.c (build_static_cast): Use complete_ctor_identifier.
+ (build_modify_expr): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+
+ Under the new ABI, constructors don't return `this'.
+ * cp-tree.h (warn_reorder): Declare.
+ (special_function_kind): New enum.
+ (global_base_init_list): Remove declaration.
+ (emit_base_init): Don't return a value.
+ (check_base_init): Don't declare.
+ (is_aggr_typedef): Likewise.
+ * decl.c (check_special_function_return_type): New function.
+ (return_types): Remove.
+ (grokdeclarator): Use check_special_function_return_type.
+ (start_function): Don't initialize ctor_label under the new ABI.
+ (finish_construtor_body): Don't create a corresponding LABEL_STMT.
+ * init.c (begin_init_stmts): Move to top of file.
+ (finish_init_stmts): Likewise.
+ (warn_reorder): Don't declare.
+ (emit_base_init): Don't create a STMT_EXPR here. Don't return a
+ value.
+ (check_base_init): Remove.
+ (is_aggr_typedef): Likewise.
+ (build_new_1): Don't use the return value of a constructor.
+ * semantics.c (setup_vtbl_ptr): Don't use the return value
+ of emit_base_init.
+ * typeck.c (check_return_expr): Don't magically convert return
+ statements into `return this' in constructors under the new ABI.
+
+ * cp-tree.h (cp_tree_index): Add CPTI_BASE_CTOR_IDENTIFIER,
+ CPTI_BASE_DTOR_IDENTIFIER, and CPTI_DELETING_DTOR_IDENTIFIER.
+ (base_ctor_identifier): New macro.
+ (base_dtor_identifier): Likewise.
+ (deleting_dtor_identifier): Likewise.
+ * decl.c: Don't include obstack.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (struct predefined_identifier): New type.
+ (initialize_predefined_identifiers): New function.
+ (init_decl_processing): Use it.
+ (debug_temp_inits): Remove.
+ (start_method): Don't call preserve_data.
+ (hack_incomplete_structures): Update comment.
+ * init.c (init_init_processing): Don't initialize
+ nelts_identifier.
+ (build_offset_rf): Remove dead code.
+ (build_delete): Use CLASSTYPE_N_BASECLASSES.
+ * search.c (init_search_processing): Don't initialize
+ vptr_identifier.
+
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to elide
+ some sign_compare warnings.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename abi::__vmi_class_type_info members.
+ * inc/cxxabi.h (__vmi_class_type_info): Rename details, n_bases,
+ base_list, detail_masks members to vmi_flags, vmi_base_count,
+ vmi_bases and vmi_flags_masks respectively.
+ (__vmi_class_type_info::vmi_flags_masks): Rename
+ details_unknown_mask to flags_unknown_mask.
+ * tinfo.cc (__class_type_info::do_upcast): Adjust.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (convert_to_base): New function.
+ (get_vbase_offset): Remove. Move into convert_to_base.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.cc (operator=): Use __builtin_strcmp.
+ * tinfo2.cc (before): Likewise.
+
+2000-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename saved_inline to deferred.
+ (DECL_SAVED_INLINE): Rename to ...
+ (DECL_DEFERRED_FN): ... this.
+ (in_function_p): Remove declaration.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ * decl.c (finish_function): Adjust call to mark_inline_for_output.
+ (in_function_p): Remove definition.
+ * decl2.c (saved_inlines): Rename to ...
+ (deferred_fns): ... this.
+ (saved_inlines_used): Rename to ...
+ (deferred_fns_used): ... this.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ (finish_file): Adjust accordingly.
+ (init_decl2): Likewise.
+ * lex.c (cons_up_default_function): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+ (instantiate_decl): Don't set DECL_DEFER_OUTPUT under any
+ circumstances.
+ * rtti.c (get_tinfo_decl): Adjust call to mark_inline_for_output.
+ * semantics.c (expand_body): Defer more functions.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: New file.
+ * Make-lang.in (CXX_LIB2FUNCS): Add it.
+ (vec.o): Build it.
+ * inc/cxxabi.h (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Declare.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (dfs_class_hint_mark): New static function.
+ (dfs_class_hint_unmark): New static function.
+ (class_hint_flags): Use them.
+
+2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * decl2.c: Make flag_honor_std dependent on ENABLE_STD_NAMESPACE.
+
+2000-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (instantiate_decl): Change prototype.
+ * decl2.c (mark_used): Adjust call.
+ * optimize.c (inlinable_function_p): Adjust handling of templates.
+ * pt.c (do_decl_instantiation): Adjust call to instantiate_decl.
+ (do_type_instantiation): Likewise.
+ (instantiate_decl): Defer more templates.
+ (instantiate_pending_templates): Adjust logic to handle inline
+ friend functions.
+
+ * Makefile.in (GGC_H): New variable. Use it throughout in place
+ of ggc.h.
+
+ * call.c: Don't include obstack.h. Include ggc.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (add_candidate): Allocate the z_candidate with ggc_alloc_obj.
+ * decl.c (push_switch): Use xmalloc to allocate the cp_switch.
+ (pop_switch): Free it.
+
+ * decl2.c (grokclassfn): Set TREE_READONLY for PARM_DECLs.
+
+ * dump.c (dequeue_and_dump): Don't try to print the bit_position
+ if we don't have a DECL_FIELD_OFFSET.
+
+Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * optimize.c (calls_setjmp_r): Use setjmp_call_p instead of
+ special_function_p.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cfns.gperf (hash, libc_name_p): Prototype.
+
+ * rtti.c (build_dynamic_cast_1): Constification.
+
+ * search.c (dfs_debug_unmarkedp, dfs_debug_mark): Unhide prototypes.
+
+ * semantics.c (deferred_type_access_control): Prototype.
+
+2000-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ Correct many new ABI issues regarding vbase and vcall offset
+ layout.
+ * cp-tree.h (BINFO_VTABLE): Document.
+ (struct lang_type): Tweak formatting.
+ (BINFO_PRIMARY_BINFO): Add to documentation.
+ (CLASSTYPE_VSIZE): Fix typo in comment.
+ (CLASSTYPE_VBASECLASSES): Update documentation.
+ (BINFO_VBASE_MARKED): Remove.
+ (SET_BINFO_VBASE_MARKED): Likewise.
+ (CLEAR_BINFO_VBASE_MARKED): Likewise.
+ (BINFO_FIELDS_MARKED): Remove.
+ (SET_BINFO_FIELDS_MARKED): Likewise.
+ (CLEAR_BINFO_FIELDS_MARKED): Likewise.
+ (enum access_kind): New enumeration.
+ (num_extra_vtbl_entries): Remove declaration.
+ (size_extra_vtbl_entries): Likewise.
+ (get_vtbl_decl_for_binfo): New function.
+ (dfs_vbase_unmark): Remove declaration.
+ (mark_primary_bases): Likewise.
+ * class.c (SAME_FN): Remove.
+ (struct vcall_offset_data_s): Move definition.
+ (build_vbase_pointer): Use `build', not `build_binary_op', to
+ access the vbase pointer under the new ABI.
+ (build_vtable_entry_ref): Use get_vtbl_decl_for_binfo.
+ (build_primary_vtable): Likewise.
+ (dfs_mark_primary_bases): Move here from search.c.
+ (mark_primary_bases): Likewise.
+ (determine_primary_bases): Under the new ABI, don't make a base
+ class a primary base just because we don't yet have any virtual
+ functions.
+ (layout_vtable_decl): Use get_vtbl_decl_for_binfo.
+ (num_vfun_entries): Remove.
+ (dfs_count_virtuals): Likewise.
+ (num_extra_vtbl_entries): Likewise.
+ (size_extra_vtbl_entries): Likewise.
+ (layout_virtual_bases): Iterate in inheritance graph order under
+ the new ABI.
+ (finish_struct_1): Use TYPE_VFIELD, not CLASSTYPE_VSIZE, to
+ indicate that a vfield is present.
+ (init_class_processing): Initialize access_public_node, etc., from
+ ak_public, etc.
+ (get_vtbl_decl_for_binfo): New function.
+ (dump_class_hierarchy_r): Likewise.
+ (dump_class_hierarchy): Use it.
+ (finish_vtbls): Build the vtbls in inheritance graph order.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (initialize_vtable): Use get_vtbl_decl_for_binfo.
+ (accumulate_vtbl_inits): Add comments explaining why a pre-order
+ walk is required.
+ (dfs_accumulate_vtbl_inits): Set BINFO_VTABLE to the location
+ where the vptr points, even for primary vtables.
+ (build_vtbl_initializer): Adjust handling of vbase and vcall
+ offsets.
+ (build_vcall_and_vbase_vtable_entries): New function.
+ (dfs_build_vbase_offset_vtbl_entries): Remove.
+ (build_vbase_offset_vtbl_entries): Reimplement.
+ (dfs_build_vcall_offset_vtbl_entries): Don't include virtuals that
+ were already handled in a primary base class vtable.
+ (build_vcall_offset_vtbl_entries): Adjust.
+ (build_rtti_vtbl_entries): Adjust.
+ * decl2.c (output_vtable_inherit): Use get_vtbl_decl_for_binfo.
+ * init.c (expand_virtual_init): Simplify.
+ * repo.c (repo_get_id): Use get_vtbl_decl_for_binfo.
+ * rtti.c (create_pseudo_type_info): Adjust calculation of vptr.
+ * search.c (BINFO_ACCESS): New macro.
+ (SET_BINFO_ACCESS): Likewise.
+ (dfs_access_in_type): Manipulate access_kinds, not access nodes.
+ (access_in_type): Likewise.
+ (dfs_accessible_p): Likewise.
+ (protected_accessible_p): Likewise.
+ (lookup_fnfields_1): Adjust documentation.
+ (dfs_mark_primary_bases): Move to class.c
+ (mark_primary_bases): Likewise.
+ (dfs_vbase_unmark): Remove.
+ (virtual_context): Use BINFO_FOR_VBASE.
+ (dfs_get_vbase_types): Simplify.
+ (dfs_build_inheritance_graph_order): New function.
+ (get_vbase_types): Use it.
+ * tree.c (debug_binfo): Use get_vtbl_decl_for_binfo.
+
+ * tinfo.cc (get_vbase_offset): New function.
+ (__vmi_class_type_info::do_find_public_src): Use it.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+2000-03-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (class_hint_flags): Rename flags.
+ (class_initializer): Remove flags.
+ (synthesize_tinfo_var): Combine offset and flags. Add flags
+ for __vmi_class_type_info.
+ (create_tinfo_types): Remove flags from __class_type_info and
+ __si_class_type_info. Merge flags and offset from
+ base_class_type_info.
+ * inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
+ (__base_class_info::is_virtual_p): Adjust.
+ (__base_class_info::is_public_p): Adjust.
+ (__base_class_info::offset): New accessor.
+ (__class_type_info::details): Remove member.
+ (__class_type_info::__class_type_info): Lose details.
+ (__class_type_info::detail_masks): Remove.
+ (__si_class_type_info::__si_class_type_info): Lose details.
+ (__vmi_class_type_info::details): New member.
+ (__vmi_class_type_info::__vmi_class_type_info): Adjust.
+ (__vmi_class_type_info::detail_masks): New member.
+ * tinfo.cc (__class_type_info::do_upcast): Initialize result
+ with unknown_details_mask.
+ (__vmi_class_type_info::do_find_public_src): Adjust
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Set result details, if
+ needed. Adjust.
+ (__dynamic_cast): Temporarily #if out optimization.
+
+2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_tinfo_decl): Mark used.
+ (emit_tinfo_decl): Don't optimize polymorphic type_info. Only
+ mark as dealt with, if we output it.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c: Reorganize to put virtual function table initialization
+ machinery at the end of the file.
+
+2000-03-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (finish_struct): Use bitsize_zero_node.
+ * pt.c (instantiate_class_template): Likewise.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ Put RTTI entries at negative offsets in new ABI.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
+ vbase offset at index -3, not -1.
+ (build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
+ dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
+ (dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
+ (build_rtti_vtbl_entries): New function.
+ (set_rtti_entry): Remove.
+ (build_primary_vtable): Don't use it.
+ (build_secondary_vtable): Likewise.
+ (start_vtable): Remove.
+ (first_vfun_index): New function.
+ (set_vindex): Likewise.
+ (add_virtual_function): Don't call start_vtable. Do call
+ set_vindex.
+ (set_primary_base): Rename parameter.
+ (determine_primary_base): Likewise.
+ (num_vfun_entries): Don't use skip_rtti_stuff.
+ (num_extra_vtbl_entries): Include RTTI information.
+ (build_vtbl_initializer): Use build_rtti_vtbl_entries.
+ (skip_rtti_stuff): Remove.
+ (dfs_modify_vtables): Don't use it.
+ (modify_all_vtables): Don't use start_vtable. Do use set_vindex.
+ (layout_nonempty_base_or_field): Update size handling.
+ (create_vtable_ptr): Tweak.
+ (layout_class_type): Adjust parameter names.
+ (finish_struct_1): Simplify.
+ * cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
+ (skip_rtti_stuff): Remove.
+ (first_vfun_index): New function.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Remove.
+ (marked_vtable_pathp): Declare.
+ (unmarked_vtable_pathp): Likewise.
+ * error.c (dump_expr): Use first_vfun_index to calculate vtable
+ offsets.
+ * rtti.c (build_headof): Look for RTTI at negative offsets.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
+ here.
+ (create_pseudo_type_info): Do it here instead. Adjust so that
+ vptr points at first virtual function.
+ * search.c (marked_vtable_pathp): Make it global.
+ (unmarked_vtable_pathp): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
+ negative offset.
+
+2000-03-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (check_field_decl): Fix typo.
+ (build_vtbl_or_vbase_field): Don't clear DECL_SAVED_INSNS.
+ (check_methods): Likewise.
+ (check_field_decls): Likewise.
+ Use DECL_CONTEXT, not DECL_FIELD_CONTEXT.
+ * cp-tree.h (DECL_SHADOWED_FOR_VAR, DECL_TEMPLATE_RESULT):
+ Use DECL_RESULT_FLD, not DECL_RESULT.
+ * decl.c (xref_tag): Use DECL_TEMPLATE_RESULT.
+ * lex.c (identifier_type): Likewise.
+ * pt.c (determine_specialization, lookup_template_class): Likewise.
+ (tsubst_friend_function, tsubst_decl, instantiate_template): Likewise.
+ (resolve_overloaded_unification, more_specialized): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+
+2000-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_empty_base): Handle empty bases with non-byte
+ alignment.
+ (build_base_field): Likewise.
+ (layout_virtual_bases): Likewise.
+
+ * class.c (finish_struct_1): Fix typo in this change:
+
+ Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+2000-03-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Count partial specializations when
+ keeping track of how many template classes have been seen.
+
+ * dump.c (dequeue_and_dump): Dump DECL_TEMPLATE_RESULT.
+
+2000-03-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_pointer_fields): layout_field now place_field.
+ (get_vfield_offset): Use byte_position.
+ (set_rtti_entry): Set OFFSET to ssizetype zero.
+ (get_binfo_offset_as_int): Deleted.
+ (dfs_record_base_offsets): Use tree_low_cst.
+ (dfs_search_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Reflect changes in RLI format
+ and call byte_position.
+ (layout_empty_base): Convert offset to ssizetype.
+ (build_base_field): use rli_size_unit_so_far.
+ (dfs_propagate_binfo_offsets): Do computation in proper type.
+ (layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
+ (layout_class_type): Reflect changes in RLI names and fields.
+ (finish_struct_1): Set DECL_FIELD_OFFSET.
+ * dump.c (dequeue_and_dump): Call bit_position.
+ * expr.c (cplus_expand_constant): Use byte_position.
+ * rtti.c (expand_class_desc): Use bitsize_one_node.
+ * typeck.c (build_component_addr): Use byte_position and don't
+ special case for zero offset.
+
+2000-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (vtype_decl_p): Use TYPE_POLYMORPHIC_P.
+
+ * rtti.c (get_tinfo_decl): Set comdat linkage on new-abi
+ tinfo object.
+ (emit_tinfo_decl): Only emit polymorphic tinfo's when emitting
+ vtable.
+
+2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * call.c (check_dtor_name, build_new_method_call): Use TYPE_P and
+ DECL_P macros.
+ * decl.c (push_class_binding, poplevel, pushtag, lookup_namespace_name,
+ make_typename_type, check_initializer, cp_finish_decl,
+ xref_tag): Likewise.
+ * decl2.c (grokfield, build_expr_from_tree, build_expr_from_tree,
+ decl_namespace, arg_assoc_template_arg, arg_assoc,
+ validate_nonmember_using_decl, do_class_using_decl): Likewise.
+ * error.c (dump_template_argument, dump_expr, cp_file_of, cp_line_of,
+ args_to_string): Likewise.
+ * friend.c (is_friend): Likewise.
+ * lex.c (note_got_semicolon, note_list_got_semicolon,
+ is_global): Likewise.
+ * method.c (build_overload_nested_name, build_overload_value,
+ build_qualified_name, build_qualified_name, hack_identifier): Likewise.
+ * parse.y (typename_sub, typename_sub1): Likewise.
+ * pt.c (push_inline_template_parms_recursive, check_template_shadow,
+ process_partial_specialization, convert_template_argument,
+ template_args_equal, add_pending_template, lookup_template_class,
+ for_each_template_parm_r, maybe_fold_nontype_arg,
+ tsubst, instantiate_template, type_unification_real, unify,
+ instantiate_pending_templates, set_mangled_name_for_template_decl):
+ Likewise.
+ * repo.c (repo_get_id, repo_template_used): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ * tree.c (walk_tree, get_type_decl, cp_tree_equal, member_p): Likewise.
+ * xref.c (classname): Likewise.
+
+2000-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
+ (CANONICAL_BINFO): New macro.
+ (BINFO_NEW_VTABLE_MARKED): Use it.
+ (SET_BINFO_NEW_VTABLE_MARKED): Likewise.
+ (CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
+ not TREE_TYPE.
+ (build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (build_secondary_vtable): Likewise.
+ (dfs_finish_vtbls): Likewise.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (accumulate_vtbl_inits): New function.
+ (finish_vtbls): Make sure that virtual bases come after
+ non-virtual bases in the vtable group.
+ (record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
+ (finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ * search.c (struct vbase_info): Move definition.
+ (marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (unmarked_new_vtable_p): Likewise.
+ (dfs_mark_vtable_path): Remove.
+ (dfs_mark_new_vtable): Remove.
+ (dfs_unmark_new_vtable): Likewise.
+ (dfs_clear_search_slot): Likewise.
+ (dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (dfs_clear_vbase_slots): Likewise.
+ (init_vbase_pointers): LIkewise.
+
+2000-03-22 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions): Prefer a
+ SIZETYPE to a non-SIZETYPE.
+
+2000-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_virtual_bases): Adjust names in conditionally
+ compiled code.
+
+ * class.c (record_base_offsets): New function.
+ (layout_conflict_p): Likewise.
+ (layout_nonempty_base_or_field): Use it.
+ (layout_empty_base): New function.
+ (build_base_field): Use it.
+ (build_base_fields): Update comment.
+ (layout_virtual_bases): Fold in a little code form
+ layout_basetypes. Use layout_empty_base.
+ (layout_basetypes): Remove.
+ (end_of_class): New function.
+ (layout_class_type): Use it. Adjust.
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Fix typo in comment.
+ (fntype_p): Remove.
+ * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Fix typo in
+ comment.
+ (dfs_skip_nonprimary_vbases_markedp): Likewise.
+ * typeck.c (fntype_p): Remove.
+
+ * cp-tree.h (TI_SPEC_INFO): Remove.
+ (CLASSTYPE_TI_SPEC_INFO): Likewise.
+ * pt.c (process_partial_specialization): Likewise.
+
+ * class.c (build_base_field): Fix thinko in computation of binfo
+ offsets.
+
+ * tree.c (mark_local_for_remap_p): Mark variables declared in
+ TARGET_EXPRs as well.
+
+2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (require_complete_type, complete_type,
+ complete_type_or_else, c_sizeof, c_sizeof_nowarn,
+ build_array_ref, convert_arguments, pointer_diff,
+ build_x_unary_op, build_unary_op, build_c_cast,
+ build_modify_expr): Use COMPLETE_TYPE_P etc.
+ * call.c (is_complete, convert_like_real,
+ build_new_method_call): Likewise.
+ * class.c (build_vbase_pointer_fields, check_bases,
+ build_base_field, finish_struct_1, pushclass): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_void): Likewise.
+ * decl.c (maybe_process_template_type_declaration, pushtag,
+ pushdecl, redeclaration_error_message, start_decl, start_decl_1,
+ layout_var_decl, check_initializer, cp_finish_decl,
+ grokdeclarator, require_complete_types_for_parms,
+ grok_op_properties, xref_tag, xref_basetypes,
+ check_function_type): Likewise.
+ * decl2.c (check_classfn, reparse_absdcl_as_casts): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * parse.y (structsp): Likewise.
+ * pt.c (maybe_process_partial_specialization,
+ tsubst_friend_function, instantiate_class_template, tsubst,
+ do_type_instantiation, instantiate_pending_templates): Likewise.
+ * repo.c (repo_get_id): Likewise.
+ * rtti.c (build_typeid, get_typeid, build_dynamic_cast_1,
+ synthesize_tinfo_var, emit_support_tinfos): Likewise.
+ * search.c (lookup_fnfields_1, lookup_conversions): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * tree.c (build_cplus_method_type): Likewise.
+ * typeck2.c (digest_init, build_functional_cast,
+ add_exception_specifier): Likewise.
+ * parse.h, parse.c: Regenerated.
+
+2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h: New header file. Define new-abi entry points.
+ (__pointer_type_info::target): Rename member to ...
+ (__pointer_type_info::type): ... here.
+ (__base_class_info::type): Rename member to ...
+ (__base_class_info::base): ... here.
+ * Make-lang.in (CXX_EXTRA_HEADERS): Add cxxabi.h
+ * cp-tree.h (CPTI_ABI): New global tree enumeration.
+ (abi_node): New global tree node.
+ * decl.c (abi_node): Document.
+ (init_decl_processing): Initialize abi_node.
+ * rtti.c (build_dynamic_cast_1): Use abi_node for new-abi.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ (emit_support_tinfos): Likewise.
+ * tinfo.h (cxxabi.h): Include for new-abi.
+ Move rtti class definitions to new header file.
+ * tinfo.cc (abi): Use the namespace.
+ (std): Move new abi rtti classes from here ...
+ (__cxxabiv1): ... to here.
+ * tinfo2.cc (cxxabi.h): Include for new-abi.
+ Move rtti class definitions to new header file.
+ (std): Move new abi rtti classes from here ...
+ (__cxxabiv1): ... to here.
+ * inc/typeinfo (__class_type_info): Move into __cxxabiv1
+ namespace.
+
+2000-03-20 Jed Wing <jedwin@zloty.ugcs.caltech.edu>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * method.c (build_overload_int): Use host_integerp.
+
+2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * init.c (build_offset_ref): Handle the case of a templated member
+ function.
+
+2000-03-19 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * except.c (expand_exception_blocks): Clear catch_clauses_last.
+
+2000-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
+ * class.c (check_bitfield_decl): Turn illegal bitfields into
+ non-bitfields.
+ (dfs_propagate_binfo_offsets): Adjust for new size_binop
+ semantics.
+ (dfs_offset_for_unshared_vbases): Likewise.
+ * cvt.c (cp_convert_to_pointer): Convert NULL to a
+ pointer-to-member correctly under the new ABI.
+ * expr.c (cplus_expand_constant): Don't use cp_convert when
+ turning an offset into a pointer-to-member.
+ * init.c (resolve_offset_ref): Don't adjust pointers-to-members
+ when dereferencing them under the new ABI.
+ * typeck.c (get_member_function_from_ptrfunc): Tweak calculation
+ of pointers-to-members under the new ABI.
+
+ * class.c (check_bitfield_decl): Remove restriction on really long
+ bitfields.
+ (layout_class_type): Implement new ABI handling of bitfields
+ longer than their types.
+
+2000-03-18 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (extdefs): Call ggc_collect.
+ * parse.c: Regenerated.
+
+2000-03-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_base_field): Use TYPE_ALIGN to examine a type.
+ (note_name_declared_in_class): Use OVL_CURRENT to get at a
+ potential overload.
+
+2000-03-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_path): Use integer_zerop.
+ (build_vtable_entry): Use tree_low_cst.
+ (get_vfield_offset): Use bit_position.
+ (dfs_modify_vtables): New variable vindex_val; `i' is HOST_WIDE_INT.
+ Use tree_low_cst.
+ (check_bitfield_decl): Set DECL_SIZE using convert.
+ (build_base_field): Set DECL_SIZE and DECL_SIZE_UNIT using size_binop.
+ (layout_virtual_bases): DSIZE is unsigned HOST_WIDE_INT.
+ Use tree_low_cst.
+ (finish_struct_1): Use bit_position.
+ (dump_class_hierarchy): Use tree_low_cst.
+ * cp-tree.h (min_precision): Add declaration.
+ * decl.c (xref_tag, xref_basetypes): Use tree_low_cst.
+ * error.c (dump_type_suffix): Use host_integerp and tree_low_cst.
+ (dump_expr): Use integer_zerop, host_integerp, and tree_low_cst.
+ * expr.c (cplus_expand_constant): Use bit_position.
+ * init.c (build_vec_init): Use host_integerp and tree_low_cst.
+ * rtti.c (get_base_offset): Use bit_position.
+ * typeck.c (build_binary_op): Use integer_zerop, compare_tree_int,
+ host_integerp, and tree_low_cst.
+ (pointer_int_sum): Use integer_zerop.
+ (build_component_addr): Use bit_position.
+
+2000-03-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (require_complete_type): Don't assume size_zero_node.
+ (complete_type_or_else): Likewise.
+
+2000-03-16 Steven Grady <grady@digitaldeck.com>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * rtti.c (build_dynamic_cast_1): Improve diagnostics.
+
+2000-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (grokfield): Bail out if type is error_mark_node.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo2.cc (__ptr_to_member_data): Rename to ...
+ (__pointer_to_member_data): ... here. Adjust.
+ * rtti.c (create_tinfo_types): Adjust.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_REF_DESC_TYPE, ref_desc_type_node): Remove.
+ * decl.c (ref_desc_type_node): Undocument.
+ * rtti.c (ptr_ref_initializer): Rename to ...
+ (ptr_initializer): ... here. Adjust comments.
+ (ptmd_initializer): Fix comment thinko.
+ (synthesize_tinfo_var): Remove REFERENCE_TYPE case.
+ (create_tinfo_types): Remove ref_desc_type_node init.
+ * tinfo2.cc (__reference_type_info): Remove.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Remove obsolete comment.
+
+ * typeck.c (build_ptrmemfunc1): Kill uninitialized warning.
+
+2000-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h: Tweak documentation.
+ * class.c (build_vbase_pointer_fields): Layout the fields, too.
+ (avoid_overlap): Remove.
+ (get_binfo_offset_as_int): New function.
+ (dfs_serach_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Likewise.
+ (build_base_field): Layout fields here. Avoid placing two objects
+ of the same type at the same address, under the new ABI.
+ (build_base_fields): Adjust accordingly.
+ (create_vtable_ptr): Return the new field, but don't attach it to
+ TYPE_FIELDS.
+ (remove_base_field): Remove.
+ (remove_base_fields): Remove.
+ (layout_basetypes): Adjust accordingly.
+ (layout_class_type): Call layout_field for each field, rather than
+ just making a wholesale call to layout_type.
+
+2000-03-14 Jeff Sturm <jsturm@sigma6.com>
+
+ * except.c (expand_throw): Fix typo in _Jv_Sjlj_Throw.
+
+2000-03-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.
+
+ * except.c (dtor_nothrow): New fn.
+ (do_pop_exception): Use it. Take type parm.
+ (push_eh_cleanup): Take type parm.
+ (expand_start_catch_block): Pass it.
+ (build_eh_type_type_ref): Accept null type.
+
+2000-03-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (revert_static_member_fn): Change prototype.
+ * decl.c (grokfndecl): Adjust call to revert_static_member_fn.
+ (grok_op_properties): Likewise.
+ (start_function): Likewise.
+ (revert_static_member_fn): Simplify.
+ * pt.c (check_explicit_specialization): Adjust call to
+ revert_static_member_fn.
+
+2000-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (scope_kind): New type.
+ (tmpl_spec_kind): Likewise.
+ (declare_pseudo_global_level): Remove.
+ (pseudo_global_level_p): Rename to template_parm_scope_p.
+ (pushlevel): Remove declaration.
+ (begin_scope): New function.
+ (finish_scope): Likewise.
+ (current_tmpl_spec_kind): Likewise.
+ * decl.c (struct binding_level): Shorten parm_flag to 2 bits.
+ Shorten keep to 2 bits. Rename pseudo_global to template_parms_p.
+ Add template_spec_p.
+ (toplevel_bindings_p): Adjust.
+ (declare_pseudo_global_level): Remove.
+ (pseudo_global_level_p): Rename to template_parm_scope_p.
+ (current_tmpl_spec_kind): New function.
+ (begin_scope): Likewise.
+ (finish_scope): Likewise.
+ (maybe_push_to_top_level): Adjust.
+ (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ (pushdecl_nonclass_level): Likewise.
+ (lookup_tag): Likewise.
+ (grokfndecl): Handle member template specializations. Share
+ constructor and non-constructor code.
+ * decl2.c (check_classfn): Handle member template specializations.
+ * pt.c (begin_template_parm_list): Use begin_scope.
+ (begin_specialization): Likewise.
+ (end_specialization): Likewise.
+ (check_explicit_specialization): Use current_tmpl_spec_kind.
+ Handle member template specializations.
+ (end_template_decl): Use finish_scope. Remove call to
+ get_pending_sizes.
+ (push_template_decl_real): Remove bogus error message.
+ (tsubst_decl): Fix typo in code contained in comment.
+ (instantiate_template): Handle member template specializations.
+ (most_general_template): Likewise.
+
+2000-03-11 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (whitespace_cr): Compress consecutive calls to warning().
+ (do_identifier): Ditto for error().
+
+ * pt.c (convert_nontype_argument): Ditto for cp_error().
+ (convert_template_argument): Ditto for cp_pedwarn().
+
+2000-03-11 Jason Merrill <jason@casey.cygnus.com>
+
+ * exception.cc (__check_null_eh_spec): New fn.
+ * except.c (expand_end_eh_spec): Call it if the spec is throw().
+
+2000-03-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (push_throw_library_fn): Take the FUNCTION_TYPE.
+ * except.c (expand_end_eh_spec): Add the return type.
+ * rtti.c (throw_bad_cast): Add the parmtypes.
+ (throw_bad_typeid): Likewise.
+
+ * semantics.c (expand_stmt): Only leave out rtl for unused
+ artificials, and set DECL_IGNORED_P on them as well.
+ * decl.c (wrapup_globals_for_namespace): Likewise.
+
+2000-03-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (maybe_commonize_var): Skip all artificial decls.
+ * pt.c (tsubst_decl): Don't copy TREE_ASM_WRITTEN.
+
+2000-03-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * lang-options.h, decl2.c: Add -fno-enforce-eh-specs.
+ * cp-tree.h: Declare flag_enforce_eh_specs.
+ * decl.c (store_parm_decls, finish_function): Check it.
+
+ C library functions don't throw.
+ * Makefile.in (cfns.h): New target.
+ (except.o): Depend on it.
+ * Make-lang.in (cc1plus): Depend on cfns.gperf.
+ * cfns.gperf: New file.
+ * cfns.h: Generated.
+ * except.c: Include it.
+ (nothrow_libfn_p): New fn.
+ * decl.c (grokfndecl): Use it.
+ * cp-tree.h: Declare it.
+
+ * decl.c (push_overloaded_decl_1, auto_function,
+ define_function): Lose.
+ (build_library_fn_1): New static fn.
+ (builtin_function): Use it.
+ (get_atexit_node): Use build_library_fn_ptr.
+ (build_library_fn, build_cp_library_fn, build_library_fn_ptr,
+ build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
+ push_void_library_fn, push_throw_library_fn): New fns.
+ * cp-tree.h: Declare them.
+ (cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
+ (throw_bad_cast_node, throw_bad_typeid_node): Lose.
+ * except.c (init_exception_processing, call_eh_info, do_pop_exception,
+ (expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
+ * rtti.c (build_runtime_decl): Lose.
+ (throw_bad_cast, throw_bad_typeid, get_tinfo_decl,
+ build_dynamic_cast_1, expand_si_desc, expand_class_desc,
+ expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.
+
+ * call.c (build_call): Remove result_type parm.
+ Call mark_used on unused artificial fns.
+ * init.c, method.c, typeck.c, except.c, rtti.c: Adjust.
+
+2000-03-09 Jason Merrill <jason@casey.cygnus.com>
+
+ * call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
+ appropriate.
+ * decl.c (define_function): Set TREE_NOTHROW on the FUNCTION_DECL.
+ * except.c (call_eh_info, alloc_eh_object, expand_throw): Set
+ TREE_NOTHROW or TREE_THIS_VOLATILE on the function as appropriate.
+ * rtti.c (build_runtime_decl, get_tinfo_decl, build_dynamic_cast_1,
+ expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
+ expand_generic_desc): Likewise.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * exception.cc (__cp_pop_exception): Cleanup the original object.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grok_op_properties): Merge conversion to void warning
+ with other silly op warnings.
+
+2000-03-08 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Set TREE_PURPOSE of
+ array CONSTRUCTOR elements. Don't use expr_tree_cons.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_make_fname_decl): New function.
+ (wrapup_globals_for_namespace): Don't emit unused static vars.
+ (init_decl_processing): Remove comment about use of
+ array_domain_type. Set make_fname_decl.
+ (cp_finish_decl): Remove __FUNCTION__ nadgering.
+ * semantics.c (begin_compound_stmt): Remove
+ current_function_name_declared flagging.
+ (expand_stmt): Don't emit unused local statics.
+ * typeck.c (decay_conversion): Don't treat __FUNCTION__ decls
+ specially.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (convert_for_assignment): Don't look at array
+ initializer.
+ * call.c (convert_like_real): Likewise.
+
+2000-03-07 Jason Merrill <jason@casey.cygnus.com>
+
+ Add initial support for '\uNNNN' specifier.
+ * lex.c (read_ucs): New fn.
+ (readescape, skip_white_space): Call it.
+ (is_extended_char, is_extended_char_1): New fns.
+ (utf8_extend_token): New fn, #if 0'd out.
+ (real_yylex): Treat extended chars like letters.
+
+ * search.c (note_debug_info_needed): Walk the bases even if we
+ weren't deferring the type itself.
+
+2000-03-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (finish_objects): Constify a char*.
+
+ * method.c (emit_thunk): Likewise.
+
+2000-03-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (dubious_conversion_warnings): Look through
+ REFERENCE_TYPE.
+
+2000-03-06 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (dfs_modify_vtables): I is now unsigned.
+ (check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
+ (build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
+ * error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
+ * init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
+ * method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
+ * typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
+ Call integer_all_onesp.
+ * typeck2.c (process_init_constructor): Use compare_tree_int.
+
+ * lang-specs.h (as): Don't call if -syntax-only.
+
+2000-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr, case STMT_EXPR): Don't set
+ RTL_EXPR_HAS_NO_SCOPE after all.
+
+2000-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr, case STMT_EXPR): Use
+ expand_start_stmt_expr and expand_end_stmt_expr directly. Set
+ RTL_EXPR_HAS_NO_SCOPE.
+
+ * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG a little
+ later.
+
+ * dump.c (dequeue_and_dump): Dump SCOPE_NO_CLEANUPS_P.
+
+2000-03-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_like): Macrofy.
+ (convert_like_with_context): New macro.
+ (convert_like_real): Renamed from convert_like. Add calling
+ context parameters, for diagnostics. Add recursive flag. Call
+ dubious_conversion_warnings for outer conversion.
+ (build_user_type_conversion): Use convert_like_with_context.
+ (build_over_call): Likewise. Don't warn about dubious
+ conversions here. Adjust convert_default_arg calls.
+ (convert_default_arg): Add context parameters for diagnostics.
+ Pass through to convert_like_with_context.
+ * cp-tree.h (convert_default_arg): Add context parameters.
+ (dubious_conversion_warnings): Prototype new function.
+ * typeck.c (convert_arguments): Adjust convert_default_arg call.
+ (dubious_conversion_warnings): New function, broken
+ out of convert_for_assignment.
+ (convert_for_assignment): Adjust.
+
+2000-03-03 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl2.c (key_method): Break out from...
+ (import_export_vtable, import_export_class): ...here.
+
+ * decl.c (finish_function): Don't mess with flag_keep_inline_functions.
+ * decl2.c (finish_vtable_vardecl): Don't check decl_function_context.
+
+ * search.c (note_debug_info_needed, dfs_debug_mark,
+ dfs_debug_unmarkedp): Uncomment. Adjust for new scheme.
+ * decl2.c (finish_vtable_vardecl): Call note_debug_info_needed.
+
+2000-03-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Remove obsolete obstack comments, fix
+ typos.
+
+2000-03-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_NEEDS_DESTRUCTOR): Rename to ...
+ (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): ... this.
+ (TYPE_HAS_TRIVIAL_DESTRUCTOR): New macro.
+ (lang_type): Split gets_new into has_new and has_array_new.
+ (TYPE_VEC_NEW_USES_COOKIE): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (TYPE_GETS_NEW): Split into ...
+ (TYPE_HAS_NEW_OPERATOR): ... this, and ...
+ (TYPE_HAS_ARRAY_NEW_OPERATOR): ... this.
+ (DECL_ARRAY_DELETE_OPERATOR_P): New macro
+ (build_op_new_call): Don't declare.
+ (build_new_1): Likewise.
+ * call.c (build_op_new_call): Remove.
+ * class.c (check_bases): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ instead of TYPE_NEEDS_DESTRUCTOR.
+ (finish_struct_bits): Likewise.
+ (add_implicitly_declared_members): Likewise.
+ (check_field_decl): Likewise.
+ (check_methods): Set TYPE_VEC_DELETE_TAKES_SIZE here, and set it
+ correctly under the new ABI.
+ * decl.c (start_decl_1): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ instead of TYPE_NEEDS_DESTRUCTOR.
+ (initialize_local_var): Likewise.
+ (destroy_local_var): Likewise.
+ (cp_finish_decl): Likewise.
+ (register_dtor_fn): Likewise.
+ (grok_op_properties): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW. Don't set
+ TYPE_VEC_DELETE_TAKES_SIZE here.
+ (xref_basetypes): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW.
+ (store_parm_decls): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * decl2.c (do_static_destruction): Likewise.
+ * init.c (build_new_1): Make it static.
+ (perform_member_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (expand_cleanup_for_base): Likewise.
+ (get_cookie_size): New function.
+ (build_new_1): Handle array-new cookies correctly under the new
+ ABI.
+ (build_vec_delete_1): Likewise.
+ (build_vec_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (build_delete): Likewise.
+ (build_vec_delete): Handle array-new cookies correctly under the new
+ ABI.
+ * lex.c (do_identifier): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * pt.c (instantiate_class_template): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR.
+ * ptree.c (print_lang_type): Check them.
+ * search.c (context_for_name_lookup): Fix typo in comment.
+ (tree_has_any_destructor_p): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * tree.c (break_out_cleanups): Likewise.
+ (build_cplus_array_test_1): Likewise.
+ (cp_build_qualified_type_real): Likewise.
+ * typeck.c (complete_type): Likewise.
+
+ * g++spec.c (lang_specific_driver): Add -fnew-abi at the start of
+ the command-line, not the end.
+
+2000-03-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG.
+
+2000-03-02 Tom Tromey <tromey@cygnus.com>
+
+ * cp-tree.h (build_java_class_ref): Declare.
+ * init.c (build_java_class_ref): No longer static.
+ * except.c (expand_throw): Generate a Java-style `throw' if the
+ thrown object is a "Java" object.
+ (initialize_handler_parm): Generate a Java-style lookup of
+ exception info if the caught object is a "Java" object.
+ (catch_language, catch_language_init): New globals.
+ (decl_is_java_type): New function.
+ (expand_start_catch_block): Don't call push_eh_info() or
+ push_eh_cleanup() when handling a Java-style "catch". Pass Java
+ class reference to build_catch_block.
+
+2000-03-02 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (comptypes): Treat sizetype like its language equivalent.
+
+2000-03-01 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Reorganize
+ to merge reference/pointer code and fix incorrect warnings.
+
+2000-02-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (protected_accessible_p): Use context_for_name_lookup.
+
+ * init.c (construct_virtual_bases): Fix thinko.
+ * typeck.c (expand_ptrmemfunc_cst): Fix thinko.
+
+2000-03-01 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (current_function_decl): Move to toplev.c.
+
+2000-02-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (fn_type_unification): Unify return type, whenever
+ provided.
+ (get_bindings_real): Only pass return type when necessary.
+ Remove explicit return type check.
+ * class.c (resolve_address_of_overloaded_function): Pass desired
+ return type to fn_type_unification.
+
+2000-02-28 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vtbl_or_vbase_field, check_methods): Don't clear
+ DECL_FIELD_SIZE.
+ (check_bitfield_decl, check_field_decls): Set DECL_SIZE, not
+ DECL_FIELD_SIZE.
+ * rtti.c (expand_class_desc): Likewise.
+ * cp-tree.h (DECL_INIT_PRIORITY): Use underlying union name.
+ (THUNK_VCALL_OFFSET): Likewise.
+ (THUNK_DELTA): Reflect changes in ../tree.h.
+
+2000-02-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (protected_accessible_p): Also allow the access if
+ the member is public in DERIVED. Lose TYPE parm.
+ (friend_accessible_p): Lose TYPE parm.
+ (accessible_p): Adjust.
+
+2000-02-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (dfs_build_vtable_offset_vtbl_entries): Don't use size_binop
+ on things that are not sizes; ssize_binop deleted.
+ Call size_diffop when appropriate.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_primary_vtable, build_secondary_vtable): Likewise.
+ (dfs_set_offset_for_unshared_vbases, dfs_modify_vtables): Likewise.
+ Variable I is HOST_WIDE_INT.
+ (get_vfield_offset): Pass proper types to size_binop.
+ (size_extra_vtbl_entries, layout_virtual_bases): Likewise.
+ (finish_struct_1): Likewise.
+ (skip_rtti_stuff): Arg N is now pointer to signed.
+ (layout_class_type): Use size_zero_node.
+ * cp-tree.h (skip_rtti_stuff): Arg N is pointer to signed.
+ * cvt.c (cp_convert_to_pointer): Pass proper types to size_binop.
+ * decl.c (complete_arry_type): Pass proper types to size_binop.
+ (xref_basetypes): BINFO_OFFSET is sizetype.
+ * error.c (dump_expr): Don't use size_binop non-sizes.
+ * expr.c (cplus_expand_constant): Pass proper types to size_binop.
+ * init.c (construct_virtual_bases): Fix type error.
+ (build_vec_delete_1): Pass proper type to size_binop and don't
+ fold result.
+ * lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype.
+ * rtti.c (get_base_offset): Pass proper type to size_binop.
+ * search.c (dfs_find_vbases): Fix type error.
+ (expand_upcast_fixups): Arg to skip_rtti_stuff is pointer to signed.
+ (dfs_get_vbase_types): BINFO_OFFSET is sizetype.
+ * tree.c (debug_binfo): Variable N is signed.
+ Use HOST_WIDE_INT_PRINT_DEC.
+ * typeck.c (comptypes): sizetype is same as equivalent integer type.
+ (c_sizeof, c_sizeof_nowarn, expr_sizeof): Use TYPE_SIZE_UNIT,
+ size_one_node and size_zero_node.
+ (c_alignof): Use size_one_node.
+ (build_component_addr): Pass proper types to size_binop.
+ (expand_ptrmemfunc_cst): Don't use size_binop on non-sizes.
+
+2000-02-26 Jason Merrill <jason@casey.cygnus.com>
+
+ Implement class scope using-declarations for functions.
+ * class.c (handle_using_decl): Call add_method for used functions.
+ Use IDENTIFIER_CLASS_VALUE to check for conflicts.
+ (add_method): Used functions are hidden by local functions.
+ (check_bases_and_members): Handle using-decls before finalizing
+ CLASSTYPE_METHOD_VEC.
+ * call.c (add_function_candidate): Add ctype parm; if nonzero,
+ override the type of 'this' accordingly.
+ (add_template_candidate, add_template_candidate_real): Add ctype parm.
+ (convert_class_to_reference, build_user_type_conversion_1,
+ build_new_function_call, build_object_call, build_new_op,
+ build_new_method_call): Pass ctype parm.
+
+ * search.c (lookup_member): Put rval_binfo, not basetype_path, in
+ the baselink.
+ * call.c (convert_class_to_reference, build_user_type_conversion_1,
+ build_new_function_call, build_object_call, build_new_op,
+ build_new_method_call, build_op_delete_call): Don't get basetype_path
+ from a baselink.
+ * typeck.c (build_component_ref): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ (resolve_offset_ref): Don't call enforce_access.
+ Call build_scoped_ref.
+ * typeck2.c (build_scoped_ref): Simplify. Do nothing if it
+ would cause an error or if -pedantic.
+ * class.c (alter_access): Lose binfo parm.
+
+2000-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (simplify_aggr_init_exprs_p): Don't walk into
+ types.
+
+2000-02-25 Alfred Minarik <a8601248@unet.univie.ac.at>
+
+ * rtti.c (get_vmi_pseudo_type_info): Move __vmi_class_type_info
+ pseudo_type_info creation into the std namespace
+
+2000-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak to correct usage before EOF.
+ (import_export_class): Remove declaration.
+ * decl2.c (import_export_class): Make it static.
+ * dump.c (dequeue_and_dump): Handle PREDECREMENT_EXPR,
+ PREINCREMENT_EXPR, POSTDECREMENT_EXPR, POSTINCREMENT_EXPR,
+ EXPR_WITH_FILE_LOCATION.
+ * lex.c (check_newline): Tweak filename/lineno setting.
+ * semantics.c (begin_while_stmt): Fix typo in comment.
+
+2000-02-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * lang-options.h (-fmessage-length=): Add missing option.
+
+ * Make-lang.in (CXX_SRCS): Add .h files and sort list.
+
+2000-02-26 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in: Delete refs to LIBGCC2_DEPS.
+
+2000-02-25 Jim Wilson <wilson@cygnus.com>
+
+ * optimize.c (expand_call_inline): Emit the return label before
+ evaluating the return value.
+
+2000-02-24 Mark Mitchell <mark@codesourcery.com>
+
+ * lex.c (check_newline): Use push_srcloc and pop_srcloc, rather
+ than duplicating functionality here.
+ * optimize.c: Include input.h.
+ (expand_call_inline): Use push_srcloc and pop_srcloc.
+ * parse.y (maybe_cv_qualifier): Remove calls to emit_line_note.
+ * parse.c: Regenerated.
+ * Makefile.in (lex.o): Depend on input.h.
+ (optimize.o): Likewise.
+
+2000-02-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Diagnose qualifiers on non-member
+ function type, rather than ICE.
+
+2000-02-23 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokdeclarator): Call decl_type_access_control.
+ * parse.y (parse_end_decl): Don't call decl_type_access_control if
+ decl is null.
+
+2000-02-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (decls_match): Remove obsolete static member nadgering.
+
+2000-02-21 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Change ANSI to ISO.
+ * lex.c (consume_string, readescape, do_identifier): Likewise.
+ (parse_float, real_yylex): Likewise.
+ * parse.y (paren_expr_or_null, paren_cond_or_null): Likewise.
+ (unary_expr, new_initializer, cast_expr, primary, primary_no_id,
+ new_type_id, maybe_label_decls, simple_stmt,
+ for.init.statement): Likewise.
+ * pt.c (do_decl_instantiation, do_type_instantiation): Likewise.
+ * semantics.c (finish_named_return_value): Likewise.
+ * parse.c: Regenerate.
+
+2000-02-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CPTI_VTABLE_INDEX_TYPE): New macro.
+ (CPTI_CLASS_STAR_TYPE): Remove.
+ (vtable_index_type): Likewise.
+ (class_star_type_node): Remove.
+ (TYPE_PTRMEMFUNC_FN_TYPE): Adjust for the new ABI.
+ (build_binary_op_nodefault): Remove.
+ * call.c (build_new_op): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ * decl.c (init_decl_processing): Remove class_star_type_node
+ initialization. Make delta_type_node ptrdiff_type_node under the
+ new ABI. Initialize vtable_index_type.
+ (build_ptrmemfunc_type): Build different structures for the new
+ ABI.
+ (build_enumerator): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ * method.c (build_overload_value): Mangle pointers-to-members
+ appropriately under the new ABI.
+ * typeck.c (build_array_ref): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ (get_member_function_from_ptrfunc): Adjust for the new ABI.
+ (build_binary_op_nodefault): Rename to ...
+ (build_binary_op): ... this. Remove old version. Adjust for
+ pointer-to-member comparisons under the new ABI.
+ (build_ptrmemfunc1): Remove dead code. Adjust for the new ABI.
+ (build_ptrmemfunc): Adjust for the new ABI.
+ (expand_ptrmemfunc_cst): Likewise.
+ (delta2_from_ptrmemfunc): Assert that we're not using the new ABI.
+ (pfn_from_ptrmemfunc): Adjust for the new ABI.
+
+2000-02-21 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * call.c (build_object_call): Compress consecutive calls to
+ cp_error.
+ (build_conditional_expr): Say 'ISO C++' not 'ANSI C++'.
+ (build_op_delete_call): Adjust message formatting.
+
+ * class.c (check_bases): Compress consecutive calls to
+ cp_pedwarn.
+ (finish_struct_anon): Say 'ISO C++'.
+
+ * decl.c (start_decl): Same here.
+ (grok_reference_init): Likewise.
+ (grokfndecl): Correct message formatting.
+ (grokfndecl): Improve diagnostic.
+ (check_static_variable_definition): Likewise. Say 'ISO C++'
+ (compute_array_index_type): Say 'ISO C++'
+ (create_array_type_for_decl): Compress consecutive calls to
+ cp_error.
+ (grokdeclarator): Say 'ISO C++'
+ (grok_op_properties): Likewise.
+
+ * decl2.c (delete_sanity): Clairify diagnostic.
+ (check_member_template): Same here.
+ (grok_function_init): Use consistent terminology.
+
+ * expr.c (do_case): Say 'ISO C++'
+
+ * friend.c (do_friend): Compress consecutive calls to warning.
+
+2000-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (merge_primary_and_secondary_vtables_p): New macro.
+ * class.c (build_secondary_vtable): Reorganize. Don't create a
+ new vtable under the new ABI.
+ (layout_vtable_decl): Don't add num_extra_vtbl_entries when
+ computing the size.
+ (build_vtbl_initializer): Don't return a CONSTRUCTOR; just return
+ the initializing elements.
+ (initialize_vtable): New function.
+ (dfs_finish_vtbls): Use it.
+ (dfs_accumulate_vtbl_inits): New function.
+ (finish_vtbls): Merge primary and secondary vtables under the new
+ ABI.
+ (finish_struct_1): Remove redundant call to layout_vtable_decl.
+ * init.c (expand_virtual_init): Deal with BINFO_VTABLEs that
+ aren't VAR_DECLs.
+
+ * class.c (build_vtable): New function, split out from ...
+ (get_vtable_decl): ... here, and ...
+ (build_secondary_vtable): ... here.
+
+ * pt.c (tsubst_decl): Fix formatting.
+
+2000-02-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_primary_vtable, layout_vtable_decl): Likewise.
+ (avoid_overlap, build_base_field): Likewise.
+ (build_base_field, build_base_fields, is_empty_class):
+ Test DECL_SIZE with integer_zero.
+ (layout_class_type): Set CLASSTYPE_SIZE_UNIT.
+ * cp-tree.h (struct lang_type): New field size_unit.
+ (CLASSTYPE_SIZE_UNIT): New macro.
+ * decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
+ (cp_finish_decl): Delete -Wlarger-than processing.
+ * optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
+ * pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
+ * tree.c (make_binfo): binfo vector is one entry longer.
+ (walk_tree): Walk DECL_SIZE_UNIT.
+
+2000-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (dfs_build_vcall_offset_vtbl_entries): Fix typo in
+ comment.
+ (build_vtable_entry): Don't assume all vtable entries are
+ functions.
+ (build_vtbl_initializer): Adjust accordingly.
+ (get_vtable_decl): Fix formatting.
+
+2000-02-18 Jason Merrill <jason@casey.cygnus.com>
+
+ * semantics.c (deferred_type_access_control): Walk the entire
+ type_lookups list.
+ (save_type_access_control): Rename from
+ initial_deferred_type_access_control. Just remember the value.
+ (decl_type_access_control): New fn.
+ (begin_function_definition): Use deferred_type_access_control, after
+ we've started the function. Set type_lookups to error_mark_node.
+ * parse.y (frob_specs, fn.def1): Adjust.
+ (parse_decl0, parse_field, parse_field0, parse_bitfield): New fns.
+ (parse_end_decl, parse_bitfield0, parse_method): New fns.
+ (fn.def2, initdcl, initdcl0_innards, nomods_initdcl0): Use them.
+ (after_type_component_declarator0): Likewise.
+ (after_type_component_declarator): Likewise.
+ (notype_component_declarator): Likewise.
+ * cp-tree.h: Adjust.
+
+ * decl.c (redeclaration_error_message): Allow redeclaration of
+ namespace-scope decls.
+
+2000-02-18 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * typeck2.c (my_friendly_abort): Use GCCBUGURL.
+
+2000-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Don't set DECL_VIRTUAL_CONTEXT.
+ * decl2.c (grokclassfn): Likewise.
+
+ * ir.texi: Document DECL_TEMPLATE_INSTANTIATIONS.
+
+ * decl2.c (lang_decode_option): Don't set default message length
+ here.
+ * lex.c (lang_init_options): Set it here.
+
+2000-02-16 Mark Mitchell <mark@codesourcery.com>
+
+ Make DECL_CONTEXT mean the class in which a member function was
+ declared, even for a virtual function.
+ * cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
+ (DECL_FRIEND_CONTEXT): New macro.
+ (DECL_REAL_CONTEXT): Remove.
+ (SET_DECL_FRIEND_CONTEXT): Likewise.
+ (DECL_VIRTUAL_CONTEXT): Adjust.
+ (DECL_CLASS_SCOPE_P): Use TYPE_P.
+ (add_friends): Remove.
+ (hack_decl_function_context): Likewise.
+ * call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
+ CP_DECL_CONTEXT.
+ (build_over_call): Fix indentation. Use DECL_CONTEXT
+ instead of DECL_CLASS_CONTEXT.
+ * class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
+ (build_base_field): Likewise.
+ (finish_struct_1): Likewise.
+ (build_self_reference): Likewise.
+ * decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (pushtag): Use decl_function_context, not
+ hack_decl_function_context.
+ (decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ (duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
+ (pushdecl): Remove bogus code.
+ (start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
+ (cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ (grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ Use decl_function_context, nothack_decl_function_context.
+ (grokvardecl): Don't set DECL_CLASS_CONTEXT.
+ (grokdeclarator): Likewise. Use decl_function_context, not
+ hack_decl_function_context.
+ (copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
+ (start_function): Use DECL_FRIEND_CONTEXT, not
+ DECL_CLASS_CONTEXT. Use decl_function_context, not
+ hack_decl_function_context.
+ (finish_function): Use decl_function_context, not
+ hack_decl_function_context.
+ (maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
+ (finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
+ (grokfield): Likewise.
+ (finish_builtin_type): Likewise.
+ (finish_vtable_vardec): Use decl_function_context, not
+ hack_decl_function_context.
+ (import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (start_static_initialization_or_destruction): Likewise.
+ (finish_static_initialization_or_destruction): Likewise.
+ (mark_used): Adjust logic for deciding when to synthesize methods.
+ * dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ * error.c (dump_function_decl): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * friend.c (is_friend): Likewise.
+ (add_friends): Remove.
+ (do_friend): Use SET_DECL_FRIEND_CONTEXT.
+ * lex.c (begin_definition_of_inclass_inline): Use
+ decl_function_context, not hack_decl_function_context.
+ (process_next_inline): Likewise.
+ (do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ * method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
+ DECL_CLASSS_CONTEXT.
+ (hack_identifier): Likewise.
+ (synthesize_method): Use decl_function_context, not
+ hack_decl_function_context.
+ * pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (is_member_template): Use decl_function_context, not
+ hack_decl_function_context. Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (check_default_tmpl_args): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (push_template_decl_real): Likewise.
+ (instantiate_class_template): Don't call add_friends.
+ (tsubst_default_argument): Use DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
+ Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * repo.c (repo_inline_used): Likewise.
+ * search.c (current_scope): Adjust for new _CONTEXT macros.
+ (context_for_name_lookup): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (lookup_fnfields_here):Likewise.
+ (check_final_overrider): Likewise.
+ (init_vbase_pointers): Likewise.
+ (virtual_context): Likewise.
+ * semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
+ (expand_body): Use decl_function_context, not
+ hack_decl_function_context.
+ * tree.c (hack_decl_function_context): Remove.
+ * typeck.c (build_x_function_call): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * typeck2.c (error_not_base_type): Likewise.
+
+2000-02-15 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (xref_tag): Don't SET_IDENTIFIER_NAMESPACE_VALUE.
+
+2000-02-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g++spec.o): Depend on $(GCC_H), not gcc.h.
+
+2000-02-15 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * lang-specs.h: Add new __GNUC_PATCHLEVEL__ define to default spec.
+
+2000-01-16 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Enable automatic line wrapping.
+
+2000-02-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * parse.y (frob_specs): Split out...
+ (parse_decl): From here.
+ (fn.def2): Call initial_deferred_type_access_control.
+ (after_type_component_declarator0): Call frob_specs.
+ (notype_component_declarator0): Likewise.
+ * search.c (friend_accessible_p): Nested classes are friends of their
+ enclosing classes.
+
+2000-02-10 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi (ADDR_EXPR): Document the fact that an ADDR_EXPR can be
+ used to create an implicit temporary.
+
+ * class.c (dfs_modify_vtables): Tweak calculation of functions to
+ override.
+
+2000-02-08 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (strip_all_pointer_quals): Use TYPE_MAIN_VARIANT, to
+ strip array element qualifiers too.
+
+2000-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (store_parm_decls): Don't build cleanups for parameters
+ while processing_template_decl.
+
+2000-02-07 Jason Merrill <jason@casey.cygnus.com>
+
+ * cp-tree.h (struct saved_scope): Add incomplete field.
+ (namespace_scope_incomplete): New macro.
+ * decl.c (pushdecl): Use it.
+ (hack_incomplete_structures): Use it. See through artificial
+ binding levels.
+ (mark_saved_scope): Mark it.
+
+ Implement access control for nested types.
+ * search.c (type_access_control): New fn.
+ (accessible_p): Now we do perform access control for types.
+ * semantics.c (deferred_type_access_control): New fn.
+ (initial_deferred_type_access_control): New fn.
+ (begin_function_definition): Call it. Add lookups parm.
+ * decl.c (struct binding_level): Add this_class field.
+ (pushlevel_class): Set it.
+ (mark_binding_level): Mark it.
+ (lookup_name_real): Use it. Call type_access_control.
+ (mark_saved_scope): Mark lookups field.
+ * cp-tree.h (flagged_type_tree): Add lookups field.
+ (struct saved_scope): Add lookups field.
+ (type_lookups): New macro.
+ * parse.y (declmods): Now <ftype>.
+ (parse_decl): Add lookups parm. Call
+ initial_deferred_type_access_control.
+ (lang_extdef): Clear type_lookups.
+ (typed_declspecs, declmods, typespec): Set lookups field.
+ (initdcl): Call deferred_type_access_control.
+ (fn.def1, fn.def2, typed_declspecs1, initdcl0_innards, nomods_initdcl0,
+ component_decl_1, named_parm): Adjust.
+ * friend.c (is_friend): Nested classes are friends of their
+ enclosing classes.
+
+ * class.c (currently_open_derived_class): New fn.
+ * method.c (hack_identifier): Use it.
+
+ * lex.c (do_identifier): Remove obsolete code.
+
+ * parse.y (typed_typespecs): Propagate new_type_flag properly.
+
+2000-02-05 Zack Weinberg <zack@wolery.cumb.org>
+
+ * tinfo.h: Remove apostrophes from C++ comment (xgettext
+ thinks this file is plain C).
+
+2000-02-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (call.o): Depend on $(EXPR_H).
+
+ * call.c: Include "expr.h".
+
+ * class.c (dump_class_hierarchy): Add prototype.
+
+ * search.c (dfs_get_pure_virtuals): Likewise.
+
+2000-02-1 Ulrich Drepper <drepper@redhat.com>
+
+ * parse.y (simple_stmt): Allow :: token in asm parameter list.
+ * parse.c: Rebuilt.
+
+2000-01-31 Jim Wilson <wilson@cygnus.com>
+
+ * class.c (build_vtbl_or_vbase_field): New parameter fcontext.
+ Store it in DECL_FCONTEXT.
+ (build_vbase_pointer_fields, create_vtable_ptr): Fix callers.
+
+2000-01-31 Jason Merrill <jason@casey.cygnus.com>
+
+ * tinfo.h (old abi): #include "tconfig.h".
+ * tinfo.cc (convert_to_base): Move into old abi section.
+
+2000-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_VIRTUALS): Tweak documentation.
+ (CLASSTYPE_PRIMARY_BINFO): Use BINFO_PRIMARY_BINFO.
+ (BINFO_PRIMARY_BINFO): New macro.
+ (BF_DELTA): Rename to ...
+ (BV_DELTA): ... this.
+ (BF_VCALL_INDEX): Rename to ...
+ (BV_VCALL_INDEX): ... this.
+ (BF_FN): Rename to ...
+ (BV_FN): ... this.
+ * class.c (build_vbase_path): Adjust for changes to reverse_path.
+ (set_rtti_entry): Rename BF_ macros to BV_ variants.
+ (modify_vtable_entry): Simplify.
+ (add_virtual_function): Rename BF_ macros to BV_ variants.
+ (build_vtable_initializer): Likewise.
+ (get_class_offset_1): Remove.
+ (dfs_get_class_offset): Likewise.
+ (get_class_offset): Likewise.
+ (dfs_find_final_overrider): New function.
+ (find_final_overrider): Likewise.
+ (modify_one_vtable): Remove.
+ (dfs_find_base): New function.
+ (dfs_modify_vtables): Fold modify_one_vtable in here. Use
+ find_final_overrider.
+ (modify_all_vtables): Adjust. Set BV_VCALL_INDEX on new
+ virtuals.
+ (dfs_fixup_vtable_deltas): Remove.
+ (override_one_vtable): Remove.
+ (merge_overrides): Likewise.
+ (layout_virtual_bases): Make sure BINFO_OFFSET is set right for
+ unreal chilren of virtual bases.
+ (finish_struct_1): Don't use merge_overrides. Don't use
+ dfs_fixup_vtable_deltas.
+ * tree.c (reverse_path): Return a TREE_LIST, not a chain of
+ BINFOs.
+
+2000-01-31 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+ Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.h: Rename USItype to myint32, depend on BITS_PER_UNIT.
+
+2000-01-31 Alfred Minarik <a8601248@unet.univie.ac.at>
+
+ * exception.cc (__throw_bad_typeid): Add missing std::.
+
+2000-01-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (make_thunk): PROTO -> PARAMS.
+
+2000-01-31 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (new_abi_rtti_p): Use flag_new_abi.
+
+ Runtime support for new-abi rtti.
+ * inc/typeinfo (type_info::operator!=): Define in class.
+ (type_info::before, type_info::name, type_info::operator==,
+ type_info::operator!=): Define new ABI implementations.
+ (type_info::is_pointer_p, type_info::is_function_p): Declare
+ new virtual functions.
+ (type_info::do_catch, type_info::do_upcast): Likewise.
+
+ * tinfo.h (__base_class_info): Define new class.
+ (__class_type_info): Likewise.
+ (__si_class_type_info): Likewise.
+ (__vmi_class_type_info): Likewise.
+ (__dynamic_cast): Prototype.
+
+ * tinfo.cc: Conditionalize old and new rtti mechanisms.
+ (type_info::is_pointer_p): Define new function.
+ (type_info::is_function_p): Likewise.
+ (type_info::do_catch): Likewise.
+ (type_info::do_upcast): Likewise.
+ (vtable_prefix): New structure for vtable access.
+ (adjust_pointer): Define new template function.
+ (contained_p, public_p, virtual_p, contained_public_p,
+ contained_nonpublic_p, contained_nonvirtual_p): Define new
+ functions.
+ (nonvirtual_base_type): New local variable.
+ (__class_type_info::~__class_type_info): Define.
+ (__si_class_type_info::~__si_class_type_info): Likewise.
+ (__vmi_class_type_info::~__vmi_class_type_info): Likewise.
+ (__class_type_info::do_catch): Define new function.
+ (__class_type_info::do_upcast): Likewise.
+ (__class_type_info::find_public_src): Likewise.
+ (__class_type_info::do_find_public_src): Likewise.
+ (__si_class_type_info::do_find_public_src): Likewise.
+ (__vmi_class_type_info::do_find_public_src): Likewise.
+ (__class_type_info::do_dyncast): Likewise.
+ (__si_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_upcast): Likewise.
+ (__si_class_type_info::do_upcast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+ (__dynamic_cast): Likewise.
+
+ * tinfo2.cc (__fundamental_type_info): Define new class.
+ (__pointer_type_info): Likewise.
+ (__reference_type_info): Likewise.
+ (__array_type_info): Likewise.
+ (__function_type_info): Likewise.
+ (__enum_type_info): Likewise.
+ (__ptr_to_member_type_info): Likewise.
+ (__fundamental_type_info::~__fundamental_type_info): Define.
+ (__pointer_type_info::~__pointer_type_info): Likewise.
+ (__reference_type_info::~__reference_type_info): Likewise.
+ (__array_type_info::~__array_type_info): Likewise.
+ (__function_type_info::~__function_type_info): Likewise.
+ (__enum_type_info::~__enum_type_info): Likewise.
+ (__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise.
+ (__pointer_type_info::do_catch): Define new function.
+ (__ptr_to_member_type_info::do_catch): Define new function.
+
+ (__throw_type_match_rtti_2): Use new ABI interface, if enabled.
+ (__is_pointer): Likewise.
+
+ * exception.cc (__cplus_type_matcher): Deal with new-abi rtti.
+
+2000-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (build_vtable): Rename to build_primary_vtable.
+ (prepare_fresh_vtable): Rename to build_secondary_vtable.
+ (make_new_vtable): New function.
+ (modify_vtable_entry): Handle generation of new vtables correctly.
+ (modify_one_vtable): Remove unused parameter.
+ (dfs_fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Use build_secondary_vtable.
+ (finish_struct_1): Use build_primary_vtable and
+ build_secondary_vtable.
+
+2000-01-28 Ulrich Drepper <drepper@redhat.com>
+
+ * cp/decl.c: Adjust variable names, comments, help strings.
+
+2000-01-29 Nathan Sidwell <nathan@acm.org>
+
+ * new2.cc (operator delete[]): Use operator delete, don't assume
+ implementation.
+
+2000-01-29 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Add argument to
+ build_vtable_entry call.
+
+2000-01-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Discuss vcall indices.
+ * cp-tree.h (BINFO_VIRTUALS): Update documentation.
+ (BF_DELTA): New macro.
+ (BF_VCALL_INDEX): Likewise.
+ (BF_FN): Likewise.
+ (THUNK_VCALL_OFFSET): Likewise.
+ (make_thunk): Change prototype.
+ * class.c (build_vtable_entry): Integrate
+ build_vtable_entry_for_fn. Handle vcall indices.
+ (build_vtable_entry_for_fn): Remove.
+ (set_rtti_entry): Handle vcall indices. Use BF_DELTA,
+ BF_VCALL_INDEX, BF_FN.
+ (modify_vtable_entry): Integrate common code from
+ modify_one_vtable and dfs_fixup_vtable_deltas.
+ (add_virtual_function): Set BF_VCALL_INDEX.
+ (build_vtbl_initializer): Simplify. Use BF_DELTA, BF_VCALL_INDEX,
+ and BF_FN.
+ (modify_one_vtable): Simplify.
+ (dfs_fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Use BF_DELTA, BF_VCALL_INDEX, BF_FN.
+ * method.c (make_thunk): Handle vcall indices.
+
+2000-01-28 Nathan Sidwell <sidwell@codesourcery.com>
+
+ Compiler side new abi rtti (not enabled).
+ * cp-tree.h (new_abi_rtti_p): New macro.
+ (emit_support_tinfos): Prototype new function.
+ (tinfo_decl_p): Likewise.
+ (emit_tinfo_decl): Likwise.
+ * rtti.c (TINFO_PSEUDO_TYPE, TINFO_VTABLE_DECL): New accessor
+ macros.
+ (doing_runtime): New local static.
+ (init_rtti_processing): Add new-abi initializer.
+ (get_tinfo_decl): Add new-abi logic.
+ (tinfo_from_decl): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (qualifier_flags): New static function.
+ (tinfo_base_init): Likewise.
+ (generic_initializer): Likewise.
+ (ptr_ref_initializer): Likewise.
+ (ptmd_initializer): Likewise.
+ (class_hint_flags): Likewise.
+ (class_initializer): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ (create_real_tinfo_var): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ (emit_support_tinfos): New global function.
+ (tinfo_decl_p): New global predicate.
+ (emit_tinfo_decl): New global function.
+ * class.c (set_rtti_entry): Generalize for old and new rtti.
+ (build_vtbl_initializer): Likewise.
+ * decl2.c (finish_file): Likewise.
+
+2000-01-27 Jim Wilson <wilson@cygnus.com>
+
+ * optimize.c (remap_decl): Add walk_tree calls for DECL_SIZE (t)
+ and TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))).
+
+2000-01-27 Mike Stump <mrs@wrs.com>
+
+ * decl.c (pushdecl): Fix up shadow warnings with respect to implicit
+ for scopes.
+
+2000-01-26 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (unify): Use fold, not maybe_fold_nontype_arg.
+
+2000-01-26 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * optimize.c (calls_setjmp_r): Supply new argument
+ to special_function_p.
+
+2000-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: PROTO -> PARAMS.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl.h: Likewise.
+ * decl2.c: Likewise.
+ * dump.c: Likewise.
+ * errfn.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * init.c: Likewise.
+ * input.c: Likewise.
+ * lex.c: Likewise.
+ * lex.h: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+ * xref.c: Likewise.
+
+2000-01-25 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Remove UNNE_EXPR.
+
+2000-01-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (vcall_offset_in_vtable_p): New macro.
+ * class.c (build_vbase_offset_vtbl_entries): Fix typo in commment.
+ (struct vcall_offset_data_s): New type.
+ (dfs_vcall_offset_queue_p): New function.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_vcall_offset_vtbl_entries): Likewise.
+ (layout_vtable_decl): Likewise.
+ (num_vfun_entries): Likewise.
+ (num_extra_vtbl_entries): Add the entries for vcall offsets.
+ (build_vtbl_initializer): Likewise.
+ (dfs_finish_vtabls): Use layout_vtable_decl.
+ (modify_one_vtables): Always duplicate vtables under the new ABI.
+ (finish_struct_1): Use layout_vtable_decl.
+
+2000-01-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (member_function_or_else): Change third arg from a format
+ specifier to an `enum overload_flags'. Callers changed.
+
+2000-01-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * typeck.c (composite_pointer_type, c_sizeof, expr_sizeof,
+ build_binary_op_nodefault, build_unary_op, build_reinterpret_cast,
+ build_const_cast, get_delta_difference, check_return_expr): Avoid
+ ANSI string concatenation usage.
+
+2000-01-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Put the fields required to make a
+ class non-empty at the end, not the beginning, of the TYPE_FIELDs
+ list.
+
+2000-01-24 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (maybe_fold_nontype_arg): Do nothing if we're not in a
+ template.
+
+ * decl2.c (mark_used): Do instantiate inlines that have been
+ explicitly instantiated.
+
+2000-01-24 Richard Henderson <rth@cygnus.com>
+
+ * call.c (build_over_call): Use expand_tree_builtin.
+ * typeck.c (build_function_call_real): Likewise.
+ (build_binary_op_nodefault): Handle unordered compares.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (CPTI_BAD_CAST, CPTI_BAD_TYPEID, CPTI_DCAST): New
+ cp_tree_index values.
+ (throw_bad_cast_node, throw_bad_typeid_node, dynamic_cast_node):
+ New global node #defines for them.
+ * rtti.c (call_void_fn): Replace with ...
+ (build_runtime_decl): ... new static function.
+ (throw_bad_cast): Use throw_bad_cast_node and build_runtime_decl.
+ (throw_bad_typeid): Use throw_bad_typeid_node and build_runtime_decl.
+ (build_dynamic_cast_1): Always produce correctly typed result.
+ Explicitly produce type_info addresses. Use dynamic_cast_node.
+ * exception.cc (__throw_bad_cast): Return `void *'.
+ (__throw_bad_typeid): Return `const type_info &'.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (get_vtable_decl): Prototype new function.
+ * class.c (get_vtable_decl): New function. Broken out from ...
+ (build_vtable): ... here. Use it.
+ * decl2.c (finish_vtable_vardecl): Ignore dummy vtables created
+ by get_vtable_decl.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (CPTI_TP_DESC_TYPE, CPTI_ACCESS_MODE_TYPE,
+ CPTI_USER_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_ATTR_DESC_TYPE,
+ CPTI_PTMF_DESC_TYPE): Remove cp_tree_index enumerations.
+ (CPTI_TI_DESC_TYPE, CPTI_REF_DESC_TYPE, CPTI_ARY_DESC_TYPE,
+ CPTI_ENUM_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_SI_CLASS_DESC_TYPE,
+ CPTI_VMI_CLASS_DESC_TYPE, CPTI_BASE_DESC_TYPE): New enumerations.
+ (CPTI_TINFO_FN_ID, CPTI_TINFO_FN_TYPE): Rename to ...
+ (CPTI_TINFO_DECL_ID, CPTI_TINFO_DECL_TYPE): ... here.
+ (CPTI_TINFO_VAR_ID): New enumeration.
+ (__tp_desc_type_node, __access_mode_type_node,
+ __bltn_desc_type_node, __user_desc_type_node,
+ __class_desc_type_node, __ptr_desc_type_node,
+ __attr_desc_type_node, __func_desc_type_node,
+ __ptmf_desc_type_node, __ptmd_desc_type_node): Remove #defines.
+ (ti_desc_type_node, bltn_desc_type_node, ptr_desc_type_node,
+ ref_desc_type_node, ary_desc_type_node, func_desc_type_node,
+ enum_desc_type_node, class_desc_type_node,
+ si_class_desc_type_node, vmi_class_desc_type_node,
+ ptmd_desc_type_node, base_desc_type_node): New #defines.
+ (tinfo_fn_id, tinfo_fn_type): Rename to ...
+ (tinfo_decl_id, tinfo_decl_type): ... here. Adjust.
+ (tinfo_var_id): New enumeration.
+ (DECL_TINFO_FN_P): Augment comment.
+ * decl.c (cp_global_trees): Adjust documentation.
+ * rtti.c (init_rtti_processing): Adjust for tinfo_decl_id,
+ tinfo_decl_type and tinfo_var_id.
+ (get_tinfo_decl_dynamic): Adjust for tinfo_decl_type.
+ (build_typeid): Remove unused variable.
+ (get_tinfo_var): Use tinfo_var_id.
+ (tinfo_name): New static function.
+ (get_tinfo_decl): Adjust for tinfo_decl_id and tinfo_decl_type.
+ (tinfo_from_decl): Likewise.
+ (get_base_offset): New static function, broken out of
+ expand_class_desc.
+ (expand_si_desc): Use tinfo_name.
+ (expand_class_desc): Likewise. Lose local static variable.
+ Use base_desc_type_node. Use get_base_offset.
+ (expand_ptr_desc): Use tinfo_name.
+ (expand_attr_desc): Likewise.
+ (expand_generic_desc): Likewise.
+
+ * tinfo.cc (__GXX_ABI_VERSION): Test value and existence.
+ * tinfo.h (__GXX_ABI_VERSION): Test value and existence.
+
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (__eprintf): Remove declaration.
+ * tree.c (__eprintf): Remove definition.
+
+2000-01-23 Zack Weinberg <zack@rabi.columbia.edu>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_MARKED_N, SET_CLASSTYPE_MARKED_N,
+ CLEAR_CLASSTYPE_MARKED_N): Avoid signed vs. unsigned warnings.
+
+2000-01-23 Brad Lucier <lucier@math.purdue.edu>
+
+ * class.c (dump_class_hierarchy): Print HOST_WIDE_INT properly.
+
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (register_dtor_fn): New function.
+ * decl.c (destroy_local_static): Rename to ...
+ (register_dtor_fn): ... this. Give it external linkage.
+ (expand_static_init): Use it.
+ * decl2.c (do_static_initialization): Likewise, if using
+ __cxa_atexit.
+ (do_static_destruction): Check that __cxa_atexit is not in use.
+ (finish_file): Don't call do_static_destruction if using
+ __cxa_atexit.
+
+ * typeck.c (convert_arguments): Restore two-message error
+ reporting.
+
+2000-01-20 Nathan Sidwell <sidwell@codesourcery.com>
+
+ Remap dynamic cast hint values to be consistent across ABIs.
+ * search.c (dynamic_cast_base_recurse): Remap generated value.
+ (get_dynamic_cast_base_type): Adjust documentation.
+ * tinfo.h (__user_type_info::dyncast): Likewise.
+ (__user_type_info::find_public_subobj): Remap BOFF meaning.
+ * tinfo.cc (__si_type_info::do_dyncast): Remap BOFF meaning.
+ (__class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_find_public_subobj): Likewise.
+ * tinfo2.cc (__dynamic_cast): Remap BOFF parameter.
+
+2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * typeck.c (build_unary_op): Use cp_pedwarn, not pedwarn.
+
+ * typeck2.c (incomplete_type_error): Restore previous
+ cp_error and cp_error_at call sequence.
+
+2000-01-20 Brad Lucier <lucier@math.purdue.edu>
+
+ * class.c (dump_class_hierarchy): Make format agree with argument;
+ cast pointer to unsigned long and print with %lx.
+
+2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Set default line-wrap length to 72.
+
+ * typeck.c (composite_pointer_type, common_type,
+ comp_target_parms, c_sizeof, expr_sizeof, build_array_ref,
+ build_function_call_real, convert_arguments,
+ build_binary_op_nodefault, pointer_int_sum, pointer_diff,
+ build_unary_op, mark_addressable, build_compound_expr,
+ build_static_cast, build_reinterpret_cast, build_const_cast,
+ build_c_cast, build_modify_expr, get_delta_difference,
+ build_ptrmemfunc, check_return_expr): Replace 'ANSI C++' with
+ 'ISO C++'. Fusion consecutive calls to diagnostic message routines
+ into a single one.
+ * typeck2.c (readonly_error, abstract_virtuals_error,
+ process_init_constructor, check_for_new_type): Likewise.
+
+2000-01-19 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (bot_manip): Set DECL_CONTEXT for newly created
+ VAR_DECLs.
+
+2000-01-18 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (get_tinfo_fn_dynamic): Remove prototype.
+ (build_x_typeid): Likewise.
+ (get_tinfo_fn): Likewise.
+ (get_tinfo_fn_unused): Rename to ...
+ (get_tinfo_decl): ... here.
+ * rtti.c (build_headof): Replace logic error with assertion.
+ (get_tinfo_fn_dynamic): Rename to ...
+ (get_tinfo_decl_dynamic): ... here. Make static. Use
+ complete_type_or_else.
+ (build_x_typeid): Move into ...
+ (build_typeid): ... here. Adjust call to
+ get_tinfo_decl_dynamic. Use tinfo_from_decl. Simplify
+ throw_bad_typeid expression.
+ (get_tinfo_fn_unused): Rename to ...
+ (get_tinfo_decl): ... here. Adjust comment.
+ (get_tinfo_fn): Delete.
+ (tinfo_from_decl): New static function.
+ (get_typeid_1): Call get_tinfo_decl and tinfo_from_decl.
+ (get_typeid): Use complete_type_or_else.
+ (build_dynamic_cast_1): Adjust calls to
+ get_tinfo_decl_dynamic. Simplify throw_bad_cast expression.
+ * parse.y (primary): Adjust call to build_typeid.
+ * except.c (build_eh_type_type_ref): Adjust call to
+ get_tinfo_decl. Mark as used.
+ * class.c (set_rtti_entry): Adjust call to get_tinfo_decl.
+ * decl2.c (build_expr_from_tree): Adjust call to build_typeid.
+ * parse.c: Regenerated.
+
+2000-01-17 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (fixed_type_or_null): Don't clear NONNULL. Document
+ calling convention.
+ (resolves_to_fixed_type_p): Document calling convention.
+ * rtti.c (build_x_typeid): Initialize NONNULL.
+
+ * cp-tree.h (build_shared_int_cst): New function.
+ * call.c (build_over_call): Use DECL_VIRTUAL_CONTEXT, for clarity.
+ * class.c (modify_vtable_entry): Likewise.
+ (add_virtual_function): Split out code to generated shared
+ INTEGER_CSTs to build_share_int_cst.
+ (modify_all_vtables): Handle all the overridden functions here.
+ Add overridden functions from non-primary virtual bases to the
+ primary vtable.
+ (finish_struct_1): Adjust call to modify_all_vtables. Add
+ overridden functions from non-primary bases to the vtable.
+ * tree.c (build_shared_int_cst): New function.
+
+ * cp-tree.h (scratchalloc): Remove.
+ (build_scratch_list): Likewise.
+ * call.c (convert_class_to_reference): Replace build_scratch_list
+ and build_expr_list with build_tree_list.
+ (add_candidate): Replace scratchalloc with expralloc. Note memory
+ leak.
+ (build_user_type_conversion_1): Replace build_scratch_list
+ and build_expr_list with build_tree_list.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * decl.c (start_decl): Likewise.
+ (start_function): Likewise.
+ (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * decl2.c (reparse_decl_as_expr): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (expand_cleanup_for_base): Likewise.
+ (build_builtin_delete_call): Likewise.
+ (build_new_1): Likewise.
+ (build_delete): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ * parse.y (already_scoped_stmt): Likewise.
+ (nontrivial_exprlist): Likewise.
+ (net_initializer): Likewise.
+ (initlist): Likewise.
+ * parse.c: Regenerated.
+ * rtti.c (build_x_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (build_x_compound_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_modify_expr): Likewise.
+
+ * cp-tree.h (DECL_VINDEX): Add documentation.
+ * class.c (build_vtable_entry): Likewise.
+ (start_vtable): Add comment.
+ (add_virtual_function): Replace pending_hard_virtuals with
+ overridden_virtuals and pending_virtuals with new_virtuals.
+ Replace redundant assignments with assertions.
+ (check_for_override): Add comment.
+ (check_bases_and_members): Replace pending_hard_virtuals with
+ overridden_virtuals and pending_virtuals with new_virtuals.
+ (create_vtbl_ptr): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise. Add comments.
+
+2000-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_1): Replace redundant code with
+ assertions.
+
+ * cp-tree.h (flag_new_abi): Move.
+ (flag_use_cxa_atexit): Likewise.
+ (flag_honor_std): Likewise.
+ (flag_rtti): Likewise.
+ (vbase_offsets_in_vtable_p): Define.
+ (vptrs_present_everywhere_p): Likewise.
+ (TYPE_CONTAINS_VPTR_P): Likewise.
+ (dfs_walk_real): Declare.
+ * class.c (build_vbase_pointer_fields): Check
+ vbase_offsets_in_vtable_p.
+ (dfs_build_vbase_offset_vtbl_entries): Record the vbase indices in
+ BINFO_VPTR_FIELD.
+ (build_vbase_offset_vtbl_entries): Simplify.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (build_vbase_pointer): Add ability to look up vbase offsets in
+ vtable.
+ (start_vtable): New function.
+ (add_virtual_function): Use it.
+ (determine_primary_base): Use TYPE_CONTAINS_VPTR_P.
+ (num_extra_vtbl_entries): Use vbase_offsets_in_vtable_p.
+ (build_vtbl_initializer): Take the type of the complete object as
+ input. Use it to correctly calculate vbase offsets.
+ (dfs_finish_vtbls): Pass the complete type to
+ build_vtbl_initializer.
+ (check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
+ (create_vtable_ptr): Create a vtable even if there are no
+ new virtual functions, under the new ABI.
+ (finish_struct_1): Likewise.
+ (get_vfield_name): Use TYPE_CONTAINS_VPTR_P.
+ * decl.c (exapnd_static_init): Remove call to
+ preserve_initializer.
+ * decl2.c (mark_vtable_entries): Tweak to handle vbase offsets in
+ vtables.
+ * init.c (initialize_vtbl_ptrs): Initialize them in pre-order.
+ (expand_virtual_init): Use vbase_offsets_in_vtable_p.
+ (construct_virtual_bases): Don't initialize virtual base pointers
+ under the new ABI.
+ (build_aggr_init): Clean up comment.
+ (expand_aggr_init_1): Likewise.
+ * rtti.c (expand_class_desc): Store the virtual function table
+ index where the vbase offset lives in the offset field.
+ * search.c (dfs_walk_real): Make it global.
+ (dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P.
+ * tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD.
+
+ * tinfo.h (USItype): Make it signed under the new ABI.
+ * tinfo.cc (convert_to_base): New function. Encapsulate base
+ conversion logic here.
+ (__class_type_info::do_upcast): Use it.
+ (__class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_find_public_subobj): Likewise.
+
+ * init.c (construct_virtual_bases): Don't look up the addresses of
+ virtual bases at run-time.
+
+ * class.c (build_vbase_pointer): Relocate.
+ (build_vbase_pointer_fields): Likewise.
+ (dfs_build_vbase_offset_vtbl_entries): Likewise.
+ (build_vbase_offset_vtbl_entries): Likewise.
+
+ * decl.c (init_decl_processing): Complain if -fnew-abi
+ -fno-vtable-thunks is used.
+
+ * decl2.c (lang_decode_option): Don't couple flag_honor_std to
+ flag_new_abi.
+
+2000-01-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (num_extra_vtbl_entries): New function.
+ (size_extra_vtbl_entries): Likewise.
+ (dfs_vtable_path_unmark): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Likewise.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ * class.c (num_extra_vtbl_entries): New function.
+ (size_extra_vtbl_entries): Likewise.
+ (dfs_build_vbase_offset_vtbl_entries): New function.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (build_vtbl_initializer): Use it.
+ (finish_struct_1): Adjust vtable sizes (using
+ num_extra_vtbl_entries).
+ * expr.c (cplus_expand_expr): Assert that the DECL_RTL for a
+ THUNK_DECL is non-NULL before expanding it.
+ * init.c (expand_virtual_init): Adjust the vtable pointer by
+ size_extra_vtbl_entries before storing it.
+ * search.c (get_shared_vase_if_not_primary): Adjust prototype.
+ Handle TREE_LIST parameters here, not in the dfs_* functions.
+ (dfs_unmarked_real_bases_queue_p): Adjust.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): New function.
+ (dfs_vtable_path_marked_real_bases_queue_p): New function.
+ (dfs_vtable_path_unmark): Likewise.
+
+2000-01-14 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (copy_body_r): Clear the operand three of a
+ TARGET_EXPR when copying it.
+
+2000-01-14 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * method.c (build_decl_overload_real): Check whether we are in ::
+ before returning __builtin_new/delete.
+
+2000-01-13 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_friend_function): Improve comment.
+ (instantiate_decl): Avoid crashing when a "nested" function is
+ instantiated from the top level.
+
+ * dump.c (dqeueue_and_dump): Dump
+ DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION.
+
+2000-01-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: If GATHER_STATISTICS, declare `n_build_method_call'.
+
+2000-01-13 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * g++spec.c (lang_specific_driver): Add -fnew-abi if
+ ENABLE_NEW_GXX_ABI defined.
+ * Make-lang.in (tinfo.o, tinfo2.o, exception.o, new.o,
+ opnew.o, opnewnt.o, opvnew.o, opvnewnt.o, opdel.o, opdelnt.o,
+ opvdel.o, opvdelnt.o): Use GXX_ABI_FLAG switch.
+
+2000-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_cleanup_fn): Call pushdecl.
+
+ * call.c (convert_class_to_reference): Fix typos.
+ (build_conditional_expr): Handle errors gracefully.
+ * class.c (push_nested_class): Likewise.
+ * cp-tree.h (VAR_FUNCTION_OR_PARM_DECL_CHECK): New macro.
+ (DECL_THIS_EXTERN): Use it.
+ (DECL_THIS_STATIC): Likewise.
+ * cvt.c (convert_to_void): Handle errors gracefully.
+ (build_expr_type_conversion): Likewise.
+ * decl.c (maybe_push_decl): Likewise.
+ (start_decl_1): Likewise.
+ (require_complete_types_for_parms): Likewise.
+ * parse.y (structsp): Likewise.
+ (base_class): Likewise.
+ * parse.c: Regenerated.
+ * pt.c (finish_member_template_decl): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+
+ * cp-tree.h (dfs_skip_vbases): New function.
+ (find_vbase_instance): Likewise.
+ * class.c (determine_primary_base): Allow a nearly empty base to
+ serve as a primary base class under the new ABI.
+ (get_class_offset_1): Rename to ...
+ (dfs_get_class_offset): ... this. Simplify. Don't issue error
+ messages here.
+ (get_class_offset): Use it. Issue error messages here.
+ (dfs_modify_vtables): Rely on dfs_unmarked_real_bases_queue_p to
+ find the right copies of virtual bases.
+ (fixup_vtable_deltas1): Rename to ...
+ (dfs_fixup_vtable_deltas): ... this. Adjust to handle virtual
+ bases as primary bases.
+ (fixup_vtable_deltas): Remove.
+ (override_one_vtable): Handle virtual bases as primary bases.
+ (merge_overrides): Likewise.
+ (finish_struct_1): Likewise.
+ (dump_class_hierarchy): Dump primary-ness of bases as well.
+ * search.c (mark_primary_bases): Use a pre-order traversal to
+ handle primary virtual bases.
+ (dfs_skip_vbases): New fiunction.
+ (expand_upcast_fixups): Adjust to handle primary virtual bases.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ (dfs_find_vbase_instances): New function.
+ (find_vbase_instance): Likewise.
+
+2000-01-11 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * lex.c (DIR_SEPARATOR): Delete macro.
+
+2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Handle automatic line wrapping
+ option.
+
+2000-01-11 Mark Mitchell <mark@codesourcery.com>
+
+ * friend.c (do_friend): Don't resolve scopes when processing
+ template declarations, even if the qualifying scope doesn't
+ involve template parameters.
+
+2000-01-10 Mark Mitchell <mitchell@dumbledore.codesourcery.com>
+
+ * class.c (dfs_modify_vtables_queue_p): Remove.
+ (modify_all_vtables): Use dfs_unmarked_real_bases_queue_p
+ and dfs_marked_real_bases_queue_p instead of
+ dfs_modify_vtables_queue_p.
+
+ * class.c (build_vbase_path): Simplify.
+ (dfs_propagate_binfo_offsets): New function.
+ (propagate_binfo_offsets): Use it.
+ (remove_base_field): Simplify.
+ (dfs_set_offset_for_vbases): Remove.
+ (dfs_set_offset_for_shared_vbases): New function.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Use them.
+ (layout_basetypes): Don't call propagate_binfo_offsets.
+ * search.c (dfs_get_vbase_types): Clone completely fresh binfos
+ for the vbases.
+
+ * class.c (build_base_field): New function, split out from ...
+ (build_base_fields): ... here. Use it. Allocate primary bases
+ first, under the new ABI.
+ (get_vtable_entry): Remove.
+ (remove_base_field): New function, split out from ...
+ (remove_base_fields): ... here. Adjust since primary bases come
+ first under the new ABI.
+
+ * cp-tree.h (expand_direct_vtbls_init): Remove declaration.
+ (initialize_vtbl_ptrs): New function.
+ (expand_indirect_vtbls_init): Change prototype.
+ (convert_pointer_to_vbase): Declare.
+ * init.c (expand_direct_vtbls_init): Remove.
+ (dfs_initialize_vtbl_ptrs): New function.
+ (initialize_vtbl_ptrs): Likewise.
+ (emit_base_init): Use initialize_vtbl_ptrs.
+ * search.c (convert_pointer_to_vbase): Make it global.
+ (expand_indirect_vtbls_init): Remove vtable initialization code.
+ * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs.
+
+ * class.c (dfs_finish_vtbls): New function.
+ (finish_vtbls): Use it.
+ (dump_class_hierarchy): New function.
+
+ * cp-tree.h (BINFO_PRIMARY_MARKED_P): Change definition.
+ (BINFO_VBASE_PRIMARY_P): New macro.
+ (BINFO_VIRTUALS): Add to documentation.
+ (SET_BINFO_PRIMARY_MARKED_P): Remove.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (dfs_mark_primary_bases_queue_p): Likewise.
+ (dfs_unmarked_real_bases_queue_p): New function.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ * search.c (dfs_mark_primary_bases): Adjust.
+ (mark_primary_bases): Likewise.
+ (get_shared_vbase_if_not_primary): New function.
+ (dfs_unmarked_real_bases_queue_p): Likewise.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Simplify.
+ (get_pure_virtuals): Likewise.
+
+2000-01-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c: Include tm_p.h.
+
+2000-01-07 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * lang-specs.h (__GXX_ABI_VERSION): New preprocessor macro.
+
+2000-01-06 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT.
+ * pt.c (instantiate_decl): Defer comdat templates that might not be
+ needed.
+
+ * cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT.
+ * decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT.
+ (finish_file): Likewise.
+
+ * decl2.c (import_export_class): Undo 12/14 change.
+
+ * error.c (dump_decl): operator new, not operatornew.
+
+ * class.c (field_decl_cmp): A nontype is "greater" than a type.
+ * search.c (lookup_field_1): Look for the last field with the
+ desired name.
+
+2000-01-05 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (lookup_arg_dependent): Deal with FNS not being a
+ FUNCTION_DECL.
+
+2000-01-05 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (build_static_cast): Don't strip target qualifiers
+ when casting from a class.
+
+2000-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (warn_hidden): Initialize variable `fndecl'.
+
+2000-01-03 Ulrich Drepper <drepper@cygnus.com>
+
+ * decl.c (flag_isoc9x): New variable to be able to use code in
+ c-common.c. For now always zero.
+
+2000-01-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation.
+ * class.c (layout_basetypes): Don't set BINFO_INHERITANCE_CHAIN
+ or unshare_base_binfos for virtual bases here.
+ * search.c (dfs_get_vbase_types): Do it here.
+ (get_vbase_types): Adjust.
+
+2000-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELDS): Move definition.
+ (BINFO_PRIMARY_MARKED_P): Use flag 5.
+ (SET_BINFO_PRIMARY_MARKED_P): Likewise.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (unmark_primary_bases): Remove declaration.
+ (unmarkedp): Declare.
+ (dfs_vbase_unmark): Likewise.
+ * class.c (determine_primary_base): Return immediately if there
+ are no base classes. Call mark_primary_bases here.
+ (modify_all_direct_vtables): Remove.
+ (modify_all_indirect_vtables): Remove.
+ (dfs_modify_vtables_queue_p): New function.
+ (dfs_modify_vtables): New function.
+ (modify_all_vtables): Use them.
+ (build_base_fields): Build FIELD_DECLs for primary virtual base
+ classes.
+ (create_vtable_ptr): Don't call determine_primary_base here.
+ (dfs_mark_primary_bases_and_set_vbase_offsets): Rename to ...
+ (dfs_set_offset_for_vbases): ... this.
+ (layout_virtual_bases): Use it.
+ (layout_class_type): Call determine_primary_base here.
+ * search.c (unmarkedp): Make it global.
+ (shared_marked_p): Simplify.
+ (shared_unmarked_p): Likewise.
+ (dfs_primary_bases_queue_p): Remove.
+ (dfs_unmark_primary_bases): Likewise.
+ (unmark_primary_bases): Likewise.
+ (mark_primary_bases): Simplify.
+ (get_pure_virtuals): Don't call mark_primary_bases here.
+ (dfs_vbase_unmark): New function.
+ (get_vbase_types): Simplify.
+
+ * class.c (struct base_info): Remove.
+ (determine_primary_base): Take has_virtual_p rather than a
+ base_info as input. Don't calculate max_has_virtual.
+ (finish_struct_bits): Remove max_has_virtual argument.
+ (create_vtable_ptr): Remove max_has_virtual_p argument.
+ (layout_virtual_bases): Remove max argument.
+ (layout_basetypes): Likewise.
+ (layout_class_type): Remove max_has_virtual_p argument.
+ (finish_struct_1): Remove max_has_virtual.
+
+ * cp-tree.h (dfs_mark_primary_bases_queue_p): New function.
+ (layout_basetypes): Remove.
+ * class.c (propagate_binfo_offsets): Moved here from tree.c.
+ Update to handle primary virtual bases.
+ (remove_base_fields): New function, split out from
+ layout_basetypes.
+ (dfs_mark_primary_bases_and_set_vbase_offsets): New function.
+ (layout_virtual_bases): New function, split out from
+ layout_basetypes. Update to handle primary virtual bases.
+ (layout_basetypes): Moved here from tree.c. Use
+ remove_base_fields and layout_virtual_bases.
+ * search.c (dfs_mark_primary_bases_queue_p): New function.
+ (mark_primary_bases): Use it.
+ * tree.c (CEIL): Remove.
+ (propagate_binfo_offsets): Remove.
+ (layout_basetypes): Remove.
+
+2000-01-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES.
+ (BINFO_PRIMARY_MARKED_P): New macro.
+ (SET_BINFO_PRIMARY_MARKED_P): Likewise.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (mark_primary_bases): New function.
+ (unmark_primary_bases): Likewise.
+ * search.c (get_abstract_virtuals_1): Remove.
+ (dfs_mark_primary_bases): New function.
+ (mark_primary_bases): Likewise.
+ (dfs_unmark_primary_bases): Likewise.
+ (unmark_primary_bases): Likewise.
+ (dfs_get_pure_virtuals): Likewise.
+
+2000-01-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (skip_rtti_stuff): Adjust prototype.
+ * class.c (skip_rtti_stuff): Reorganize parameters and return value.
+ (modify_one_vtable): Adjust.
+ (fixup_vtable_deltas1): Likewise.
+ (override_one_vtable): Likewise.
+ * search.c (get_abstract_virtuals_1): Likewise.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+
+ * class.c (build_vtable): Don't return a value. Don't rebuild
+ vtables for bases that have already been handled.
+ (prepare_fresh_vtable): Don't rebuild vtables for bases that have
+ already been handled.
+ (modify_one_vtable): Adjust accordingly.
+ (fixup_vtable_deltas1): Likewise.
+ (finish_struct_1): Likewise.
+
+2000-01-01 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * call.c (build_new_method_call): Also check destructors.
+
+See ChangeLog.2 for earlier changes.
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/cp-gimplify.c b/gcc/cp/cp-gimplify.c
new file mode 100644
index 00000000000..db88e052b4d
--- /dev/null
+++ b/gcc/cp/cp-gimplify.c
@@ -0,0 +1,295 @@
+/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
+
+ Copyright (C) 2002, 2003, 2004 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"
+
+
+/* Genericize a TRY_BLOCK. */
+
+static void
+genericize_try_block (tree *stmt_p)
+{
+ tree body = TRY_STMTS (*stmt_p);
+ tree cleanup = TRY_HANDLERS (*stmt_p);
+
+ gimplify_stmt (&body);
+
+ if (CLEANUP_P (*stmt_p))
+ /* A cleanup is an expression, so it doesn't need to be genericized. */;
+ else
+ 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);
+
+ 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));
+ gimplify_stmt (&body);
+
+ *stmt_p = gimple_build_eh_filter (body, allowed, failure);
+}
+
+/* Genericize an IF_STMT by turning it into a COND_EXPR. */
+
+static void
+gimplify_if_stmt (tree *stmt_p)
+{
+ tree stmt, then_, else_;
+
+ stmt = *stmt_p;
+ 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_);
+ *stmt_p = stmt;
+}
+
+/* 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);
+ if (TREE_CODE (from) == CLEANUP_POINT_EXPR)
+ from = TREE_OPERAND (from, 0);
+
+ /* Look through any COMPOUND_EXPRs. */
+ sub = expr_last (from);
+
+ /* 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. */
+ 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, NULL);
+ 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;
+}
+
+/* Do C++-specific gimplification. Args are as for gimplify_expr. */
+
+int
+cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ int saved_stmts_are_full_exprs_p = 0;
+ enum tree_code code = TREE_CODE (*expr_p);
+ enum gimplify_status ret;
+
+ if (STATEMENT_CODE_P (code))
+ {
+ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p
+ = STMT_IS_FULL_EXPR_P (*expr_p);
+ }
+
+ switch (code)
+ {
+ case PTRMEM_CST:
+ *expr_p = cplus_expand_constant (*expr_p);
+ ret = GS_OK;
+ break;
+
+ case AGGR_INIT_EXPR:
+ simplify_aggr_init_expr (expr_p);
+ ret = GS_OK;
+ break;
+
+ case THROW_EXPR:
+ /* FIXME communicate throw type to backend, probably by moving
+ THROW_EXPR into ../tree.def. */
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ ret = GS_OK;
+ break;
+
+ case MUST_NOT_THROW_EXPR:
+ gimplify_must_not_throw_expr (expr_p, pre_p);
+ ret = GS_OK;
+ break;
+
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ cp_gimplify_init_expr (expr_p, pre_p, post_p);
+ ret = GS_OK;
+ break;
+
+ 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;
+ }
+ ret = GS_OK;
+ break;
+
+ case BASELINK:
+ *expr_p = BASELINK_FUNCTIONS (*expr_p);
+ ret = GS_OK;
+ break;
+
+ case TRY_BLOCK:
+ genericize_try_block (expr_p);
+ ret = GS_OK;
+ break;
+
+ case HANDLER:
+ genericize_catch_block (expr_p);
+ ret = GS_OK;
+ break;
+
+ case EH_SPEC_BLOCK:
+ genericize_eh_spec_block (expr_p);
+ ret = GS_OK;
+ break;
+
+ case USING_STMT:
+ /* Just ignore for now. Eventually we will want to pass this on to
+ the debugger. */
+ *expr_p = build_empty_stmt ();
+ ret = GS_ALL_DONE;
+ break;
+
+ case IF_STMT:
+ gimplify_if_stmt (expr_p);
+ ret = GS_OK;
+ break;
+
+ default:
+ ret = c_gimplify_expr (expr_p, pre_p, post_p);
+ break;
+ }
+
+ /* Restore saved state. */
+ if (STATEMENT_CODE_P (code))
+ current_stmt_tree ()->stmts_are_full_exprs_p
+ = saved_stmts_are_full_exprs_p;
+
+ return ret;
+}
+
+/* Genericize a CLEANUP_STMT. This just turns into a TRY_FINALLY or
+ TRY_CATCH depending on whether it's EH-only. */
+
+static tree
+gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree stmt = *stmt_p;
+
+ if (DECL_P (stmt) || TYPE_P (stmt))
+ *walk_subtrees = 0;
+ else if (TREE_CODE (stmt) == CLEANUP_STMT)
+ *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
+ void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt));
+
+ return NULL;
+}
+
+void
+cp_genericize (tree fndecl)
+{
+ /* Due to the way voidify_wrapper_expr is written, we don't get a chance
+ to lower this construct before scanning it. So we need to lower these
+ before doing anything else. */
+ walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL);
+
+ /* Do everything else. */
+ c_genericize (fndecl);
+}
diff --git a/gcc/ddg.c b/gcc/ddg.c
new file mode 100644
index 00000000000..2c66454cd02
--- /dev/null
+++ b/gcc/ddg.c
@@ -0,0 +1,1046 @@
+/* DDG - Data Dependence Graph implementation.
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.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 "toplev.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "regs.h"
+#include "function.h"
+#include "flags.h"
+#include "insn-config.h"
+#include "insn-attr.h"
+#include "except.h"
+#include "recog.h"
+#include "sched-int.h"
+#include "target.h"
+#include "cfglayout.h"
+#include "cfgloop.h"
+#include "sbitmap.h"
+#include "expr.h"
+#include "bitmap.h"
+#include "df.h"
+#include "ddg.h"
+
+/* A flag indicating that a ddg edge belongs to an SCC or not. */
+enum edge_flag {NOT_IN_SCC = 0, IN_SCC};
+
+/* Forward declarations. */
+static void add_backarc_to_ddg (ddg_ptr, ddg_edge_ptr);
+static void add_backarc_to_scc (ddg_scc_ptr, ddg_edge_ptr);
+static void add_scc_to_ddg (ddg_all_sccs_ptr, ddg_scc_ptr);
+static void create_ddg_dependence (ddg_ptr, ddg_node_ptr, ddg_node_ptr, rtx);
+static void create_ddg_dep_no_link (ddg_ptr, ddg_node_ptr, ddg_node_ptr,
+ dep_type, dep_data_type, int);
+static ddg_edge_ptr create_ddg_edge (ddg_node_ptr, ddg_node_ptr, dep_type,
+ dep_data_type, int, int);
+static void add_edge_to_ddg (ddg_ptr g, ddg_edge_ptr);
+
+/* Auxiliary variable for mem_read_insn_p/mem_write_insn_p. */
+static bool mem_ref_p;
+
+/* Auxiliary function for mem_read_insn_p. */
+static int
+mark_mem_use (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ if (MEM_P (*x))
+ mem_ref_p = true;
+ return 0;
+}
+
+/* Auxiliary function for mem_read_insn_p. */
+static void
+mark_mem_use_1 (rtx *x, void *data)
+{
+ for_each_rtx (x, mark_mem_use, data);
+}
+
+/* Returns nonzero if INSN reads from memory. */
+static bool
+mem_read_insn_p (rtx insn)
+{
+ mem_ref_p = false;
+ note_uses (&PATTERN (insn), mark_mem_use_1, NULL);
+ return mem_ref_p;
+}
+
+static void
+mark_mem_store (rtx loc, rtx setter ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
+{
+ if (MEM_P (loc))
+ mem_ref_p = true;
+}
+
+/* Returns nonzero if INSN writes to memory. */
+static bool
+mem_write_insn_p (rtx insn)
+{
+ mem_ref_p = false;
+ note_stores (PATTERN (insn), mark_mem_store, NULL);
+ return mem_ref_p;
+}
+
+/* Returns nonzero if X has access to memory. */
+static bool
+rtx_mem_access_p (rtx x)
+{
+ int i, j;
+ const char *fmt;
+ enum rtx_code code;
+
+ if (x == 0)
+ return false;
+
+ if (MEM_P (x))
+ return true;
+
+ code = GET_CODE (x);
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ if (rtx_mem_access_p (XEXP (x, i)))
+ return true;
+ }
+ else if (fmt[i] == 'E')
+ for (j = 0; j < XVECLEN (x, i); j++)
+ {
+ if (rtx_mem_access_p (XVECEXP (x, i, j)))
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Returns nonzero if INSN reads to or writes from memory. */
+static bool
+mem_access_insn_p (rtx insn)
+{
+ return rtx_mem_access_p (PATTERN (insn));
+}
+
+/* Computes the dependence parameters (latency, distance etc.), creates
+ a ddg_edge and adds it to the given DDG. */
+static void
+create_ddg_dependence (ddg_ptr g, ddg_node_ptr src_node,
+ ddg_node_ptr dest_node, rtx link)
+{
+ ddg_edge_ptr e;
+ int latency, distance = 0;
+ int interloop = (src_node->cuid >= dest_node->cuid);
+ dep_type t = TRUE_DEP;
+ dep_data_type dt = (mem_access_insn_p (src_node->insn)
+ && mem_access_insn_p (dest_node->insn) ? MEM_DEP
+ : REG_DEP);
+
+ /* For now we don't have an exact calculation of the distance,
+ so assume 1 conservatively. */
+ if (interloop)
+ distance = 1;
+
+ if (!link)
+ abort ();
+
+ /* Note: REG_DEP_ANTI applies to MEM ANTI_DEP as well!! */
+ if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
+ t = ANTI_DEP;
+ else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
+ t = OUTPUT_DEP;
+ latency = insn_cost (src_node->insn, link, dest_node->insn);
+
+ e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance);
+
+ if (interloop)
+ {
+ /* Some interloop dependencies are relaxed:
+ 1. Every insn is output dependent on itself; ignore such deps.
+ 2. Every true/flow dependence is an anti dependence in the
+ opposite direction with distance 1; such register deps
+ will be removed by renaming if broken --- ignore them. */
+ if (!(t == OUTPUT_DEP && src_node == dest_node)
+ && !(t == ANTI_DEP && dt == REG_DEP))
+ add_backarc_to_ddg (g, e);
+ else
+ free (e);
+ }
+ else
+ add_edge_to_ddg (g, e);
+}
+
+/* The same as the above function, but it doesn't require a link parameter. */
+static void
+create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to,
+ dep_type d_t, dep_data_type d_dt, int distance)
+{
+ ddg_edge_ptr e;
+ int l;
+ rtx link = alloc_INSN_LIST (to->insn, NULL_RTX);
+
+ if (d_t == ANTI_DEP)
+ PUT_REG_NOTE_KIND (link, REG_DEP_ANTI);
+ else if (d_t == OUTPUT_DEP)
+ PUT_REG_NOTE_KIND (link, REG_DEP_OUTPUT);
+
+ l = insn_cost (from->insn, link, to->insn);
+ free_INSN_LIST_node (link);
+
+ e = create_ddg_edge (from, to, d_t, d_dt, l, distance);
+ if (distance > 0)
+ add_backarc_to_ddg (g, e);
+ else
+ add_edge_to_ddg (g, e);
+}
+
+
+/* Given a downwards exposed register def RD, add inter-loop true dependences
+ for all its uses in the next iteration, and an output dependence to the
+ first def of the next iteration. */
+static void
+add_deps_for_def (ddg_ptr g, struct df *df, struct ref *rd)
+{
+ int regno = DF_REF_REGNO (rd);
+ struct bb_info *bb_info = DF_BB_INFO (df, g->bb);
+ struct df_link *r_use;
+ int use_before_def = false;
+ rtx def_insn = DF_REF_INSN (rd);
+ ddg_node_ptr src_node = get_node_of_insn (g, def_insn);
+
+ /* Create and inter-loop true dependence between RD and each of its uses
+ that is upwards exposed in RD's block. */
+ for (r_use = DF_REF_CHAIN (rd); r_use != NULL; r_use = r_use->next)
+ {
+ if (bitmap_bit_p (bb_info->ru_gen, r_use->ref->id))
+ {
+ rtx use_insn = DF_REF_INSN (r_use->ref);
+ ddg_node_ptr dest_node = get_node_of_insn (g, use_insn);
+
+ if (!src_node || !dest_node)
+ abort ();
+
+ /* Any such upwards exposed use appears before the rd def. */
+ use_before_def = true;
+ create_ddg_dep_no_link (g, src_node, dest_node, TRUE_DEP,
+ REG_DEP, 1);
+ }
+ }
+
+ /* Create an inter-loop output dependence between RD (which is the
+ last def in its block, being downwards exposed) and the first def
+ in its block. Avoid creating a self output dependence. Avoid creating
+ an output dependence if there is a dependence path between the two defs
+ starting with a true dependence followed by an anti dependence (i.e. if
+ there is a use between the two defs. */
+ if (! use_before_def)
+ {
+ struct ref *def = df_bb_regno_first_def_find (df, g->bb, regno);
+ int i;
+ ddg_node_ptr dest_node;
+
+ if (!def || rd->id == def->id)
+ return;
+
+ /* Check if there are uses after RD. */
+ for (i = src_node->cuid + 1; i < g->num_nodes; i++)
+ if (df_reg_used (df, g->nodes[i].insn, rd->reg))
+ return;
+
+ dest_node = get_node_of_insn (g, def->insn);
+ create_ddg_dep_no_link (g, src_node, dest_node, OUTPUT_DEP, REG_DEP, 1);
+ }
+}
+
+/* Given a register USE, add an inter-loop anti dependence to the first
+ (nearest BLOCK_BEGIN) def of the next iteration, unless USE is followed
+ by a def in the block. */
+static void
+add_deps_for_use (ddg_ptr g, struct df *df, struct ref *use)
+{
+ int i;
+ int regno = DF_REF_REGNO (use);
+ struct ref *first_def = df_bb_regno_first_def_find (df, g->bb, regno);
+ ddg_node_ptr use_node;
+ ddg_node_ptr def_node;
+ struct bb_info *bb_info;
+
+ bb_info = DF_BB_INFO (df, g->bb);
+
+ if (!first_def)
+ return;
+
+ use_node = get_node_of_insn (g, use->insn);
+ def_node = get_node_of_insn (g, first_def->insn);
+
+ if (!use_node || !def_node)
+ abort ();
+
+ /* Make sure there are no defs after USE. */
+ for (i = use_node->cuid + 1; i < g->num_nodes; i++)
+ if (df_find_def (df, g->nodes[i].insn, use->reg))
+ return;
+ /* We must not add ANTI dep when there is an intra-loop TRUE dep in
+ the opozite direction. If the first_def reaches the USE then there is
+ such a dep. */
+ if (! bitmap_bit_p (bb_info->rd_gen, first_def->id))
+ create_ddg_dep_no_link (g, use_node, def_node, ANTI_DEP, REG_DEP, 1);
+}
+
+/* Build inter-loop dependencies, by looking at DF analysis backwards. */
+static void
+build_inter_loop_deps (ddg_ptr g, struct df *df)
+{
+ int rd_num, u_num;
+ struct bb_info *bb_info;
+
+ bb_info = DF_BB_INFO (df, g->bb);
+
+ /* Find inter-loop output and true deps by connecting downward exposed defs
+ to the first def of the BB and to upwards exposed uses. */
+ EXECUTE_IF_SET_IN_BITMAP (bb_info->rd_gen, 0, rd_num,
+ {
+ struct ref *rd = df->defs[rd_num];
+
+ add_deps_for_def (g, df, rd);
+ });
+
+ /* Find inter-loop anti deps. We are interested in uses of the block that
+ appear below all defs; this implies that these uses are killed. */
+ EXECUTE_IF_SET_IN_BITMAP (bb_info->ru_kill, 0, u_num,
+ {
+ struct ref *use = df->uses[u_num];
+
+ /* We are interested in uses of this BB. */
+ if (BLOCK_FOR_INSN (use->insn) == g->bb)
+ add_deps_for_use (g, df,use);
+ });
+}
+
+/* Given two nodes, analyze their RTL insns and add inter-loop mem deps
+ to ddg G. */
+static void
+add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
+{
+ if (mem_write_insn_p (from->insn))
+ {
+ if (mem_read_insn_p (to->insn))
+ create_ddg_dep_no_link (g, from, to, TRUE_DEP, MEM_DEP, 1);
+ else if (from->cuid != to->cuid)
+ create_ddg_dep_no_link (g, from, to, OUTPUT_DEP, MEM_DEP, 1);
+ }
+ else
+ {
+ if (mem_read_insn_p (to->insn))
+ return;
+ else if (from->cuid != to->cuid)
+ {
+ create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1);
+ create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
+ }
+ }
+
+}
+
+/* Perform intra-block Data Dependency analysis and connect the nodes in
+ the DDG. We assume the loop has a single basic block. */
+static void
+build_intra_loop_deps (ddg_ptr g)
+{
+ int i;
+ /* Hold the dependency analysis state during dependency calculations. */
+ struct deps tmp_deps;
+ rtx head, tail, link;
+
+ /* Build the dependence information, using the sched_analyze function. */
+ init_deps_global ();
+ init_deps (&tmp_deps);
+
+ /* Do the intra-block data dependence analysis for the given block. */
+ get_block_head_tail (g->bb->index, &head, &tail);
+ sched_analyze (&tmp_deps, head, tail);
+
+ /* Build intra-loop data dependencies using the scheduler dependency
+ analysis. */
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_node_ptr dest_node = &g->nodes[i];
+
+ if (! INSN_P (dest_node->insn))
+ continue;
+
+ for (link = LOG_LINKS (dest_node->insn); link; link = XEXP (link, 1))
+ {
+ ddg_node_ptr src_node = get_node_of_insn (g, XEXP (link, 0));
+
+ if (!src_node)
+ continue;
+
+ add_forward_dependence (XEXP (link, 0), dest_node->insn,
+ REG_NOTE_KIND (link));
+ create_ddg_dependence (g, src_node, dest_node,
+ INSN_DEPEND (src_node->insn));
+ }
+
+ /* If this insn modifies memory, add an edge to all insns that access
+ memory. */
+ if (mem_access_insn_p (dest_node->insn))
+ {
+ int j;
+
+ for (j = 0; j <= i; j++)
+ {
+ ddg_node_ptr j_node = &g->nodes[j];
+ if (mem_access_insn_p (j_node->insn))
+ /* Don't bother calculating inter-loop dep if an intra-loop dep
+ already exists. */
+ if (! TEST_BIT (dest_node->successors, j))
+ add_inter_loop_mem_dep (g, dest_node, j_node);
+ }
+ }
+ }
+
+ /* Free the INSN_LISTs. */
+ finish_deps_global ();
+ free_deps (&tmp_deps);
+}
+
+
+/* Given a basic block, create its DDG and return a pointer to a variable
+ of ddg type that represents it.
+ Initialize the ddg structure fields to the appropriate values. */
+ddg_ptr
+create_ddg (basic_block bb, struct df *df, int closing_branch_deps)
+{
+ ddg_ptr g;
+ rtx insn, first_note;
+ int i;
+ int num_nodes = 0;
+
+ g = (ddg_ptr) xcalloc (1, sizeof (struct ddg));
+
+ g->bb = bb;
+ g->closing_branch_deps = closing_branch_deps;
+
+ /* Count the number of insns in the BB. */
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ if (! INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE)
+ continue;
+
+ if (mem_read_insn_p (insn))
+ g->num_loads++;
+ if (mem_write_insn_p (insn))
+ g->num_stores++;
+ num_nodes++;
+ }
+
+ /* There is nothing to do for this BB. */
+ if (num_nodes <= 1)
+ {
+ free (g);
+ return NULL;
+ }
+
+ /* Allocate the nodes array, and initialize the nodes. */
+ g->num_nodes = num_nodes;
+ g->nodes = (ddg_node_ptr) xcalloc (num_nodes, sizeof (struct ddg_node));
+ g->closing_branch = NULL;
+ i = 0;
+ first_note = NULL_RTX;
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ if (! INSN_P (insn))
+ {
+ if (! first_note && GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
+ first_note = insn;
+ continue;
+ }
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ if (g->closing_branch)
+ abort (); /* Found two branches in DDG. */
+ else
+ g->closing_branch = &g->nodes[i];
+ }
+ else if (GET_CODE (PATTERN (insn)) == USE)
+ {
+ if (! first_note)
+ first_note = insn;
+ continue;
+ }
+
+ g->nodes[i].cuid = i;
+ g->nodes[i].successors = sbitmap_alloc (num_nodes);
+ sbitmap_zero (g->nodes[i].successors);
+ g->nodes[i].predecessors = sbitmap_alloc (num_nodes);
+ sbitmap_zero (g->nodes[i].predecessors);
+ g->nodes[i].first_note = (first_note ? first_note : insn);
+ g->nodes[i++].insn = insn;
+ first_note = NULL_RTX;
+ }
+
+ if (!g->closing_branch)
+ abort (); /* Found no branch in DDG. */
+
+ /* Build the data dependency graph. */
+ build_intra_loop_deps (g);
+ build_inter_loop_deps (g, df);
+ return g;
+}
+
+/* Free all the memory allocated for the DDG. */
+void
+free_ddg (ddg_ptr g)
+{
+ int i;
+
+ if (!g)
+ return;
+
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_edge_ptr e = g->nodes[i].out;
+
+ while (e)
+ {
+ ddg_edge_ptr next = e->next_out;
+
+ free (e);
+ e = next;
+ }
+ sbitmap_free (g->nodes[i].successors);
+ sbitmap_free (g->nodes[i].predecessors);
+ }
+ if (g->num_backarcs > 0)
+ free (g->backarcs);
+ free (g->nodes);
+ free (g);
+}
+
+void
+print_ddg_edge (FILE *dump_file, ddg_edge_ptr e)
+{
+ char dep_c;
+
+ switch (e->type) {
+ case OUTPUT_DEP :
+ dep_c = 'O';
+ break;
+ case ANTI_DEP :
+ dep_c = 'A';
+ break;
+ default:
+ dep_c = 'T';
+ }
+
+ fprintf (dump_file, " [%d -(%c,%d,%d)-> %d] ", INSN_UID (e->src->insn),
+ dep_c, e->latency, e->distance, INSN_UID (e->dest->insn));
+}
+
+/* Print the DDG nodes with there in/out edges to the dump file. */
+void
+print_ddg (FILE *dump_file, ddg_ptr g)
+{
+ int i;
+
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_edge_ptr e;
+
+ print_rtl_single (dump_file, g->nodes[i].insn);
+ fprintf (dump_file, "OUT ARCS: ");
+ for (e = g->nodes[i].out; e; e = e->next_out)
+ print_ddg_edge (dump_file, e);
+
+ fprintf (dump_file, "\nIN ARCS: ");
+ for (e = g->nodes[i].in; e; e = e->next_in)
+ print_ddg_edge (dump_file, e);
+
+ fprintf (dump_file, "\n");
+ }
+}
+
+/* Print the given DDG in VCG format. */
+void
+vcg_print_ddg (FILE *dump_file, ddg_ptr g)
+{
+ int src_cuid;
+
+ fprintf (dump_file, "graph: {\n");
+ for (src_cuid = 0; src_cuid < g->num_nodes; src_cuid++)
+ {
+ ddg_edge_ptr e;
+ int src_uid = INSN_UID (g->nodes[src_cuid].insn);
+
+ fprintf (dump_file, "node: {title: \"%d_%d\" info1: \"", src_cuid, src_uid);
+ print_rtl_single (dump_file, g->nodes[src_cuid].insn);
+ fprintf (dump_file, "\"}\n");
+ for (e = g->nodes[src_cuid].out; e; e = e->next_out)
+ {
+ int dst_uid = INSN_UID (e->dest->insn);
+ int dst_cuid = e->dest->cuid;
+
+ /* Give the backarcs a different color. */
+ if (e->distance > 0)
+ fprintf (dump_file, "backedge: {color: red ");
+ else
+ fprintf (dump_file, "edge: { ");
+
+ fprintf (dump_file, "sourcename: \"%d_%d\" ", src_cuid, src_uid);
+ fprintf (dump_file, "targetname: \"%d_%d\" ", dst_cuid, dst_uid);
+ fprintf (dump_file, "label: \"%d_%d\"}\n", e->latency, e->distance);
+ }
+ }
+ fprintf (dump_file, "}\n");
+}
+
+/* Create an edge and initialize it with given values. */
+static ddg_edge_ptr
+create_ddg_edge (ddg_node_ptr src, ddg_node_ptr dest,
+ dep_type t, dep_data_type dt, int l, int d)
+{
+ ddg_edge_ptr e = (ddg_edge_ptr) xmalloc (sizeof (struct ddg_edge));
+
+ e->src = src;
+ e->dest = dest;
+ e->type = t;
+ e->data_type = dt;
+ e->latency = l;
+ e->distance = d;
+ e->next_in = e->next_out = NULL;
+ e->aux.info = 0;
+ return e;
+}
+
+/* Add the given edge to the in/out linked lists of the DDG nodes. */
+static void
+add_edge_to_ddg (ddg_ptr g ATTRIBUTE_UNUSED, ddg_edge_ptr e)
+{
+ ddg_node_ptr src = e->src;
+ ddg_node_ptr dest = e->dest;
+
+ if (!src->successors || !dest->predecessors)
+ abort (); /* Should have allocated the sbitmaps. */
+
+ SET_BIT (src->successors, dest->cuid);
+ SET_BIT (dest->predecessors, src->cuid);
+ e->next_in = dest->in;
+ dest->in = e;
+ e->next_out = src->out;
+ src->out = e;
+}
+
+
+
+/* Algorithm for computing the recurrence_length of an scc. We assume at
+ for now that cycles in the data dependence graph contain a single backarc.
+ This simplifies the algorithm, and can be generalized later. */
+static void
+set_recurrence_length (ddg_scc_ptr scc, ddg_ptr g)
+{
+ int j;
+ int result = -1;
+
+ for (j = 0; j < scc->num_backarcs; j++)
+ {
+ ddg_edge_ptr backarc = scc->backarcs[j];
+ int length;
+ int distance = backarc->distance;
+ ddg_node_ptr src = backarc->dest;
+ ddg_node_ptr dest = backarc->src;
+
+ length = longest_simple_path (g, src->cuid, dest->cuid, scc->nodes);
+ if (length < 0 )
+ {
+ /* fprintf (stderr, "Backarc not on simple cycle in SCC.\n"); */
+ continue;
+ }
+ length += backarc->latency;
+ result = MAX (result, (length / distance));
+ }
+ scc->recurrence_length = result;
+}
+
+/* Create a new SCC given the set of its nodes. Compute its recurrence_length
+ and mark edges that belong to this scc as IN_SCC. */
+static ddg_scc_ptr
+create_scc (ddg_ptr g, sbitmap nodes)
+{
+ ddg_scc_ptr scc;
+ int u;
+
+ scc = (ddg_scc_ptr) xmalloc (sizeof (struct ddg_scc));
+ scc->backarcs = NULL;
+ scc->num_backarcs = 0;
+ scc->nodes = sbitmap_alloc (g->num_nodes);
+ sbitmap_copy (scc->nodes, nodes);
+
+ /* Mark the backarcs that belong to this SCC. */
+ EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+ {
+ ddg_edge_ptr e;
+ ddg_node_ptr n = &g->nodes[u];
+
+ for (e = n->out; e; e = e->next_out)
+ if (TEST_BIT (nodes, e->dest->cuid))
+ {
+ e->aux.count = IN_SCC;
+ if (e->distance > 0)
+ add_backarc_to_scc (scc, e);
+ }
+ });
+
+ set_recurrence_length (scc, g);
+ return scc;
+}
+
+/* Cleans the memory allocation of a given SCC. */
+static void
+free_scc (ddg_scc_ptr scc)
+{
+ if (!scc)
+ return;
+
+ sbitmap_free (scc->nodes);
+ if (scc->num_backarcs > 0)
+ free (scc->backarcs);
+ free (scc);
+}
+
+
+/* Add a given edge known to be a backarc to the given DDG. */
+static void
+add_backarc_to_ddg (ddg_ptr g, ddg_edge_ptr e)
+{
+ int size = (g->num_backarcs + 1) * sizeof (ddg_edge_ptr);
+
+ add_edge_to_ddg (g, e);
+ g->backarcs = (ddg_edge_ptr *) xrealloc (g->backarcs, size);
+ g->backarcs[g->num_backarcs++] = e;
+}
+
+/* Add backarc to an SCC. */
+static void
+add_backarc_to_scc (ddg_scc_ptr scc, ddg_edge_ptr e)
+{
+ int size = (scc->num_backarcs + 1) * sizeof (ddg_edge_ptr);
+
+ scc->backarcs = (ddg_edge_ptr *) xrealloc (scc->backarcs, size);
+ scc->backarcs[scc->num_backarcs++] = e;
+}
+
+/* Add the given SCC to the DDG. */
+static void
+add_scc_to_ddg (ddg_all_sccs_ptr g, ddg_scc_ptr scc)
+{
+ int size = (g->num_sccs + 1) * sizeof (ddg_scc_ptr);
+
+ g->sccs = (ddg_scc_ptr *) xrealloc (g->sccs, size);
+ g->sccs[g->num_sccs++] = scc;
+}
+
+/* Given the instruction INSN return the node that represents it. */
+ddg_node_ptr
+get_node_of_insn (ddg_ptr g, rtx insn)
+{
+ int i;
+
+ for (i = 0; i < g->num_nodes; i++)
+ if (insn == g->nodes[i].insn)
+ return &g->nodes[i];
+ return NULL;
+}
+
+/* Given a set OPS of nodes in the DDG, find the set of their successors
+ which are not in OPS, and set their bits in SUCC. Bits corresponding to
+ OPS are cleared from SUCC. Leaves the other bits in SUCC unchanged. */
+void
+find_successors (sbitmap succ, ddg_ptr g, sbitmap ops)
+{
+ int i;
+
+ EXECUTE_IF_SET_IN_SBITMAP (ops, 0, i,
+ {
+ const sbitmap node_succ = NODE_SUCCESSORS (&g->nodes[i]);
+ sbitmap_a_or_b (succ, succ, node_succ);
+ });
+
+ /* We want those that are not in ops. */
+ sbitmap_difference (succ, succ, ops);
+}
+
+/* Given a set OPS of nodes in the DDG, find the set of their predecessors
+ which are not in OPS, and set their bits in PREDS. Bits corresponding to
+ OPS are cleared from PREDS. Leaves the other bits in PREDS unchanged. */
+void
+find_predecessors (sbitmap preds, ddg_ptr g, sbitmap ops)
+{
+ int i;
+
+ EXECUTE_IF_SET_IN_SBITMAP (ops, 0, i,
+ {
+ const sbitmap node_preds = NODE_PREDECESSORS (&g->nodes[i]);
+ sbitmap_a_or_b (preds, preds, node_preds);
+ });
+
+ /* We want those that are not in ops. */
+ sbitmap_difference (preds, preds, ops);
+}
+
+
+/* Compare function to be passed to qsort to order the backarcs in descending
+ recMII order. */
+static int
+compare_sccs (const void *s1, const void *s2)
+{
+ int rec_l1 = (*(ddg_scc_ptr *)s1)->recurrence_length;
+ int rec_l2 = (*(ddg_scc_ptr *)s2)->recurrence_length;
+ return ((rec_l2 > rec_l1) - (rec_l2 < rec_l1));
+
+}
+
+/* Order the backarcs in descending recMII order using compare_sccs. */
+static void
+order_sccs (ddg_all_sccs_ptr g)
+{
+ qsort (g->sccs, g->num_sccs, sizeof (ddg_scc_ptr),
+ (int (*) (const void *, const void *)) compare_sccs);
+}
+
+/* Perform the Strongly Connected Components decomposing algorithm on the
+ DDG and return DDG_ALL_SCCS structure that contains them. */
+ddg_all_sccs_ptr
+create_ddg_all_sccs (ddg_ptr g)
+{
+ int i;
+ int num_nodes = g->num_nodes;
+ sbitmap from = sbitmap_alloc (num_nodes);
+ sbitmap to = sbitmap_alloc (num_nodes);
+ sbitmap scc_nodes = sbitmap_alloc (num_nodes);
+ ddg_all_sccs_ptr sccs = (ddg_all_sccs_ptr)
+ xmalloc (sizeof (struct ddg_all_sccs));
+
+ sccs->ddg = g;
+ sccs->sccs = NULL;
+ sccs->num_sccs = 0;
+
+ for (i = 0; i < g->num_backarcs; i++)
+ {
+ ddg_scc_ptr scc;
+ ddg_edge_ptr backarc = g->backarcs[i];
+ ddg_node_ptr src = backarc->src;
+ ddg_node_ptr dest = backarc->dest;
+
+ /* If the backarc already belongs to an SCC, continue. */
+ if (backarc->aux.count == IN_SCC)
+ continue;
+
+ sbitmap_zero (from);
+ sbitmap_zero (to);
+ SET_BIT (from, dest->cuid);
+ SET_BIT (to, src->cuid);
+
+ if (find_nodes_on_paths (scc_nodes, g, from, to))
+ {
+ scc = create_scc (g, scc_nodes);
+ add_scc_to_ddg (sccs, scc);
+ }
+ }
+ order_sccs (sccs);
+ sbitmap_free (from);
+ sbitmap_free (to);
+ sbitmap_free (scc_nodes);
+ return sccs;
+}
+
+/* Frees the memory allocated for all SCCs of the DDG, but keeps the DDG. */
+void
+free_ddg_all_sccs (ddg_all_sccs_ptr all_sccs)
+{
+ int i;
+
+ if (!all_sccs)
+ return;
+
+ for (i = 0; i < all_sccs->num_sccs; i++)
+ free_scc (all_sccs->sccs[i]);
+
+ free (all_sccs);
+}
+
+
+/* Given FROM - a bitmap of source nodes - and TO - a bitmap of destination
+ nodes - find all nodes that lie on paths from FROM to TO (not excluding
+ nodes from FROM and TO). Return non zero if nodes exist. */
+int
+find_nodes_on_paths (sbitmap result, ddg_ptr g, sbitmap from, sbitmap to)
+{
+ int answer;
+ int change, u;
+ int num_nodes = g->num_nodes;
+ sbitmap workset = sbitmap_alloc (num_nodes);
+ sbitmap reachable_from = sbitmap_alloc (num_nodes);
+ sbitmap reach_to = sbitmap_alloc (num_nodes);
+ sbitmap tmp = sbitmap_alloc (num_nodes);
+
+ sbitmap_copy (reachable_from, from);
+ sbitmap_copy (tmp, from);
+
+ change = 1;
+ while (change)
+ {
+ change = 0;
+ sbitmap_copy (workset, tmp);
+ sbitmap_zero (tmp);
+ EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u,
+ {
+ ddg_edge_ptr e;
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ for (e = u_node->out; e != (ddg_edge_ptr) 0; e = e->next_out)
+ {
+ ddg_node_ptr v_node = e->dest;
+ int v = v_node->cuid;
+
+ if (!TEST_BIT (reachable_from, v))
+ {
+ SET_BIT (reachable_from, v);
+ SET_BIT (tmp, v);
+ change = 1;
+ }
+ }
+ });
+ }
+
+ sbitmap_copy (reach_to, to);
+ sbitmap_copy (tmp, to);
+
+ change = 1;
+ while (change)
+ {
+ change = 0;
+ sbitmap_copy (workset, tmp);
+ sbitmap_zero (tmp);
+ EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u,
+ {
+ ddg_edge_ptr e;
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ for (e = u_node->in; e != (ddg_edge_ptr) 0; e = e->next_in)
+ {
+ ddg_node_ptr v_node = e->src;
+ int v = v_node->cuid;
+
+ if (!TEST_BIT (reach_to, v))
+ {
+ SET_BIT (reach_to, v);
+ SET_BIT (tmp, v);
+ change = 1;
+ }
+ }
+ });
+ }
+
+ answer = sbitmap_a_and_b_cg (result, reachable_from, reach_to);
+ sbitmap_free (workset);
+ sbitmap_free (reachable_from);
+ sbitmap_free (reach_to);
+ sbitmap_free (tmp);
+ return answer;
+}
+
+
+/* Updates the counts of U_NODE's successors (that belong to NODES) to be
+ at-least as large as the count of U_NODE plus the latency between them.
+ Sets a bit in TMP for each successor whose count was changed (increased).
+ Returns nonzero if any count was changed. */
+static int
+update_dist_to_successors (ddg_node_ptr u_node, sbitmap nodes, sbitmap tmp)
+{
+ ddg_edge_ptr e;
+ int result = 0;
+
+ for (e = u_node->out; e; e = e->next_out)
+ {
+ ddg_node_ptr v_node = e->dest;
+ int v = v_node->cuid;
+
+ if (TEST_BIT (nodes, v)
+ && (e->distance == 0)
+ && (v_node->aux.count < u_node->aux.count + e->latency))
+ {
+ v_node->aux.count = u_node->aux.count + e->latency;
+ SET_BIT (tmp, v);
+ result = 1;
+ }
+ }
+ return result;
+}
+
+
+/* Find the length of a longest path from SRC to DEST in G,
+ going only through NODES, and disregarding backarcs. */
+int
+longest_simple_path (struct ddg * g, int src, int dest, sbitmap nodes)
+{
+ int i, u;
+ int change = 1;
+ int result;
+ int num_nodes = g->num_nodes;
+ sbitmap workset = sbitmap_alloc (num_nodes);
+ sbitmap tmp = sbitmap_alloc (num_nodes);
+
+
+ /* Data will hold the distance of the longest path found so far from
+ src to each node. Initialize to -1 = less than minimum. */
+ for (i = 0; i < g->num_nodes; i++)
+ g->nodes[i].aux.count = -1;
+ g->nodes[src].aux.count = 0;
+
+ sbitmap_zero (tmp);
+ SET_BIT (tmp, src);
+
+ while (change)
+ {
+ change = 0;
+ sbitmap_copy (workset, tmp);
+ sbitmap_zero (tmp);
+ EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u,
+ {
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ change |= update_dist_to_successors (u_node, nodes, tmp);
+ });
+ }
+ result = g->nodes[dest].aux.count;
+ sbitmap_free (workset);
+ sbitmap_free (tmp);
+ return result;
+}
diff --git a/gcc/ddg.h b/gcc/ddg.h
new file mode 100644
index 00000000000..c958aec1eae
--- /dev/null
+++ b/gcc/ddg.h
@@ -0,0 +1,187 @@
+/* DDG - Data Dependence Graph - interface.
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.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_DDG_H
+#define GCC_DDG_H
+
+/* For sbitmap. */
+#include "sbitmap.h"
+/* For basic_block. */
+#include "basic-block.h"
+/* For struct df. */
+#include "df.h"
+
+typedef struct ddg_node *ddg_node_ptr;
+typedef struct ddg_edge *ddg_edge_ptr;
+typedef struct ddg *ddg_ptr;
+typedef struct ddg_scc *ddg_scc_ptr;
+typedef struct ddg_all_sccs *ddg_all_sccs_ptr;
+
+typedef enum {TRUE_DEP, OUTPUT_DEP, ANTI_DEP} dep_type;
+typedef enum {REG_OR_MEM_DEP, REG_DEP, MEM_DEP, REG_AND_MEM_DEP}
+ dep_data_type;
+
+/* The following two macros enables direct access to the successors and
+ predecessors bitmaps held in each ddg_node. Do not make changes to
+ these bitmaps, unless you want to change the DDG. */
+#define NODE_SUCCESSORS(x) ((x)->successors)
+#define NODE_PREDECESSORS(x) ((x)->predecessors)
+
+/* A structure that represents a node in the DDG. */
+struct ddg_node
+{
+ /* Each node has a unique CUID index. These indices increase monotonically
+ (according to the order of the corresponding INSN in the BB), starting
+ from 0 with no gaps. */
+ int cuid;
+
+ /* The insn represented by the node. */
+ rtx insn;
+
+ /* A note preceding INSN (or INSN itself), such that all insns linked
+ from FIRST_NOTE until INSN (inclusive of both) are moved together
+ when reordering the insns. This takes care of notes that should
+ continue to precede INSN. */
+ rtx first_note;
+
+ /* Incoming and outgoing dependency edges. */
+ ddg_edge_ptr in;
+ ddg_edge_ptr out;
+
+ /* Each bit corresponds to a ddg_node according to its cuid, and is
+ set iff the node is a successor/predecessor of "this" node. */
+ sbitmap successors;
+ sbitmap predecessors;
+
+ /* For general use by algorithms manipulating the ddg. */
+ union {
+ int count;
+ void *info;
+ } aux;
+};
+
+/* A structure that represents an edge in the DDG. */
+struct ddg_edge
+{
+ /* The source and destination nodes of the dependency edge. */
+ ddg_node_ptr src;
+ ddg_node_ptr dest;
+
+ /* TRUE, OUTPUT or ANTI dependency. */
+ dep_type type;
+
+ /* REG or MEM dependency. */
+ dep_data_type data_type;
+
+ /* Latency of the dependency. */
+ int latency;
+
+ /* The distance: number of loop iterations the dependency crosses. */
+ int distance;
+
+ /* The following two fields are used to form a linked list of the in/out
+ going edges to/from each node. */
+ ddg_edge_ptr next_in;
+ ddg_edge_ptr next_out;
+
+ /* For general use by algorithms manipulating the ddg. */
+ union {
+ int count;
+ void *info;
+ } aux;
+};
+
+/* This structure holds the Data Dependence Graph for a basic block. */
+struct ddg
+{
+ /* The basic block for which this DDG is built. */
+ basic_block bb;
+
+ /* Number of instructions in the basic block. */
+ int num_nodes;
+
+ /* Number of load/store instructions in the BB - statistics. */
+ int num_loads;
+ int num_stores;
+
+ /* This array holds the nodes in the graph; it is indexed by the node
+ cuid, which follows the order of the instructions in the BB. */
+ ddg_node_ptr nodes;
+
+ /* The branch closing the loop. */
+ ddg_node_ptr closing_branch;
+
+ /* Build dependence edges for closing_branch, when set. In certain cases,
+ the closing branch can be dealt with separately from the insns of the
+ loop, and then no such deps are needed. */
+ int closing_branch_deps;
+
+ /* Array and number of backarcs (edges with distance > 0) in the DDG. */
+ ddg_edge_ptr *backarcs;
+ int num_backarcs;
+};
+
+
+/* Holds information on an SCC (Strongly Connected Component) of the DDG. */
+struct ddg_scc
+{
+ /* A bitmap that represents the nodes of the DDG that are in the SCC. */
+ sbitmap nodes;
+
+ /* Array and number of backarcs (edges with distance > 0) in the SCC. */
+ ddg_edge_ptr *backarcs;
+ int num_backarcs;
+
+ /* The maximum of (total_latency/total_distance) over all cycles in SCC. */
+ int recurrence_length;
+};
+
+/* This structure holds the SCCs of the DDG. */
+struct ddg_all_sccs
+{
+ /* Array that holds the SCCs in the DDG, and their number. */
+ ddg_scc_ptr *sccs;
+ int num_sccs;
+
+ ddg_ptr ddg;
+};
+
+
+ddg_ptr create_ddg (basic_block, struct df *, int closing_branch_deps);
+void free_ddg (ddg_ptr);
+
+void print_ddg (FILE *, ddg_ptr);
+void vcg_print_ddg (FILE *, ddg_ptr);
+void print_ddg_edge (FILE *, ddg_edge_ptr);
+
+ddg_node_ptr get_node_of_insn (ddg_ptr, rtx);
+
+void find_successors (sbitmap result, ddg_ptr, sbitmap);
+void find_predecessors (sbitmap result, ddg_ptr, sbitmap);
+
+ddg_all_sccs_ptr create_ddg_all_sccs (ddg_ptr);
+void free_ddg_all_sccs (ddg_all_sccs_ptr);
+
+int find_nodes_on_paths (sbitmap result, ddg_ptr, sbitmap from, sbitmap to);
+int longest_simple_path (ddg_ptr, int from, int to, sbitmap via);
+
+#endif /* GCC_DDG_H */
diff --git a/gcc/doc/cfg.texi b/gcc/doc/cfg.texi
new file mode 100644
index 00000000000..caf8c4fc58b
--- /dev/null
+++ b/gcc/doc/cfg.texi
@@ -0,0 +1,615 @@
+@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}. Given two basic blocks A and B, block A
+dominates block B if A is @emph{always} executed before B.
+
+@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 singly linked lists of edges to the predecessors and
+successors 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/tree-ssa.texi b/gcc/doc/tree-ssa.texi
new file mode 100644
index 00000000000..4b5e61684ac
--- /dev/null
+++ b/gcc/doc/tree-ssa.texi
@@ -0,0 +1,1205 @@
+@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}.
+In GIMPLE form, type of @code{MODIFY_EXPR} is not meaningful. Instead, use type
+of LHS or RHS.
+
+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 the 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 are used with variables that can have
+a partial or ambiguous reference. This includes structures, arrays,
+globals, and aliased variables. In these cases, we have two types of
+definitions. For globals, structures, and arrays, we can determine from
+a statement whether a variable of these types has a killing definition.
+If the variable does, then the statement is marked as having a
+@dfn{must definition} of that variable. However, if a statement is only
+defining a part of the variable (ie. a field in a structure), or if we
+know that a statement might define the variable but we cannot say for sure,
+then we mark that statement as having a @dfn{may definition}. 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 = V_MAY_DEF <a>
+ # b = V_MAY_DEF <b>
+ *p = 5;
+
+ # VUSE <a>
+ # VUSE <b>
+ return *p;
+@}
+@end smallexample
+
+Notice that @code{V_MAY_DEF} 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{V_MAY_DEF} 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{V_MAY_DEF_OPS},
+@code{V_MUST_DEF_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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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);
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ print_generic_expr (stderr, V_MAY_DEF_OP (v_may_defs, i), 0);
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ print_generic_expr (stderr, V_MUST_DEF_OP (v_must_defs, 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 = V_MAY_DEF <a_3>;
+ # b_8 = V_MAY_DEF <b_5>;
+ *p_1 = 3;
+
+ # a_9 = V_MAY_DEF <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/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..d4778337951
--- /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_BITFIELD 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/emit-rtl.h b/gcc/emit-rtl.h
new file mode 100644
index 00000000000..c1735ab5e8a
--- /dev/null
+++ b/gcc/emit-rtl.h
@@ -0,0 +1,48 @@
+/* Exported functions from emit-rtl.c
+ 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. */
+
+#ifndef GCC_EMIT_RTL_H
+#define GCC_EMIT_RTL_H
+
+/* Set the alias set of MEM to SET. */
+extern void set_mem_alias_set (rtx, HOST_WIDE_INT);
+
+/* Set the alignment of MEM to ALIGN bits. */
+extern void set_mem_align (rtx, unsigned int);
+
+/* Set the expr for MEM to EXPR. */
+extern void set_mem_expr (rtx, tree);
+
+/* Set the offset for MEM to OFFSET. */
+extern void set_mem_offset (rtx, rtx);
+
+/* Set the size for MEM to SIZE. */
+extern void set_mem_size (rtx, rtx);
+
+/* Return a memory reference like MEMREF, but with its address changed to
+ ADDR. The caller is asserting that the actual piece of memory pointed
+ to is the same, just the form of the address is being changed, such as
+ by putting something into a register. */
+extern rtx replace_equiv_address (rtx, rtx);
+
+/* Likewise, but the reference is not required to be valid. */
+extern rtx replace_equiv_address_nv (rtx, rtx);
+
+#endif /* GCC_EMIT_RTL_H */
diff --git a/gcc/fixinc/tests/base/locale.h b/gcc/fixinc/tests/base/locale.h
new file mode 100644
index 00000000000..3b079e544c9
--- /dev/null
+++ b/gcc/fixinc/tests/base/locale.h
@@ -0,0 +1,20 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/locale.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+#ifndef FIXINC_WRAP_LOCALE_H_ULTRIX_LOCALE
+#define FIXINC_WRAP_LOCALE_H_ULTRIX_LOCALE 1
+
+
+
+#if defined( ULTRIX_LOCALE_CHECK )
+@(#)locale.h 6.1 (ULTRIX)
+
+#endif /* ULTRIX_LOCALE_CHECK */
+
+#endif /* FIXINC_WRAP_LOCALE_H_ULTRIX_LOCALE */
diff --git a/gcc/fixinc/tests/base/mach-o/dyld.h b/gcc/fixinc/tests/base/mach-o/dyld.h
new file mode 100644
index 00000000000..c0620312d34
--- /dev/null
+++ b/gcc/fixinc/tests/base/mach-o/dyld.h
@@ -0,0 +1,17 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/mach-o/dyld.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+
+
+#if defined( DARWIN_PRIVATE_EXTERN_CHECK )
+extern int _dyld_func_lookup(
+const char *dyld_func_name,
+unsigned long *address);
+
+#endif /* DARWIN_PRIVATE_EXTERN_CHECK */
diff --git a/gcc/fixinc/tests/base/standards.h b/gcc/fixinc/tests/base/standards.h
new file mode 100644
index 00000000000..fccf8063fa3
--- /dev/null
+++ b/gcc/fixinc/tests/base/standards.h
@@ -0,0 +1,14 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/standards.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+
+
+#if defined( ALPHA___EXTERN_PREFIX_STANDARDS_CHECK )
+#if (_ISO_C_SOURCE>=19990L) && !defined(_LIBC_POLLUTION_H_) && !defined(__DECC) && !defined(__PRAGMA_EXTERN_PREFIX)
+#endif /* ALPHA___EXTERN_PREFIX_STANDARDS_CHECK */
diff --git a/gcc/fixinc/tests/base/wchar.h b/gcc/fixinc/tests/base/wchar.h
new file mode 100644
index 00000000000..5c0b9dfe86a
--- /dev/null
+++ b/gcc/fixinc/tests/base/wchar.h
@@ -0,0 +1,15 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/wchar.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+
+
+#if defined( ALPHA_WCHAR_CHECK )
+extern wchar_t *wcstok __((wchar_t *, const wchar_t *, wchar_t **)) __asm__("wcstok_r");
+extern size_t wcsftime __((wchar_t *, size_t, const wchar_t *, const struct tm *)) __asm__("__wcsftime_isoc");
+#endif /* ALPHA_WCHAR_CHECK */
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..ad9aa2ca59b
--- /dev/null
+++ b/gcc/fortran/ChangeLog
@@ -0,0 +1,3930 @@
+2004-07-04 Janne Blomqvist <jblomqvi@cc.hut.fi>
+ Paul Brook <paul@codesourcery.com>
+
+ PR fortran/15280
+ PR fortran/15665
+ * gfortran.h (enum gfc_generic_isym_id): Add GFC_ISYM_IARGC and
+ GFC_ISYM_COMMAND_ARGUMENT_COUNT.
+ * intrinsic.c (add_functions): Identify iargc. Add
+ command_argument_count.
+ (add_subroutines): Resolve getarg. Add get_command and
+ get_command_argument.
+ * intrinsic.h (gfc_resolve_getarg, gfc_resolve_get_command,
+ gfc_resolve_get_command_argument): Add prototypes.
+ * iresolve.c (gfc_resolve_getarg, gfc_resolve_get_command,
+ gfc_resolve_get_command_argument): New functions.
+ * trans-decl.c (gfor_fndecl_iargc): New variable.
+ (gfc_build_intrinsic_function_decls): Set it.
+ * trans-intrinsic.c (gfc_conv_intrinsic_iargc): New function.
+ (gfc_conv_intrinsic_function): Use it.
+ * trans.h (gfor_fndecl_iargc): Declare.
+
+2004-07-04 Matthias Klose <doko@debian.org>
+
+ * Make-lang.in: Generate and install gfortran man page.
+ * invoke.texi: Remove extra '@c man end'.
+
+2004-07-04 Richard Henderson <rth@redhat.com>
+
+ * f95-lang.c (gfc_mark_addressable): Don't put_var_into_stack.
+
+2004-07-04 Paul Brook <paul@codesourcery.com>
+
+ * decl.c (gfc_match_implicit_range): Don't use typespec.
+ (gfc_match_implicit): Handle character selectors.
+ * gfortran.h (gfc_set_implicit): Remove prototype.
+ (gfc_add_new_implicit_range, gfc_merge_new_implicit): Update.
+ * parse.c (accept_statement): Don't call gfc_set_implicit.
+ * symbol.c (new_ts): Remove.
+ (gfc_set_implicit_none): Use same loop bounds as other functions.
+ (gfc_set_implicit): Remove.
+ (gfc_clear_new_implicit, gfc_add_new_implicit_range): Only set flags.
+ (gfc_merge_new_implicit): Combine with gfc_set_implicit.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * match.c (var_element): Remove unused variable.
+
+ * trans-decl.c (gfc_generate_function_code): Don't set
+ x_whole_function_mode_p.
+ (gfc_generate_constructors): Likewise.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * trans-decl.c (gfc_generate_function_code): Don't set
+ immediate_size_expand.
+ (gfc_generate_constructors): Likewise.
+
+2004-06-30 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/16161
+ * decl.c (gfc_match_type_spec): Rename second argument to
+ 'implicit_flag', reverse meaning. Don't match_char_spec if
+ 'implicit_flag' is set. Rename to ...
+ (match_type_spec): ... this.
+ (gfc_match_implicit_none, match_implicit_range): Move here
+ from match.c.
+ (gfc_match_implicit): Move here from match.c, try to
+ match_char_len if match_implicit_range doesn't succeed for
+ CHARACTER implicits. Call renamed fucntion match_type_spec.
+ (gfc_match_data_decl, match_prefix): Call renamed function
+ match_type_spec.
+ * match.c (gfc_match_implicit_none, match_implicit_range,
+ gfc_match_implicit): Move to decl.c.
+ * match.h (gfc_match_implicit_none, gfc_match_implicit):
+ Move protoypes to section 'decl.c'.
+ (gfc_match_type_spec): Remove prototype.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * decl.c, interface.c, symbol.c, trans-common.c: Add 2004 to
+ copyright years.
+
+2004-06-29 Steven Bosscher <stevenb@suse.de>
+
+ Make sure types in assignments are compatible. Mostly mechanical.
+ * trans-const.h (gfc_index_one_node): New define.
+ * trans-array.c (gfc_trans_allocate_array_storage,
+ gfc_trans_allocate_temp_array, gfc_trans_array_constructor_subarray,
+ gfc_trans_array_constructor_value, gfc_trans_array_constructor,
+ gfc_conv_array_ubound, gfc_conv_array_ref,
+ gfc_trans_scalarized_loop_end, gfc_conv_section_startstride,
+ gfc_conv_ss_startstride, gfc_conv_loop_setup, gfc_array_init_size,
+ gfc_trans_array_bounds, gfc_trans_dummy_array_bias,
+ gfc_conv_expr_descriptor, gfc_trans_deferred_array): Use the correct
+ types in assignments, conversions and conditionals for expressions.
+ * trans-expr.c (gfc_conv_expr_present, gfc_conv_substring,
+ gfc_conv_unary_op, gfc_conv_cst_int_power, gfc_conv_string_tmp,
+ gfc_conv_function_call, gfc_trans_pointer_assignment,
+ gfc_trans_scalar_assign): Likewise.
+ * trans-intrinsic.c (build_fixbound_expr, gfc_conv_intrinsic_bound,
+ gfc_conv_intrinsic_anyall, gfc_conv_intrinsic_count,
+ gfc_conv_intrinsic_minmaxloc, gfc_conv_intrinsic_btest,
+ gfc_conv_intrinsic_singlebitop, gfc_conv_intrinsic_ishft,
+ gfc_conv_intrinsic_ishftc, gfc_conv_intrinsic_strcmp,
+ gfc_conv_allocated, gfc_conv_associated,
+ gfc_conv_intrinsic_rrspacing, gfc_conv_intrinsic_trim): Likewise.
+ * trans-io.c (set_string): Likewise.
+ * trans-stmt.c (gfc_trans_do, gfc_trans_forall_loop,
+ gfc_do_allocate, generate_loop_for_temp_to_lhs,
+ generate_loop_for_rhs_to_temp, compute_inner_temp_size,
+ compute_overall_iter_number, gfc_trans_assign_need_temp,
+ gfc_trans_pointer_assign_need_temp, gfc_trans_forall_1,
+ gfc_evaluate_where_mask, gfc_trans_where_assign,
+ gfc_trans_where_2): Likewise.
+ * trans-types.c (gfc_get_character_type, gfc_build_array_type,
+ gfc_get_nodesc_array_type, gfc_get_array_type_bounds): Likewise.
+
+ * trans.c (gfc_add_modify_expr): Add sanity check that types
+ for the lhs and rhs are the same for scalar assignments.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * dump-parse-tree.c (show_common): New function.
+ (gfc_show_namespace): Show commons.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+ Andrew Vaught <andyv@firstinter.net>
+
+ PR fortran/13249
+ PR fortran/15481
+ * decl.c (gfc_match_save): Adapt to new common structures,
+ don't allow saving USE-associated common.
+ * dump-parse-tree (gfc_show_attr): (saved_)common are not
+ symbol attributes any longer.
+ (gfc_show_symbol): Don't show old-style commons any longer.
+ (gfc_show_namespace): Adapt call to gfc_traverse_symtree to new
+ interface.
+ * gfortran.h (symbol_attribute): Remove common and saved_common
+ attributes.
+ (gfc_symbol): Remove common_head element.
+ (gfc_common_head): New struct.
+ (gfc_get_common_head): New macro.
+ (gfc_symtree): Add field 'common' to union.
+ (gfc_namespace): Add field 'common_root'; change type of field
+ 'blank_common' to blank_common.
+ (gfc_add_data): New prototype.
+ (gfc_traverse_symtree): Expect a symtree as first argument
+ instead of namespace.
+ * match.c (gfc_get_common): New function.
+ (match_common_name): Change to take char * as argument, adapt,
+ fix bug with empty name.
+ (gfc_match_common): Adapt to new data structures. Disallow
+ redeclaration of USE-associated COMMON-block. Fix bug with
+ empty common.
+ (var_element): Adapt to new common structures.
+ * match.h (gfc_get_common): Declare.
+ * module.c: Add 2004 to copyright years, add commons to module
+ file layout description.
+ (ab_attribute, attr_bits, mio_symbol_attributes): Remove code
+ for removed attributes.
+ (mio_symbol): Adapt to new way of storing common relations.
+ (load_commons): New function.
+ (read_module): Skip common list on first pass, load_commons at
+ second.
+ (write_commons): New function.
+ (write_module): Call write_commons().
+ * symbol.c (gfc_add_saved_comon, gfc_add_common): Remove
+ functions related to removed attributes.
+ (gfc_add_data): New function.
+ (gfc_clear_attr): Don't set removed attributes.
+ (gfc_copy_attr): Don't copy removed attributes.
+ (traverse_symtree): Remove.
+ (gfc_traverse_symtree): Don't traverse symbol
+ tree of the passed namespace, but require a symtree to be passed
+ instead. Unify with traverse_symtree.
+ (gfc_traverse_ns): Call gfc_traverse_symtree according to new
+ interface.
+ (save_symbol): Remove setting of removed attribute.
+ * trans-common.c (gfc_sym_mangled_common_id): Change to
+ take 'char *' argument instead of 'gfc_symbol'.
+ (build_common_decl, new_segment, translate_common): Adapt to new
+ data structures, add new
+ argument name.
+ (create_common): Adapt to new data structures, add new
+ argument name. Fix typo in intialization of derived types.
+ (finish_equivalences): Add second argument in call to
+ create_common.
+ (named_common): take 'gfc_symtree' instead of 'gfc_symbol'.
+ (gfc_trans_common): Adapt to new data structures.
+ * trans-decl.c (gfc_create_module_variables): Remove test for
+ removed attribute.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * io.c: Add 2004 to copyright years.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+ Andrew Vaught <andyv@firstinter.net>
+
+ * gfortran.h (gfc_gsymbol): New typedef.
+ (gfc_gsym_root): New variable.
+ (gfc_get_gsymbol, gfc_find_gsym): New prototypes.
+ * parse.c (global_used): New function.
+ (parse_block_data): Check for double empty BLOCK DATA,
+ use global symbol table.
+ (parse_module): Use global symbol table.
+ (add_global_procedure, add_global_program): New functions.
+ (gfc_parse_file): Use global symbol table.
+ * symbol.c (gfc_gsym_root): New variable.
+ (gfc_find_gsym, gsym_compare, gfc_get_gsymbol): New
+ functions.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * module.c (mio_gmp_real): Correct writing of negative numbers.
+
+2004-06-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15963
+ * expr.c (check_intrinsic_op): Allow comparison of characters.
+ Make logic easier.
+
+2004-06-26 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+ Andrew Vaught <andyv@firstinter.net>
+
+ * decl.c (contained_procedure): New function.
+ (match_end): Verify correctness of END STATEMENT in
+ all cases.
+
+2004-06-26 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+ Andrew Vaught <andyv@firstinter.net>
+
+ PR fortran/15190
+ * decl.c (gfc_match_type_spec), io.c (match_io), parse.c
+ (decode_statement): Enforce required space in free-form.
+
+2004-06-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * f95-lang.c (LANG_HOOKS_GIMPLE_BEFORE_INLINING): Deleted.
+ * trans-array.c (gfc_conv_descriptor_data): Add operand
+ for COMPONENT_REF.
+ (gfc_conv_descriptor_offset, gfc_conv_descriptor_dtype): Likewise.
+ (gfc_conv_descriptor_dimension, gfc_conv_descriptor_stride): Likewise.
+ (gfc_conv_descriptor_lbound, gfc_conv_descriptor_ubound): Likewise.
+ * trans-common.c (create_common): Likewise.
+ * trans-expr.c (gfc_conv_component_ref): Likewise.
+ * trans-io.c (set_parameter_value): Likewise.
+ (set_parameter_ref, set_string, set_flag, io_result): Likewise.
+ (transfer_expr): Likewise.
+ * trans-decl.c (gfc_trans_auto_character_variable):
+ Set up to get DECL_SIZE and DECL_SIZE_UNIT gimplified.
+ (gfc_gimplify_function): New function.
+ (gfc_generate_function-code): Properly handle nested functions.
+ * trans.c (gfc_build_array_ref): Add two new operands for ARRAY_REF.
+
+2004-06-22 Janne Blomqvist <jblomqvi@cc.hut.fi>
+
+ PR fortran/15750
+ * io.c (gfc_match_inquire): Bugfix for iolength related stuff.
+ (gfc_resolve_inquire): Resolve the iolength tag. Return
+ SUCCESS at end of function if no failure has occured.
+ * resolve.c (resolve_code): Resolve if iolength is encountered.
+ * trans-io.c: (ioparm_iolength, iocall_iolength,
+ iocall_iolength_done): New variables.
+ (last_dt): Add IOLENGTH.
+ (gfc_build_io_library_fndecls ): Set iolength related variables.
+ (gfc_trans_iolength): Implement.
+ (gfc_trans_dt_end): Treat iolength as a third form of data transfer.
+
+2004-06-21 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de
+
+ PR fortran/15511
+ * scanner.c (load_line): Don't truncate preprocessor lines.
+ Reformat error message.
+ (preprocessor_line): Issue warning in case of malformed
+ preprocessor line.
+
+2004-06-21 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * resolve.c (resolve_symbol): Add comment in function body.
+ (check_data_variable): Change type of mark to ar_type, adapt code
+ accordingly.
+
+2004-06-21 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * array.c (gfc_insert_constructor): Avoid redundant call to
+ mpz_comp. Add 2004 to copyright years.
+
+2004-06-21 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * trans.h (stmtblock_t): Change has_scope to unsigned int.
+
+2004-06-20 Steven G. Kargl <kargls@comcast.net>
+
+ * arith.c (gfc_range_check): correct complex underflow.
+
+2004-06-15 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15962
+ * match.c (match_case_selector): Call gfc_match_init_expr
+ instead of gfc_match_expr.
+ * resolve.c (validate_case_label_expr): No need to check for
+ constant, since it wouldn't have been matched with the fix to
+ match.c.
+
+2004-06-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15211
+ * trans-intrinsic.c (gfc_conv_intrinsic_len): Deal with arrays
+ of strings.
+
+2004-06-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15510
+ * trans-deecl.c (generate_local_decl): Do not issue warning for
+ unused variables if they're use associated.
+
+2004-06-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+ Andrew Vaught <andyv@firstinter.net>
+
+ PR fortran/14928
+ * gfortran.h (gfc_check_f): Add new field f3ml.
+ * check.c (gfc_check_minloc_maxloc): Take argument list instead
+ of individual arguments, reorder if necessary.
+ * intrinsic.h (gfc_check_minloc_maxloc): ... adapt prototype.
+ * intrinsic.c (add_sym_3ml): New function.
+ (add_functions): Change to add_sym_3ml for MINLOC, MAXLOC.
+ (check_specific): Catch special case MINLOC, MAXLOC.
+
+2004-06-14 Paul Brook <paul@codesourcery.com>
+
+ * intrinsic.c (add_sym_2s): Use correct function types.
+
+2004-06-12 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * Make-lang.in (F95_OBJS, F95_PARSER_OBJS): Alphabetize. Move data.c
+ * data.c (gfc_get_section_index): Remove dependency on trans.h.
+
+2004-06-12 Steven G. Kargl <kargls@comcast.net>
+
+ * check.c (gfc_check_second_sub, gfc_check_irand, gfc_check_rand
+ gfc_check_srand, gfc_check_etime, gfc_check_etime_sub): New functions.
+ * gfortran.h (gfc_generic_isym_id): New symbols GFC_ISYM_ETIME,
+ GFC_ISYM_IRAND, GFC_ISYM_RAND, GFC_ISYM_SECOND.
+ * trans-intrinsic.c: Use symbols.
+ * intrinsic.c (add_sym_2s): New function.
+ * intrinsic.c: Add etime, dtime, irand, rand, second, srand.
+ * intrinsic.h: Function prototypes.
+ * iresolve.c (gfc_resolve_etime_sub, gfc_resolve_second_sub
+ gfc_resolve_srand): New functions.
+
+2004-06-12 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/14957
+ * decl.c (gfc_match_end): Require END {SUBROUTINE|FUNCTION} for
+ contained procedure.
+
+2004-06-12 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/12841
+ * interface.c (compare_parameter, compare_actual_formal): Don't
+ check types and array shapes for NULL()
+ * trans-expr.c (conv_function_call): No double indirection for
+ NULL()
+
+2004-06-09 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * trans-expr.c (gfc_conv_cst_int_power): Compute
+ x**(-n) by converting it to (1/x)**n instead of
+ 1/x**n.
+
+2004-06-09 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13372
+ * module.c (write_symbol, write_symtree): Don't write symbols
+ wrongly added to namespace.
+ * trans-decl.c (gfc_create_module_variable): Don't create a
+ backend decl for a symbol incorrectly added to namespace.
+
+2004-06-09 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13201
+ * resolve.c (resolve_symbol): Verify that parameter array has an
+ explicit shape. Fix typos and coding style issues in surrounding
+ lines.
+
+2004-06-05 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15478
+ * gfortran.texi: The documentation doesn't contain infomration on
+ how to report bugs, and shouldn't, so remove the line which
+ says it does.
+
+2004-06-05 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * intrinsic.c (sort_actual): Keep track of type of missing
+ arguments. (Missing from previous commit.)
+
+2004-06-03 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * gfortran.h (gfc_actual_arglist): New field missing_arg_type.
+ * interface.c (compare_actual_formal): Keep type of omitted
+ optional arguments.
+ * trans-expr.c (gfc_conv_function_call): Add string length
+ argument for omitted string argument.
+
+2004-06-03 Paul Brook <paul@codesourcery.com>
+
+ * trans.c (gfc_finish_block, gfc_add_expr_to_block): Build statement
+ lists instead of compound expr chains.
+ (gfc_trans_code): Annotate statement lists.
+
+2004-06-03 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * trans-array.c: Fix spelling in comments.
+
+2004-06-02 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15557
+ * data.c (assign_substring_data_value): New function.
+ (gfc_assign_data_value): Call the new function if we're dealing
+ with a substring LHS.
+
+2004-06-01 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15477
+ * gfortran.h (GFC_VERSION): Remove.
+ * gfortran.texi (version-gfortran): Remove, replace by version-GCC
+ where used.
+
+2004-05-31 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * trans-types.c: Fix spelling & layout in comments.
+
+2004-05-30 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/14067
+ * trans-const.c (gfc_conv_string_init): Allow variable string
+ length lower than initialization string length.
+
+2004-05-30 Paul Brook <paul@codesourcery.com>
+
+ PR fortran/15620
+ * trans-decl.c (gfc_shadow_sym, gfc_restore_sym): New functions.
+ * trans-expr.c (gfc_trans_string_copy): New function.
+ (gfc_conv_statement_function): Use them. Create temp vars. Enforce
+ character lengths.
+ (gfc_conv_string_parameter): Use gfc_trans_string_copy.
+ * trans-stmt.c (gfc_trans_forall_1): Use gfc_{shadow,restore}_sym.
+ * trans.h (struct gfc_saved_var): Define.
+ (gfc_shadow_sym, gfc_restore_sym): Add prototypes.
+
+2004-05-30 Steven G. Kargl <kargls@comcast.net>
+
+ * iresolve.c (gfc_resolve_random_number): Clean up conditional.
+
+2004-05-29 Steven G. Kargl <kargls@comcast.net>
+
+ * simplify.c (gfc_simplify_log): Remove useless line of code.
+
+2004-05-29 Paul Brook <paul@codesourcery.com>
+
+ * trans-common.c (find_equivalence): Find multiple rules.
+
+2004-05-27 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * gfortran.h (gfc_current_locus, gfc_set_locus): Remove.
+ (gfc_current_locus): Declare new global variable.
+ * scanner.c (gfc_current_locus, gfc_set_locus): Remove.
+ (gfc_current_locus1): Rename ...
+ (gfc_current_locus): ... to this.
+ (gfc_at_eof, gfc_at_bol, gfc_at_eol, gfc_advance_line, next_char,
+ skip_fixed_comments, skip_free_comments, gfc_next_char_literal,
+ gfc_peek_char, gfc_gobble_whitespace, gfc_new_file): Use
+ gfc_current_locus instead of gfc_current_locus1, gfc_set_locus()
+ and gfc_current_locus(), respectively.
+ * array.c (match_subscript, gfc_match_array_ref, match_array_list,
+ match_array_cons_element, gfc_match_array_constructor):
+ Read/modify gfc_current_locus instead of calling gfc_set_locus()
+ and gfc_current_locus().
+ * decl.c (gfc_match_null, variable_decl, gfc_match_kind_spec,
+ match_attr_spec, gfc_match_function_decl, gfc_match_end,
+ attr_decl1, gfc_match_save): Likewise.
+ * error.c (error_print, gfc_internal_error): Likewise.
+ * expr.c (gfc_int_expr, gfc_default_logical_kind): Likewise.
+ * interface.c (gfc_add_interface): Likewise.
+ * io.c (gfc_match_format, match_dt_format, match_dt_element,
+ match_io_iterator, match_io): Likewise.
+ * match.c (gfc_match_space, gfc_match_eos,
+ gfc_match_small_literal_int, gfc_match_st_label,
+ gfc_match_strings, gfc_match_name, gfc_match_iterator,
+ gfc_match_char, gfc_match, gfc_match_assignment,
+ gfc_match_pointer_assignment, gfc_match_if, gfc_match_do,
+ gfc_match_nullify, gfc_match_call, match_implicit_range,
+ gfc_match_implicit, gfc_match_data, match_case_selector,
+ gfc_match_case, match_forall_iterator): Likewise.
+ * matchexp.c (gfc_match_defined_op_name, next_operator,
+ match_level_1, match_mult_operand, match_ext_mult_operand,
+ match_add_operand, match_ext_add_operand, match_level_2,
+ match_level_3, match_level_4, match_and_operand, match_or_operand,
+ match_equiv_operand, match_level_5, gfc_match_expr): Likewise.
+ * module.c (gfc_match_use, mio_array_ref, mio_expr): Likewise.
+ * parse.c (match_word, decode_statement, next_free, next_fixed,
+ add_statement, verify_st_order, parse_if_block, gfc_parse_file):
+ Likewise.
+ * primary.c (match_digits, match_integer_constant,
+ match_boz_constant, match_real_constant, match_substring,
+ next_string_char, match_charkind_name, match_string_constant,
+ match_logical_constant, match_const_complex_part,
+ match_complex_constant, match_actual_arg, match_keyword_arg,
+ gfc_match_actual_arglist, gfc_match_structure_constructor,
+ gfc_match_rvalue, gfc_match_variable): Likewise.
+ * st.c (gfc_get_code): Likewise.
+ * symbol.c (check_conflict, check_used, check_done,
+ duplicate_attr, add_flavor, gfc_add_procedure, gfc_add_intent,
+ gfc_add_access, gfc_add_explicit_interface, gfc_add_type,
+ gfc_add_component, gfc_reference_st_label, gfc_new_symbol): Likewise.
+
+2004-05-26 Roger Sayle <roger@eyesopen.com>
+
+ * io.c (format_asterisk): Silence compiler warnings by correcting
+ the number of elements of a "locus" initializer.
+
+2004-05-25 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/13912
+ * matchexp.c: Allow unary operators after arithmetic operators
+ as a GNU extension.
+ (match_ext_mult_operand, match_ext_add_operand): New functions.
+ (match_mult_operand): Tweak to call match_ext_mult_operand.
+ (match_add_operand): Tweak to call match_ext_mult_operand.
+ (match_level_2): Rearrange to call match_ext_add_operand.
+
+2004-05-25 Paul Brook <paul@codesourcery.com>
+
+ * expr.c (check_inquiry): Remove bogus tests.
+
+2004-05-23 Paul Brook <paul@codesourcery.com>
+
+ PR fortran/13773
+ * expr.c (restricted_args): Remove redundant checks/argument.
+ (external_spec_function): Update to match.
+ (restricted_intrinsic): Rewrite.
+
+2004-05-23 Paul Brook <paul@codesourcery.com>
+ Victor Leikehman <lei@haifasphere.co.il>
+
+ * gfortran.h (struct gfc_symbol): Add equiv_built.
+ * trans-common.c: Change int to HOST_WIDE_INT. Capitalize error
+ messages.
+ (current_length): Remove.
+ (add_segments): New function.
+ (build_equiv_decl): Create initialized common blocks.
+ (build_common_decl): Always add decl to bindings.
+ (create_common): Create initializers.
+ (find_segment_info): Reformat to match coding conventions.
+ (new_condition): Use add_segments.
+ (add_condition, find_equivalence, add_equivalences): Move iteration
+ inside functions. Only process each segment once.
+ (new_segment, finish_equivalences, translate_common): Simplify.
+
+2004-05-23 Steven G. Kargl <kargls@comcast.net>
+
+ * check.c (gfc_check_random_seed): Issue for too many arguments.
+
+2004-05-22 Steven G. Kargl <kargls@comcast.net>
+
+ * intrinsic.c (add_subroutines): Use add_sym_3s for random_seed.
+
+2004-05-22 Paul Brook <paul@codesourcery.com>
+
+ * dump-parse-tree.c (gfc_show_equiv): New function.
+ (gfc_show_namespace): Use it.
+
+2004-05-22 Victor Leikehman <lei@haifasphere.co.il>
+
+ PR fortran/13249
+ * symbol.c (gfc_add_common): Disable checks to work around other more
+ fundamental inadequacies.
+
+2004-05-22 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * trans-decl.c (gfc_get_extern_function_decl): Set DECL_IS_PURE
+ only for functions.
+ (gfc_build_function_decl): Likewise.
+
+2004-05-22 Steven G. Kargl <kargls@comcast.net>
+
+ * check.c (gfc_check_system_clock): New function.
+ * intrinsic.c (add_sym_3s): New function.
+ (add_subroutines): Use it.
+ * intrinsic.h (gfc_check_system_clock, gfc_resolve_system_clock):
+ Add prototypes.
+ * iresolve.c (gfc_resolve_system_clock): New function.
+
+2004-05-22 Steven G. Kargl <kargls@comcast.net>
+
+ * invoke.texi: Document -Wunderflow and spell check.
+ * lang.opt: Add Wunderflow.
+ * gfortran.h (gfc_option_t): Add warn_underflow option.
+ * options.c (gfc_init_options, set_Wall): Use it.
+ * primary.c (match_real_constant): Explicitly handle UNDERFLOW.
+ * arith.c (gfc_arith_uminus, gfc_arith_plus, gfc_arith_minus,
+ gfc_arith_times, gfc_arith_divide, gfc_arith_power, gfc_real2real,
+ gfc_real2complex, gfc_complex2real, gfc_complex2complex): Ditto.
+ * arith.c (common_logarithm): Fix typo in comment.
+
+2004-05-21 Roger Sayle <roger@eyesopen.com>
+
+ * io.c (check_format): As a GNU extension, allow the comma after a
+ string literal to be optional in a format. Use gfc_notify_std to
+ issue an error/warning as appropriate.
+
+2004-05-21 Roger Sayle <roger@eyesopen.com>
+
+ * io.c (check_format): Use gfc_notify_std to determine whether to
+ issue an error/warning for omitting the digits from the X format.
+
+2004-05-20 Roger Sayle <roger@eyesopen.com>
+
+ * io.c (check_format): Allow the number before the X format to
+ be optional when not -pedantic.
+
+2004-05-18 Feng Wang <fengwang@nudt.edu.cn>
+ Paul Brook <paul@codesourcery.com>
+
+ * f95-lang.c (gfc_init_builtin_functions): Use vold_list_node.
+ Create decls for __builtin_pow{,f}.
+ * gfortran.h (PREFIX_LEN): Define.
+ * trans-decl.c (gfor_fndecl_math_powi): Add.
+ (gfor_fndecl_math_powf, gfor_fndecl_math_pow): Remove.
+ (gfc_build_intrinsic_function_decls): Create decls for powi.
+ * trans-expr.c (powi_table): Add.
+ (gfc_conv_integer_power): Remove.
+ (gfc_conv_powi): New function.
+ (gfc_conv_cst_int_power): New function.
+ (gfc_conv_power_op): Use new powi routines.
+ * trans.h (struct gfc_powdecl_list): Add.
+ (gfor_fndecl_math_powi): Add.
+ (gfor_fndecl_math_powf, gfor_fndecl_math_pow): Remove.
+
+2004-05-18 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * trans.c, trans-decl.c: Fix comment typos.
+
+2004-05-18 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * trans-const.c (gfc_conv_mpf_to_tree): Fix typo.
+
+2004-05-18 Steve Kargl <kargls@comcast.net>
+
+ * arith.c (gfc_int2complex): Fix incorrect range checking.
+
+2004-05-18 Paul Brook <paul@codesourcery.com>
+
+ PR fortran/13930
+ * decl.c (add_init_expr_to_sym): Remove incorrect check.
+ (default_initializer): Move to expr.c.
+ (variable_decl): Don't assign default initializer to variables.
+ * expr.c (gfc_default_initializer): Move to here.
+ * gfortran.h (gfc_default_initializer): Add prototype.
+ * resolve.c (resolve_symbol): Check for illegal initializers.
+ Assign default initializer.
+
+2004-05-17 Steve Kargl <kargls@comcast.net>
+
+ * arith.c (gfc_arith_power): Complex number raised to 0 power is 1.
+
+2004-05-17 Steve Kargl <kargls@comcast.net>
+
+ * arith.c (gfc_real2complex): Range checking wrong part of complex
+ number.
+
+2004-05-16 Paul Brook <paul@codesourcery.com>
+
+ * options.c (gfc_handle_module_path_options): Fix buffer overrun.
+
+2004-05-16 Paul Brook <paul@codesourcery.com>
+
+ * arith.c (gfc_range_check): Fix logic error.
+
+2004-05-16 Steve Kargl <sgk@troutmask.apl.washington.edu>
+
+ * arith.c: Fix comment typos.
+
+2004-05-15 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13742
+ * decl.c (add_init_expr_to_sym): Verify that COMMON variable is
+ not initialized in a disallowed fashion.
+ * match.c (gfc_match_common): Likewise.
+ (var_element): Verify that variable is not in the blank COMMON,
+ if it is in a common.
+
+2004-05-15 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (f95.generated-manpages): Remove.
+ (f95.srcextra): New.
+ (f95.info, fortran/gfortran.info, fortran/gfortran.dvi,
+ f95.maintainer-clean): Generate info and dvi files in objdir/doc.
+ (f95.dvi): Remove.
+ (dvi): New.
+ (f95.install-info): Remove.
+ (install-info): New.
+
+2004-05-15 Victor Leikehman <lei@haifasphere.co.il>
+
+ * decl.c (add_init_expr_to_sym): Check for variable size arrays.
+
+2004-05-15 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * primary.c (match_boz_constant): Use gfc_notify_std() for
+ issuing a warning or an error.
+
+2004-05-15 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13826
+ * primary.c (match_structure_constructor): Rename ...
+ (gfc_match_structure_constructor): ... to this. Make non-static.
+ (gfc_match_rvalue): Call renamed function.
+ * match.h (gfc_match_structure_constructor): Declare.
+ * match.c (gfc_match_data_constant): Handle structure
+ constructor.
+
+2004-05-15 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13702
+ (Port from g95)
+ * gfortran.h (gfc_linebuf): New typedef.
+ (linebuf): Remove.
+ (gfc_file): Revamped, use new gfc_linebuf.
+ (locus): Revamped, use new types.
+ (gfc_current_file): Remove.
+ (gfc_current_form, gfc_source_file): New global variables.
+ * match.c (gfc_match_space, gfc_match_strings): Use
+ gfc_current_form to find source form.
+ * module.c (gfc_dump_module): Use gfc_source_file when printing
+ module header.
+ * error.c (show_locus, show_loci) Use new data structures to print
+ locus.
+ * scanner.c (first_file, first_duplicated_file, gfc_current_file):
+ Remove.
+ (file_head, current_file, gfc_current_form, line_head, line_tail,
+ gfc_current_locus1, gfc_source_file): New global variables.
+ (gfc_scanner_init1): Set new global variables.
+ (gfc_scanner_done1): Free new data structures.
+ (gfc_current_locus): Return pointer to gfc_current_locus1.
+ (gfc_set_locus): Set gfc_current_locus1.
+ (gfc_at_eof): Set new variables.
+ (gfc_at_bol, gfc_at_eol, gfc_advance_line, gfc_next_char): Adapt
+ to new locus structure.
+ (gfc_check_include): Remove.
+ (skip_free_comments, skip_fixed_comments): Use gfc_current_locus1.
+ (gfc_skip_comments): Use gfc_current_form, find locus with
+ gfc_current_locus1.
+ (gfc_next_char): Use gfc_current_form.
+ (gfc_peek_char, gfc_gobble_whitespace): Use gfc_current_locus1.
+ (load_line): Use gfc_current_form. Recognize ^Z as EOF. Fix
+ comment formatting.
+ (get_file): New function.
+ (preprocessor_line, include_line): New functions.
+ (load_file): Move down, rewrite to match new data structures.
+ (gfc_new_file): Rewrite to match new data structures.
+ * parse.c (next_statement): Remove code which is now useless. Use
+ gfc_source_form and gfc_source_file where appropriate.
+ * trans-decl.c (gfc_get_label_decl): adapt to new data structures
+ when determining locus of frontend code.
+ * trans-io.c (set_error_locus): Same.
+ * trans.c (gfc_get_backend_locus, gfc_set_backend_locus): Likewise.
+ * lang-specs.h (@f77-cpp-input, @f95-cpp-input): Remove '-P' from
+ preprocessor flags.
+ (all): Add missing initializers.
+
+2004-05-15 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * Make-lang.in (trans-common.o): Remove redundant dependency.
+ (data.c): Replace object file name ...
+ (data.o): ... by the correct one.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * dump-parse-tree.c (gfc_show_array_ref): Print colon only
+ for ranges when dumping array references.
+
+2004-05-14 Victor Leikehman <lei@haifasphere.co.il>
+
+ * decl.c (variable_decl): Always apply default initializer.
+
+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..de4a0054535
--- /dev/null
+++ b/gcc/fortran/Make-lang.in
@@ -0,0 +1,298 @@
+# -*- 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 := $(shell echo gfortran|sed '$(program_transform_name)')
+
+# Actual name to use when installing a cross-compiler.
+GFORTRAN_CROSS_NAME := $(shell 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/data.o fortran/decl.o fortran/dump-parse-tree.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/options.o fortran/parse.o fortran/primary.o fortran/resolve.o \
+ fortran/scanner.o fortran/simplify.o fortran/st.o fortran/symbol.o
+
+F95_OBJS = $(F95_PARSER_OBJS) \
+ fortran/convert.o fortran/dependency.o fortran/f95-lang.o \
+ fortran/trans.o fortran/trans-array.o fortran/trans-common.o \
+ fortran/trans-const.o fortran/trans-decl.o fortran/trans-expr.o \
+ fortran/trans-intrinsic.o fortran/trans-io.o fortran/trans-stmt.o \
+ fortran/trans-types.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: doc/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: doc/gfortran.info
+dvi:: doc/gfortran.dvi
+
+F95_MANFILES = doc/gfortran.1
+
+f95.man: $(F95_MANFILES)
+
+f95.srcman: $(F95_MANFILES)
+ -cp -p $^ $(srcdir)/doc
+
+f95.srcextra:
+
+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
+
+doc/gfortran.info: $(GFORTRAN_TEXI)
+ if [ x$(BUILD_INFO) = xinfo ]; then \
+ rm -f doc/gfortran.info-*; \
+ $(MAKEINFO) -I$(srcdir)/doc/include -I$(srcdir)/fortran \
+ -o doc/gfortran.info $(srcdir)/fortran/gfortran.texi; \
+ else true; fi
+
+doc/gfortran.dvi: $(GFORTRAN_TEXI)
+ $(TEXI2DVI) -I $(srcdir)/fortran -I $(abs_docdir)/include -o $@ $<
+
+.INTERMEDIATE: gfortran.pod
+
+gfortran.pod: $(GFORTRAN_TEXI)
+ -$(TEXI2POD) < $(srcdir)/fortran/invoke.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-info:: $(DESTDIR)$(infodir)/gfortran.info
+
+f95.install-man: installdirs \
+ $(DESTDIR)$(man1dir)/$(GFORTRAN_INSTALL_NAME)$(man1ext)
+
+$(DESTDIR)$(man1dir)/$(GFORTRAN_INSTALL_NAME)$(man1ext): doc/gfortran.1
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
+
+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)$(man1dir)/$(GFORTRAN_INSTALL_NAME)$(man1ext); \
+ 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 doc/gfortran.info* fortran/gfortran.*aux
+ -rm -f $(docobjdir)/gfortran.1
+
+#
+# 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)
+
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..b6aec5b951d
--- /dev/null
+++ b/gcc/fortran/arith.c
@@ -0,0 +1,2861 @@
+/* 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/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
+ logarithm 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 Maclaurin 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 Maclaurin 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
+ its type and kind. GMP is doing 130 bit arithmetic, so an UNDERFLOW
+ is numerically zero for REAL(4) and REAL(8) types. Reset the value(s)
+ to exactly 0 for UNDERFLOW. 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);
+ if (rc == ARITH_UNDERFLOW)
+ mpf_set_ui (e->value.real, 0);
+ break;
+
+ case BT_COMPLEX:
+ rc = gfc_check_real_range (e->value.complex.r, e->ts.kind);
+ if (rc == ARITH_UNDERFLOW)
+ mpf_set_ui (e->value.complex.r, 0);
+ if (rc == ARITH_OK || rc == ARITH_UNDERFLOW)
+ {
+ rc = gfc_check_real_range (e->value.complex.i, e->ts.kind);
+ if (rc == ARITH_UNDERFLOW)
+ mpf_set_ui (e->value.complex.i, 0);
+ }
+
+ 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_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else 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_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else 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_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else 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_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else 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_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else 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.i, 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_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else 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, 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.r, 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);
+
+ rc = gfc_check_real_range (result->value.real, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.real, 0);
+ }
+ else if (rc != 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);
+
+ rc = gfc_check_real_range (result->value.complex.r, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.complex.r, 0);
+ }
+ else if (rc != 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);
+
+ rc = gfc_check_real_range (result->value.real, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.real, 0);
+ }
+ if (rc != 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);
+
+ rc = gfc_check_real_range (result->value.complex.r, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.complex.r, 0);
+ }
+ else if (rc != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ rc = gfc_check_real_range (result->value.complex.i, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.complex.i, 0);
+ }
+ else if (rc != 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..a7081d84305
--- /dev/null
+++ b/gcc/fortran/array.c
@@ -0,0 +1,1975 @@
+/* Array things
+ 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 "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;
+ int t;
+
+ 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)
+ {
+ t = mpz_cmp (c->n.offset, c1->n.offset);
+ if (t < 0)
+ {
+ pre = c;
+ c = c->next;
+ }
+ else if (t == 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_current_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..9a82d889371
--- /dev/null
+++ b/gcc/fortran/check.c
@@ -0,0 +1,2037 @@
+/* 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
+
+ I.e. in the case of minloc(array,mask), mask will be in the second
+ position of the argument list and we'll have to fix that up. */
+
+try
+gfc_check_minloc_maxloc (gfc_actual_arglist * ap)
+{
+ gfc_expr *a, *m, *d;
+
+ a = ap->expr;
+ if (int_or_real_check (a, 0) == FAILURE
+ || array_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ d = ap->next->expr;
+ m = ap->next->next->expr;
+
+ if (m == NULL && d != NULL && d->ts.type == BT_LOGICAL
+ && ap->next->name[0] == '\0')
+ {
+ m = d;
+ d = NULL;
+
+ ap->next->expr = NULL;
+ ap->next->next->expr = m;
+ }
+
+ if (d != NULL
+ && (scalar_check (d, 1) == FAILURE
+ || type_check (d, 1, BT_INTEGER) == FAILURE))
+ return FAILURE;
+
+ if (m != NULL && type_check (m, 2, BT_LOGICAL) == FAILURE)
+ 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 (size != NULL)
+ gfc_error ("Too many arguments to %s at %L", gfc_current_intrinsic,
+ &put->where);
+
+ 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 (size != NULL || put != NULL)
+ gfc_error ("Too many arguments to %s at %L", gfc_current_intrinsic,
+ &get->where);
+
+ 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;
+}
+
+try
+gfc_check_second_sub (gfc_expr * time)
+{
+
+ if (scalar_check (time, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (time, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(time, 0, 4) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* The arguments of SYSTEM_CLOCK are scalar, integer variables. Note,
+ count, count_rate, and count_max are all optional arguments */
+
+try
+gfc_check_system_clock (gfc_expr * count, gfc_expr * count_rate,
+ gfc_expr * count_max)
+{
+
+ if (count != NULL)
+ {
+ if (scalar_check (count, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (count, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (count, 0) == FAILURE)
+ return FAILURE;
+ }
+
+ if (count_rate != NULL)
+ {
+ if (scalar_check (count_rate, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (count_rate, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (count_rate, 1) == FAILURE)
+ return FAILURE;
+
+ if (count != NULL && same_type_check(count, 0, count_rate, 1) == FAILURE)
+ return FAILURE;
+
+ }
+
+ if (count_max != NULL)
+ {
+ if (scalar_check (count_max, 2) == FAILURE)
+ return FAILURE;
+
+ if (type_check (count_max, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (count_max, 2) == FAILURE)
+ return FAILURE;
+
+ if (count != NULL && same_type_check(count, 0, count_max, 2) == FAILURE)
+ return FAILURE;
+
+ if (count_rate != NULL
+ && same_type_check(count_rate, 1, count_max, 2) == FAILURE)
+ return FAILURE;
+
+ }
+
+ return SUCCESS;
+}
+
+try
+gfc_check_irand (gfc_expr * x)
+{
+ if (scalar_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (x, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(x, 0, 4) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+try
+gfc_check_rand (gfc_expr * x)
+{
+ if (scalar_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (x, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(x, 0, 4) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+try
+gfc_check_srand (gfc_expr * x)
+{
+ if (scalar_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (x, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(x, 0, 4) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+try
+gfc_check_etime (gfc_expr * x)
+{
+ if (array_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (rank_check (x, 0, 1) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (x, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(x, 0, 4) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+try
+gfc_check_etime_sub (gfc_expr * values, gfc_expr * time)
+{
+ if (array_check (values, 0) == FAILURE)
+ return FAILURE;
+
+ if (rank_check (values, 0, 1) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (values, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (values, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(values, 0, 4) == FAILURE)
+ return FAILURE;
+
+ if (scalar_check (time, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (time, 1, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check(time, 1, 4) == 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..ea64f399ff1
--- /dev/null
+++ b/gcc/fortran/data.c
@@ -0,0 +1,541 @@
+/* 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 "gfortran.h"
+#include "assert.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 RVALUE to LVALUE where we assume that LVALUE is a substring
+ reference. We do a little more than that: if LVALUE already has an
+ initialization, we put RVALUE into the existing initialization as
+ per the rules of assignment to a substring. If LVALUE has no
+ initialization yet, we initialize it to all blanks, then filling in
+ the RVALUE. */
+
+static void
+assign_substring_data_value (gfc_expr * lvalue, gfc_expr * rvalue)
+{
+ gfc_symbol *symbol;
+ gfc_expr *expr, *init;
+ gfc_ref *ref;
+ int len, i;
+ int start, end;
+ char *c, *d;
+
+ symbol = lvalue->symtree->n.sym;
+ ref = lvalue->ref;
+ init = symbol->value;
+
+ assert (symbol->ts.type == BT_CHARACTER);
+ assert (symbol->ts.cl->length->expr_type == EXPR_CONSTANT);
+ assert (symbol->ts.cl->length->ts.type == BT_INTEGER);
+ assert (symbol->ts.kind == 1);
+
+ gfc_extract_int (symbol->ts.cl->length, &len);
+
+ if (init == NULL)
+ {
+ /* Setup the expression to hold the constructor. */
+ expr = gfc_get_expr ();
+ expr->expr_type = EXPR_CONSTANT;
+ expr->ts.type = BT_CHARACTER;
+ expr->ts.kind = 1;
+
+ expr->value.character.length = len;
+ expr->value.character.string = gfc_getmem (len);
+ memset (expr->value.character.string, ' ', len);
+
+ symbol->value = expr;
+ }
+ else
+ expr = init;
+
+ /* Now that we have allocated the memory for the string,
+ fill in the initialized places, truncating the
+ intialization string if necessary, i.e.
+ DATA a(1:2) /'123'/
+ doesn't initialize a(3:3). */
+
+ gfc_extract_int (ref->u.ss.start, &start);
+ gfc_extract_int (ref->u.ss.end, &end);
+
+ assert (start >= 1);
+ assert (end <= len);
+
+ len = rvalue->value.character.length;
+ c = rvalue->value.character.string;
+ d = &expr->value.character.string[start - 1];
+
+ for (i = 0; i <= end - start && i < len; i++)
+ d[i] = c[i];
+
+ /* Pad with spaces. I.e.
+ DATA a(1:2) /'a'/
+ intializes a(1:2) to 'a ' per the rules for assignment.
+ If init == NULL we don't need to do this, as we have
+ intialized the whole string to blanks above. */
+
+ if (init != NULL)
+ for (; i <= end - start; i++)
+ d[i] = ' ';
+
+ return;
+}
+
+/* Assign the initial value RVALUE to LVALUE's symbol->value. If the
+ LVALUE already has an initialization, we extend this, otherwise we
+ create a new one. */
+
+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;
+ if (ref != NULL && ref->type == REF_SUBSTRING)
+ {
+ /* No need to go through the for (; ref; ref->next) loop, since
+ a single substring lvalue will only refer to a single
+ substring, and therefore ref->next == NULL. */
+ assert (ref->next == NULL);
+ assign_substring_data_value (lvalue, rvalue);
+ return;
+ }
+
+ symbol = lvalue->symtree->n.sym;
+ init = symbol->value;
+ last_con = NULL;
+ mpz_init_set_si (offset, 0);
+
+ for (; 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: dealt with separately above. */
+
+ 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_internal_error ("TODO: Vector 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..94573ac9df5
--- /dev/null
+++ b/gcc/fortran/decl.c
@@ -0,0 +1,2884 @@
+/* Declaration statement matcher
+ Copyright (C) 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 "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 (attr.in_common
+ && !attr.data
+ && *initp != NULL)
+ {
+ gfc_error ("Initializer not allowed for COMMON variable '%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;
+}
+
+
+/* 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;
+ }
+ }
+
+ /* 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
+ {
+ if (current_ts.type == BT_DERIVED && !initializer)
+ initializer = gfc_default_initializer (&current_ts);
+ 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_current_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 implicit_flag is nonzero, then we don't check for the optional
+ kind specification. Not doing so is needed for matching an IMPLICIT
+ statement correctly. */
+
+static match
+match_type_spec (gfc_typespec * ts, int implicit_flag)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+ int c;
+
+ 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;
+ if (implicit_flag == 0)
+ return match_char_spec (ts);
+ else
+ return MATCH_YES;
+ }
+
+ 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 (implicit_flag == 1)
+ return MATCH_YES;
+
+ if (gfc_current_form == FORM_FREE)
+ {
+ c = gfc_peek_char();
+ if (!gfc_is_whitespace(c) && c != '*' && c != '('
+ && c != ':' && c != ',')
+ return MATCH_NO;
+ }
+
+ 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;
+}
+
+
+/* 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 (void)
+{
+ 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) != SUCCESS)
+ goto bad;
+ }
+
+ return MATCH_YES;
+
+bad:
+ gfc_syntax_error (ST_IMPLICIT);
+
+ gfc_current_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;
+ }
+
+ do
+ {
+ /* First cleanup. */
+ gfc_clear_new_implicit ();
+
+ /* A basic type is mandatory here. */
+ m = match_type_spec (&ts, 1);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ cur_loc = gfc_current_locus;
+ m = match_implicit_range ();
+
+ if (m == MATCH_YES)
+ {
+ /* We may have <TYPE> (<RANGE>). */
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ if ((c == '\n') || (c == ','))
+ {
+ /* Check for CHARACTER with no length parameter. */
+ if (ts.type == BT_CHARACTER && !ts.cl)
+ {
+ ts.kind = gfc_default_character_kind ();
+ ts.cl = gfc_get_charlen ();
+ ts.cl->next = gfc_current_ns->cl_list;
+ gfc_current_ns->cl_list = ts.cl;
+ ts.cl->length = gfc_int_expr (1);
+ }
+
+ /* Record the Successful match. */
+ if (gfc_merge_new_implicit (&ts) != SUCCESS)
+ return MATCH_ERROR;
+ continue;
+ }
+
+ gfc_current_locus = cur_loc;
+ }
+
+ /* Discard the (incorrectly) matched range. */
+ gfc_clear_new_implicit ();
+
+ /* Last chance -- check <TYPE> <SELECTOR> (<RANGE>). */
+ if (ts.type == BT_CHARACTER)
+ m = match_char_spec (&ts);
+ else
+ {
+ m = gfc_match_kind_spec (&ts);
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_old_kind_spec (&ts);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+ }
+ if (m == MATCH_ERROR)
+ goto error;
+
+ m = match_implicit_range ();
+ 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;
+
+ if (gfc_merge_new_implicit (&ts) != SUCCESS)
+ return MATCH_ERROR;
+ }
+ while (c == ',');
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_IMPLICIT);
+
+error:
+ return MATCH_ERROR;
+}
+
+
+/* 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_current_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 = match_type_spec (&current_ts, 0);
+ 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
+ && match_type_spec (ts, 0) == 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_current_locus = old_loc;
+ return m;
+ }
+
+ if (gfc_match ("function% %n", name) != MATCH_YES)
+ {
+ gfc_current_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_current_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;
+}
+
+
+/* Return nonzero if we're currenly compiling a contained procedure. */
+
+static int
+contained_procedure (void)
+{
+ gfc_state_data *s;
+
+ for (s=gfc_state_stack; s; s=s->previous)
+ if ((s->state == COMP_SUBROUTINE || s->state == COMP_FUNCTION)
+ && s->previous != NULL
+ && s->previous->state == COMP_CONTAINS)
+ return 1;
+
+ return 0;
+}
+
+/* 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;
+ int eos_ok;
+ 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";
+ eos_ok = 1;
+ break;
+
+ case COMP_SUBROUTINE:
+ *st = ST_END_SUBROUTINE;
+ target = " subroutine";
+ eos_ok = !contained_procedure ();
+ break;
+
+ case COMP_FUNCTION:
+ *st = ST_END_FUNCTION;
+ target = " function";
+ eos_ok = !contained_procedure ();
+ break;
+
+ case COMP_BLOCK_DATA:
+ *st = ST_END_BLOCK_DATA;
+ target = " block data";
+ eos_ok = 1;
+ break;
+
+ case COMP_MODULE:
+ *st = ST_END_MODULE;
+ target = " module";
+ eos_ok = 1;
+ break;
+
+ case COMP_INTERFACE:
+ *st = ST_END_INTERFACE;
+ target = " interface";
+ eos_ok = 0;
+ break;
+
+ case COMP_DERIVED:
+ *st = ST_END_TYPE;
+ target = " type";
+ eos_ok = 0;
+ break;
+
+ case COMP_IF:
+ *st = ST_ENDIF;
+ target = " if";
+ eos_ok = 0;
+ break;
+
+ case COMP_DO:
+ *st = ST_ENDDO;
+ target = " do";
+ eos_ok = 0;
+ break;
+
+ case COMP_SELECT:
+ *st = ST_END_SELECT;
+ target = " select";
+ eos_ok = 0;
+ break;
+
+ case COMP_FORALL:
+ *st = ST_END_FORALL;
+ target = " forall";
+ eos_ok = 0;
+ break;
+
+ case COMP_WHERE:
+ *st = ST_END_WHERE;
+ target = " where";
+ eos_ok = 0;
+ break;
+
+ default:
+ gfc_error ("Unexpected END statement at %C");
+ goto cleanup;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ if (!eos_ok)
+ {
+ /* We would have required END [something] */
+ 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_current_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)
+{
+ char n[GFC_MAX_SYMBOL_LEN+1];
+ gfc_common_head *c;
+ 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 (" / %n /", &n);
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ c = gfc_get_common (n);
+
+ if (c->use_assoc)
+ {
+ gfc_error("COMMON block '%s' at %C is already USE associated", n);
+ return MATCH_ERROR;
+ }
+
+ c->saved = 1;
+
+ 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..8d23c908ed0
--- /dev/null
+++ b/gcc/fortran/dump-parse-tree.c
@@ -0,0 +1,1500 @@
+/* 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++)
+ {
+ /* There are two types of array sections: either the
+ elements are identified by an integer array ('vector'),
+ or by an index range. In the former case we only have to
+ print the start expression which contains the vector, in
+ the latter case we have to print any of lower and upper
+ bound and the stride, if they're present. */
+
+ if (ar->start[i] != NULL)
+ gfc_show_expr (ar->start[i]);
+
+ if (ar->dimen_type[i] == DIMEN_RANGE)
+ {
+ 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->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->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;
+
+ 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->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);
+}
+
+
+/* Function to display a common block. */
+
+static void
+show_common (gfc_symtree * st)
+{
+ gfc_symbol *s;
+
+ show_indent ();
+ gfc_status ("common: /%s/ ", st->name);
+
+ s = st->n.common->head;
+ while (s)
+ {
+ gfc_status ("%s", s->name);
+ s = s->common_next;
+ if (s)
+ gfc_status (", ");
+ }
+ gfc_status_char ('\n');
+}
+
+/* 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 and equivalence chain. */
+
+static void
+gfc_show_equiv (gfc_equiv *eq)
+{
+ show_indent ();
+ gfc_status ("Equivalence: ");
+ while (eq)
+ {
+ gfc_show_expr (eq->expr);
+ eq = eq->eq;
+ if (eq)
+ gfc_status (", ");
+ }
+}
+
+
+/* Show a freakin' whole namespace. */
+
+void
+gfc_show_namespace (gfc_namespace * ns)
+{
+ gfc_interface *intr;
+ gfc_namespace *save;
+ gfc_intrinsic_op op;
+ gfc_equiv *eq;
+ 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->common_root, show_common);
+
+ gfc_traverse_symtree (ns->sym_root, 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);
+ }
+ }
+
+ for (eq = ns->equiv; eq; eq = eq->next)
+ gfc_show_equiv (eq);
+
+ 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..aab196fdfdb
--- /dev/null
+++ b/gcc/fortran/error.c
@@ -0,0 +1,757 @@
+/* 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 * loc)
+{
+ gfc_linebuf *lb;
+ 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. */
+
+ lb = loc->lb;
+ f = lb->file;
+ error_printf ("In file %s:%d\n", f->filename, lb->linenum);
+
+ for (;;)
+ {
+ i = f->inclusion_line;
+
+ f = f->included_by;
+ if (f == NULL) break;
+
+ error_printf (" Included at %s:%d\n", f->filename, i);
+ }
+
+ /* Show the line itself, taking care not to print more than what can
+ show up on the terminal. Tabs are converted to spaces. */
+
+ p = lb->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->lb->line;
+ c2 = 0;
+ if (l2 == NULL)
+ goto separate;
+
+ c2 = l2->nextc - l2->lb->line;
+
+ if (c1 < c2)
+ m = c2 - c1;
+ else
+ m = c1 - c2;
+
+
+ if (l1->lb != l2->lb || 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..e9ed27040ee
--- /dev/null
+++ b/gcc/fortran/expr.c
@@ -0,0 +1,1916 @@
+/* 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:
+ if ((*check_function) (e->op2) == FAILURE)
+ return FAILURE;
+
+ if (!(et0 (e->op1) == BT_CHARACTER && et0 (e->op2) == BT_CHARACTER)
+ && !(numeric_type (et0 (e->op1)) && numeric_type (et0 (e->op2))))
+ {
+ gfc_error ("Numeric or CHARACTER operands are required in "
+ "expression at %L", &e->where);
+ return FAILURE;
+ }
+ break;
+
+ 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
+ && 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;
+
+ 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)
+{
+ for (; a; a = a->next)
+ {
+ if (check_restricted (a->expr) == FAILURE)
+ 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);
+}
+
+
+/* Check to see that a function reference to an intrinsic is a
+ restricted expression. */
+
+static try
+restricted_intrinsic (gfc_expr * e)
+{
+ /* TODO: Check constraints on inquiry functions. 7.1.6.2 (7). */
+ if (check_inquiry (e) == SUCCESS)
+ return SUCCESS;
+
+ return restricted_args (e->value.function.actual);
+}
+
+
+/* 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;
+}
+
+
+/* Get an expression for a default initializer. */
+
+gfc_expr *
+gfc_default_initializer (gfc_typespec *ts)
+{
+ gfc_constructor *tail;
+ gfc_expr *init;
+ gfc_component *c;
+
+ init = NULL;
+
+ /* See if we have a default initializer. */
+ for (c = ts->derived->components; c; c = c->next)
+ {
+ if (c->initializer && init == NULL)
+ init = gfc_get_expr ();
+ }
+
+ if (init == NULL)
+ return NULL;
+
+ /* Build the constructor. */
+ init->expr_type = EXPR_STRUCTURE;
+ init->ts = *ts;
+ init->where = ts->derived->declared_at;
+ tail = NULL;
+ for (c = 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;
+}
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
new file mode 100644
index 00000000000..43eb87d1be3
--- /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_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_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)));
+ }
+
+ /* 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;
+
+ tmp = tree_cons (NULL_TREE, float_type_node, void_list_node);
+ 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, void_list_node);
+ 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);
+
+ /* These are used to implement the ** operator. */
+ gfc_define_builtin ("__builtin_pow", mfunc_double[0],
+ BUILT_IN_POW, "pow", true);
+ gfc_define_builtin ("__builtin_powf", mfunc_float[0],
+ BUILT_IN_POWF, "powf", true);
+
+ /* Other builtin functions we use. */
+
+ tmp = tree_cons (NULL_TREE, long_integer_type_node, void_list_node);
+ 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, void_list_node);
+ 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, void_list_node);
+ 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, void_list_node);
+ 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, void_list_node);
+ 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, void_list_node);
+ 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, void_list_node);
+ 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, void_list_node);
+ tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
+ 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, void_list_node);
+ gfc_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
+ "stack_save", false);
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, void_list_node);
+ 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..54508dc590e
--- /dev/null
+++ b/gcc/fortran/gfortran.h
@@ -0,0 +1,1699 @@
+/* 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_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
+#define PREFIX_LEN 10
+
+/* 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_COMMAND_ARGUMENT_COUNT,
+ 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_ETIME,
+ GFC_ISYM_EXP,
+ GFC_ISYM_EXPONENT,
+ GFC_ISYM_FLOOR,
+ GFC_ISYM_FRACTION,
+ GFC_ISYM_IACHAR,
+ GFC_ISYM_IAND,
+ GFC_ISYM_IARGC,
+ 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_IRAND,
+ 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_RAND,
+ GFC_ISYM_REAL,
+ GFC_ISYM_REPEAT,
+ GFC_ISYM_RESHAPE,
+ GFC_ISYM_RRSPACING,
+ GFC_ISYM_SCALE,
+ GFC_ISYM_SCAN,
+ GFC_ISYM_SECOND,
+ 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, 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;
+ 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;
+
+
+/* The following three structures are used to identify a location in
+ the sources.
+
+ gfc_file is used to maintain a tree of the source files and how
+ they include each other
+
+ gfc_linebuf holds a single line of source code and information
+ which file it resides in
+
+ locus point to the sourceline and the character in the source
+ line.
+*/
+
+typedef struct gfc_file
+{
+ struct gfc_file *included_by, *next, *up;
+ int inclusion_line, line;
+ char *filename;
+} gfc_file;
+
+typedef struct gfc_linebuf
+{
+ int linenum;
+ struct gfc_file *file;
+ struct gfc_linebuf *next;
+
+ char line[];
+} gfc_linebuf;
+
+typedef struct
+{
+ char *nextc;
+ gfc_linebuf *lb;
+} locus;
+
+
+#include <limits.h>
+#ifndef PATH_MAX
+# include <sys/param.h>
+# define PATH_MAX MAXPATHLEN
+#endif
+
+
+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;
+
+ /* This is set to the type of an eventual omitted optional
+ argument. This is used to determine if a hidden string length
+ argument has to be added to a function call. */
+ bt missing_arg_type;
+
+ 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 */
+
+ struct gfc_symbol *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;
+ /* Nonzero if all equivalences associated with this symbol have been
+ processed. */
+ unsigned equiv_built:1;
+ int refs;
+ struct gfc_namespace *ns; /* namespace containing this symbol */
+
+ tree backend_decl;
+
+}
+gfc_symbol;
+
+
+/* This structure is used to keep track of symbols in common blocks. */
+
+typedef struct
+{
+ locus where;
+ int use_assoc, saved;
+ gfc_symbol *head;
+}
+gfc_common_head;
+
+#define gfc_get_common_head() gfc_getmem(sizeof(gfc_common_head))
+
+
+
+/* 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;
+ gfc_common_head *common;
+ }
+ n;
+
+}
+gfc_symtree;
+
+
+typedef struct gfc_namespace
+{
+ /* Roots of the red/black symbol trees */
+ gfc_symtree *sym_root, *uop_root, *common_root;
+
+ 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_common_head 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;
+
+/* Global symbols are symbols of global scope. Currently we only use
+ this to detect collisions already when parsing.
+ TODO: Extend to verify procedure calls. */
+
+typedef struct gfc_gsymbol
+{
+ BBT_HEADER(gfc_gsymbol);
+
+ char name[GFC_MAX_SYMBOL_LEN+1];
+ enum { GSYM_UNKNOWN=1, GSYM_PROGRAM, GSYM_FUNCTION, GSYM_SUBROUTINE,
+ GSYM_MODULE, GSYM_COMMON, GSYM_BLOCK_DATA } type;
+
+ int defined, used;
+ locus where;
+}
+gfc_gsymbol;
+
+extern gfc_gsymbol *gfc_gsym_root;
+
+/* 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 (*f3ml)(gfc_actual_arglist *);
+ 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_underflow;
+ 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 *);
+
+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_source_form gfc_current_form;
+extern char *gfc_source_file;
+extern locus gfc_current_locus;
+
+/* 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);
+try gfc_merge_new_implicit (gfc_typespec *);
+void gfc_set_implicit_none (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_data (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_symtree *, 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);
+
+gfc_gsymbol *gfc_get_gsymbol (char *);
+gfc_gsymbol *gfc_find_gsymbol (gfc_gsymbol *, char *);
+
+/* 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 *);
+
+gfc_expr *gfc_default_initializer (gfc_typespec *);
+
+/* 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..c1a0fe1c1c7
--- /dev/null
+++ b/gcc/fortran/gfortran.texi
@@ -0,0 +1,739 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gfortran.info
+@set last-update 13 May 2004
+@set copyrights-gfortran 1999-2004
+
+@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-GCC}
+@page
+@vskip 0pt plus 1filll
+For the @value{version-GCC} 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.
+
+@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}.
+* 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 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..abff6a1d715
--- /dev/null
+++ b/gcc/fortran/interface.c
@@ -0,0 +1,1865 @@
+/* Deal with interfaces.
+ 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. */
+
+
+/* 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 (actual->expr_type != EXPR_NULL
+ && !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 (a->expr->expr_type != EXPR_NULL
+ && 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];
+
+ /* Note the types of omitted optional arguments. */
+ for (a = actual, f = formal; a; a = a->next, f = f->next)
+ if (a->expr == NULL && a->label == NULL)
+ a->missing_arg_type = f->sym->ts.type;
+
+ 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..258843bad05
--- /dev/null
+++ b/gcc/fortran/intrinsic.c
@@ -0,0 +1,2726 @@
+/* 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);
+}
+
+
+/* Add the name of an intrinsic subroutine with two arguments to the list
+ of intrinsic names. */
+
+static void add_sym_2s (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_code *),
+ 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.s1 = 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);
+}
+
+/* MINLOC and MAXLOC get special treatment because their argument
+ might have to be reordered. */
+
+static void add_sym_3ml (const char *name, int elemental,
+ int actual_ok, bt type, int kind,
+ try (*check)(gfc_actual_arglist *),
+ 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.f3ml = 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);
+}
+
+/* Add the name of an intrinsic subroutine with three arguments to the list
+ of intrinsic names. */
+
+static void add_sym_3s (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_code *),
+ 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.s1 = 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);
+
+ /* G77 compatibility */
+ add_sym_1 ("etime", 0, 1, BT_REAL, 4,
+ gfc_check_etime, NULL, NULL,
+ x, BT_REAL, 4, 0);
+
+ make_alias ("dtime");
+
+ make_generic ("etime", GFC_ISYM_ETIME);
+
+
+ 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 */
+ make_generic ("iargc", GFC_ISYM_IARGC);
+
+ add_sym_0 ("command_argument_count", 1, 1, BT_INTEGER, di, NULL, NULL, NULL);
+ make_generic ("command_argument_count", GFC_ISYM_COMMAND_ARGUMENT_COUNT);
+
+ 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);
+
+ /* The following function is for G77 compatibility. */
+ add_sym_1 ("irand", 0, 1, BT_INTEGER, 4,
+ gfc_check_irand, NULL, NULL,
+ i, BT_INTEGER, 4, 0);
+
+ make_generic ("irand", GFC_ISYM_IRAND);
+
+ 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_3ml ("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_3ml ("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);
+
+ /* The following function is for G77 compatibility. */
+ add_sym_1 ("rand", 0, 1, BT_REAL, 4,
+ gfc_check_rand, NULL, NULL,
+ i, BT_INTEGER, 4, 0);
+
+ make_generic ("rand", GFC_ISYM_RAND);
+
+ 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);
+
+ /* Added for G77 compatibility garbage. */
+ add_sym_0 ("second", 0, 1, BT_REAL, 4, NULL, NULL, NULL);
+
+ make_generic ("second", GFC_ISYM_SECOND);
+
+ 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",
+ *com = "command", *length = "length", *st = "status",
+ *val = "value", *num = "number";
+
+ 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);
+
+ /* More G77 compatibility garbage. */
+ add_sym_1s ("second", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_second_sub, NULL, gfc_resolve_second_sub,
+ 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);
+
+ /* More G77 compatibility garbage. */
+ add_sym_2s ("etime", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_etime_sub, NULL, gfc_resolve_etime_sub,
+ vl, BT_REAL, 4, 0, tm, BT_REAL, 4, 0);
+
+ add_sym_2s ("dtime", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_etime_sub, NULL, gfc_resolve_etime_sub,
+ vl, BT_REAL, 4, 0, tm, BT_REAL, 4, 0);
+
+ add_sym_2 ("getarg", 0, 1, BT_UNKNOWN, 0,
+ NULL, NULL, gfc_resolve_getarg,
+ c, BT_INTEGER, di, 0, vl, BT_CHARACTER, dc, 0);
+
+ /* F2003 commandline routines. */
+
+ add_sym_3s ("get_command", 0, 1, BT_UNKNOWN, 0,
+ NULL, NULL, gfc_resolve_get_command,
+ com, BT_CHARACTER, dc, 1,
+ length, BT_INTEGER, di, 1,
+ st, BT_INTEGER, di, 1);
+
+ add_sym_4 ("get_command_argument", 0, 1, BT_UNKNOWN, 0,
+ NULL, NULL, gfc_resolve_get_command_argument,
+ num, BT_INTEGER, di, 0,
+ val, BT_CHARACTER, dc, 1,
+ length, BT_INTEGER, di, 1,
+ st, BT_INTEGER, di, 1);
+
+ /* 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_3s ("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);
+
+ /* More G77 compatibility garbage. */
+ add_sym_1s ("srand", 0, 1, BT_UNKNOWN, di,
+ gfc_check_srand, NULL, gfc_resolve_srand,
+ c, BT_INTEGER, 4, 0);
+
+ add_sym_3s ("system_clock", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_system_clock, NULL, gfc_resolve_system_clock,
+ 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)
+ {
+ if (f->actual == NULL)
+ {
+ a = gfc_get_actual_arglist ();
+ a->missing_arg_type = f->ts.type;
+ }
+ else
+ a = 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.f3ml != gfc_check_minloc_maxloc)
+ {
+ 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);
+ }
+ else
+ /* This is special because we might have to reorder the argument
+ list. */
+ t = gfc_check_minloc_maxloc (*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..2d759cf5a9d
--- /dev/null
+++ b/gcc/fortran/intrinsic.h
@@ -0,0 +1,329 @@
+/* Header file for intrinsics check, resolve and simplify function
+ prototypes.
+ 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. */
+
+/* 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_etime (gfc_expr *);
+try gfc_check_etime_sub (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_irand (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_actual_arglist *);
+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_rand (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_second_sub (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_srand (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_system_clock (gfc_expr *, gfc_expr *, 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_etime_sub (gfc_code *);
+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_second_sub (gfc_code *);
+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_srand (gfc_code *);
+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_system_clock(gfc_code *);
+void gfc_resolve_random_number (gfc_code *);
+void gfc_resolve_getarg (gfc_code *);
+void gfc_resolve_get_command (gfc_code *);
+void gfc_resolve_get_command_argument (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..08ce4624256
--- /dev/null
+++ b/gcc/fortran/invoke.texi
@@ -0,0 +1,662 @@
+@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 -Wunderflow -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
+
+@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 -fimplicit-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 currently 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
+will trigger the warning 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 ``suspicious'' code constructs are encountered.
+While technically 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 -Wunderflow
+@cindex options, -Wunderflow
+@item -Wunderflow
+@cindex UNDERFLOW
+Produce a warning when numerical constant expressions are
+encountered, which yield an UNDERFLOW during compilation.
+
+
+@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 useful 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 modules.
+It is also added to the list of directories to searched 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. checking
+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 likely 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..631197258a0
--- /dev/null
+++ b/gcc/fortran/io.c
@@ -0,0 +1,2459 @@
+/* Deal with I/O statements & related stuff.
+ 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 <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, 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 requires a prior number. */
+ error = "P descriptor requires leading scale factor";
+ goto syntax;
+
+ case FMT_X:
+ /* X requires a prior number if we're being pedantic. */
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: X descriptor "
+ "requires leading space count at %C")
+ == FAILURE)
+ return FAILURE;
+ goto between_desc;
+
+ case FMT_SIGN:
+ case FMT_BLANK:
+ goto between_desc;
+
+ case FMT_CHAR:
+ goto extension_optional_comma;
+
+ 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;
+
+extension_optional_comma:
+ /* As a GNU extension, permit a missing comma after a string literal. */
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_COMMA:
+ break;
+
+ 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:
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: Missing comma at %C")
+ == FAILURE)
+ return FAILURE;
+ 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_current_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_current_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_current_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, c;
+ 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;
+
+ if (gfc_current_form == FORM_FREE)
+ {
+ c = gfc_peek_char();
+ if (c != ' ' && c != '*' && c != '\'' && c != '"')
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+ }
+
+ 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_current_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;
+ new_st.ext.inquire = 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);
+ RESOLVE_TAG (&tag_iolength, inquire->iolength);
+
+ if (gfc_reference_st_label (inquire->err, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
new file mode 100644
index 00000000000..f7e7f71427e
--- /dev/null
+++ b/gcc/fortran/iresolve.c
@@ -0,0 +1,1489 @@
+/* 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;
+ if (c->ext.actual->expr->rank == 0)
+ name = gfc_get_string (PREFIX("random_r%d"), kind);
+ else
+ name = gfc_get_string (PREFIX("arandom_r%d"), kind);
+
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+
+}
+
+
+/* G77 compatibility subroutines etime() and dtime(). */
+
+void
+gfc_resolve_etime_sub (gfc_code * c)
+{
+ const char *name;
+
+ name = gfc_get_string (PREFIX("etime_sub"));
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+/* G77 compatibility subroutine second(). */
+
+void
+gfc_resolve_second_sub (gfc_code * c)
+{
+ const char *name;
+
+ name = gfc_get_string (PREFIX("second_sub"));
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+/* G77 compatibility function srand(). */
+
+void
+gfc_resolve_srand (gfc_code * c)
+{
+ const char *name;
+ name = gfc_get_string (PREFIX("srand"));
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+/* Resolve the getarg intrinsic subroutine. */
+
+void
+gfc_resolve_getarg (gfc_code * c)
+{
+ const char *name;
+ int kind;
+
+ kind = gfc_default_integer_kind ();
+ name = gfc_get_string (PREFIX("getarg_i%d"), kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+/* Resolve the get_command intrinsic subroutine. */
+
+void
+gfc_resolve_get_command (gfc_code * c)
+{
+ const char *name;
+ int kind;
+
+ kind = gfc_default_integer_kind ();
+ name = gfc_get_string (PREFIX("get_command_i%d"), kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+/* Resolve the get_command_argument intrinsic subroutine. */
+
+void
+gfc_resolve_get_command_argument (gfc_code * c)
+{
+ const char *name;
+ int kind;
+
+ kind = gfc_default_integer_kind ();
+ name = gfc_get_string (PREFIX("get_command_argument_i%d"), kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+/* Determine if the arguments to SYSTEM_CLOCK are INTEGER(4) or INTEGER(8) */
+
+void
+gfc_resolve_system_clock (gfc_code * c)
+{
+ const char *name;
+ int kind;
+
+ if (c->ext.actual->expr != NULL)
+ kind = c->ext.actual->expr->ts.kind;
+ else if (c->ext.actual->next->expr != NULL)
+ kind = c->ext.actual->next->expr->ts.kind;
+ else if (c->ext.actual->next->next->expr != NULL)
+ kind = c->ext.actual->next->next->expr->ts.kind;
+ else
+ kind = gfc_default_integer_kind ();
+
+ name = gfc_get_string (PREFIX("system_clock_%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..b18483f5c23
--- /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, 0, 0},
+{".fpp", "@f77-cpp-input", 0, 0, 0},
+{".FPP", "@f77-cpp-input", 0, 0, 0},
+{"@f77-cpp-input",
+ "cc1 -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, 0, 0},
+{".F90", "@f95-cpp-input", 0, 0, 0},
+{".F95", "@f95-cpp-input", 0, 0, 0},
+{"@f95-cpp-input",
+ "cc1 -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, 0, 0},
+{".f90", "@f95", 0, 0, 0},
+{".f95", "@f95", 0, 0, 0},
+{"@f95", "%{!E:f951 %i %(cc1_options) %{J*} %{I*}\
+ %{!fsyntax-only:%(invoke_as)}}", 0, 0, 0},
+{".f", "@f77", 0, 0, 0},
+{".for", "@f77", 0, 0, 0},
+{".FOR", "@f77", 0, 0, 0},
+{"@f77", "%{!E:f951 %i %{!ffree-form:-ffixed-form} %(cc1_options) %{J*} %{I*}\
+ %{!fsyntax-only:%(invoke_as)}}", 0, 0, 0},
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
new file mode 100644
index 00000000000..ff670d66f2b
--- /dev/null
+++ b/gcc/fortran/lang.opt
@@ -0,0 +1,156 @@
+; 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
+
+Wunderflow
+F95
+Warn about underflow of numerical constant expressions
+
+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..f8bf2b334d1
--- /dev/null
+++ b/gcc/fortran/match.c
@@ -0,0 +1,3426 @@
+/* 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_form == FORM_FIXED)
+ return MATCH_YES;
+
+ old_loc = gfc_current_locus;
+
+ c = gfc_next_char ();
+ if (!gfc_is_whitespace (c))
+ {
+ gfc_current_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_current_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_current_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_current_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_current_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_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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;
+}
+
+
+/* Given a name, return a pointer to the common head structure,
+ creating it if it does not exist.
+ TODO: Add to global symbol tree. */
+
+gfc_common_head *
+gfc_get_common (char *name)
+{
+ gfc_symtree *st;
+
+ st = gfc_find_symtree (gfc_current_ns->common_root, name);
+ if (st == NULL)
+ st = gfc_new_symtree (&gfc_current_ns->common_root, name);
+
+ if (st->n.common == NULL)
+ {
+ st->n.common = gfc_get_common_head ();
+ st->n.common->where = gfc_current_locus;
+ }
+
+ return st->n.common;
+}
+
+
+/* Match a common block name. */
+
+static match
+match_common_name (char *name)
+{
+ match m;
+
+ if (gfc_match_char ('/') == MATCH_NO)
+ {
+ name[0] = '\0';
+ return MATCH_YES;
+ }
+
+ if (gfc_match_char ('/') == MATCH_YES)
+ {
+ name[0] = '\0';
+ return MATCH_YES;
+ }
+
+ m = gfc_match_name (name);
+
+ 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, **head, *tail, *old_blank_common;
+ char name[GFC_MAX_SYMBOL_LEN+1];
+ gfc_common_head *t;
+ gfc_array_spec *as;
+ match m;
+
+ old_blank_common = gfc_current_ns->blank_common.head;
+ if (old_blank_common)
+ {
+ while (old_blank_common->common_next)
+ old_blank_common = old_blank_common->common_next;
+ }
+
+ as = NULL;
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto syntax;
+
+ for (;;)
+ {
+ m = match_common_name (name);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (name[0] == '\0')
+ {
+ t = &gfc_current_ns->blank_common;
+ if (t->head == NULL)
+ t->where = gfc_current_locus;
+ head = &t->head;
+ }
+ else
+ {
+ t = gfc_get_common (name);
+ head = &t->head;
+
+ if (t->use_assoc)
+ {
+ gfc_error ("COMMON block '%s' at %C has already "
+ "been USE-associated");
+ goto cleanup;
+ }
+ }
+
+ if (*head == NULL)
+ tail = NULL;
+ else
+ {
+ tail = *head;
+ while (tail->common_next)
+ tail = tail->common_next;
+ }
+
+ /* Grab the list of symbols. */
+ if (gfc_match_eos () == MATCH_YES)
+ goto done;
+
+ 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;
+
+ if (sym->value != NULL
+ && (name[0] == '\0' || !sym->attr.data))
+ {
+ if (name[0] == '\0')
+ gfc_error ("Previously initialized symbol '%s' in "
+ "blank COMMON block at %C", sym->name);
+ else
+ gfc_error ("Previously initialized symbol '%s' in "
+ "COMMON block '%s' at %C", sym->name, 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.head = 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;
+ gfc_symbol *sym;
+
+ 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;
+
+ sym = new->expr->symtree->n.sym;
+
+ if(sym->value != NULL)
+ {
+ gfc_error ("Variable '%s' at %C already has an initialization",
+ sym->name);
+ return MATCH_ERROR;
+ }
+
+#if 0 // TODO: Find out where to move this message
+ if (sym->attr.in_common)
+ /* See if sym is in the blank common block. */
+ for (t = &sym->ns->blank_common; t; t = t->common_next)
+ if (sym == t->head)
+ {
+ gfc_error ("DATA statement at %C may not initialize variable "
+ "'%s' from blank COMMON", sym->name);
+ return MATCH_ERROR;
+ }
+#endif
+
+ if (gfc_add_data (&sym->attr, &new->expr->where) == FAILURE)
+ return MATCH_ERROR;
+
+ 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 && sym->attr.flavor != FL_DERIVED))
+ {
+ gfc_error ("Symbol '%s' must be a PARAMETER in DATA statement at %C",
+ name);
+ return MATCH_ERROR;
+ }
+ else if (sym->attr.flavor == FL_DERIVED)
+ return gfc_match_structure_constructor (sym, result);
+
+ *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_init_expr (&c->high);
+ if (m == MATCH_NO)
+ goto need_expr;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
+ else
+ {
+ m = gfc_match_init_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_init_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 initialization 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_current_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..4b8f87232ec
--- /dev/null
+++ b/gcc/fortran/match.h
@@ -0,0 +1,169 @@
+/* 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_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 *);
+
+/* Other functions. */
+
+gfc_common_head *gfc_get_common (char *);
+
+/* 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_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);
+
+match gfc_match_implicit_none (void);
+match gfc_match_implicit (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_structure_constructor (gfc_symbol *, gfc_expr **);
+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..1035e8888c3
--- /dev/null
+++ b/gcc/fortran/matchexp.c
@@ -0,0 +1,881 @@
+/* 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_current_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_current_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_current_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;
+}
+
+
+/* As a GNU extension we support an expanded level-2 expression syntax.
+ Via this extension we support (arbitrary) nesting of unary plus and
+ minus operations following unary and binary operators, such as **.
+ The grammar of section 7.1.1.3 is effectively rewitten as:
+
+ R704 mult-operand is level-1-expr [ power-op ext-mult-operand ]
+ R704' ext-mult-operand is add-op ext-mult-operand
+ or mult-operand
+ R705 add-operand is add-operand mult-op ext-mult-operand
+ or mult-operand
+ R705' ext-add-operand is add-op ext-add-operand
+ or add-operand
+ R706 level-2-expr is [ level-2-expr ] add-op ext-add-operand
+ or add-operand
+ */
+
+static match match_ext_mult_operand (gfc_expr ** result);
+static match match_ext_add_operand (gfc_expr ** result);
+
+
+static int
+match_add_op (void)
+{
+
+ if (next_operator (INTRINSIC_MINUS))
+ return -1;
+ if (next_operator (INTRINSIC_PLUS))
+ return 1;
+ return 0;
+}
+
+
+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_ext_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_ext_mult_operand (gfc_expr ** result)
+{
+ gfc_expr *all, *e;
+ locus where;
+ match m;
+ int i;
+
+ where = gfc_current_locus;
+ i = match_add_op ();
+
+ if (i == 0)
+ return match_mult_operand (result);
+
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: Unary operator following"
+ " arithmetic operator (use parentheses) at %C")
+ == FAILURE)
+ return MATCH_ERROR;
+
+ m = match_ext_mult_operand (&e);
+ if (m != MATCH_YES)
+ return m;
+
+ 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;
+ *result = all;
+ 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_ext_mult_operand (&e);
+ if (m == MATCH_NO)
+ {
+ gfc_current_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 match
+match_ext_add_operand (gfc_expr ** result)
+{
+ gfc_expr *all, *e;
+ locus where;
+ match m;
+ int i;
+
+ where = gfc_current_locus;
+ i = match_add_op ();
+
+ if (i == 0)
+ return match_add_operand (result);
+
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: Unary operator following"
+ " arithmetic operator (use parentheses) at %C")
+ == FAILURE)
+ return MATCH_ERROR;
+
+ m = match_ext_add_operand (&e);
+ if (m != MATCH_YES)
+ return m;
+
+ 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;
+ *result = all;
+ return MATCH_YES;
+}
+
+
+/* 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 ();
+
+ if (i != 0)
+ {
+ m = match_ext_add_operand (&e);
+ if (m == MATCH_NO)
+ {
+ gfc_error (expression_syntax);
+ m = MATCH_ERROR;
+ }
+ }
+ else
+ m = match_add_operand (&e);
+
+ 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_ext_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_current_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..7f720ba9770
--- /dev/null
+++ b/gcc/fortran/module.c
@@ -0,0 +1,3525 @@
+/* Handle modules, which amounts to loading and saving symbols and
+ their attendant structures.
+ 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. */
+
+/* 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> ... )
+ ...
+ )
+ ( ( <common name> <symbol> <saved flag>)
+ ...
+ )
+ ( <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_RESULT,
+ AB_ENTRY, AB_DATA, AB_IN_NAMELIST, AB_IN_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 ("RESULT", AB_RESULT),
+ minit ("ENTRY", AB_ENTRY),
+ minit ("DATA", AB_DATA),
+ minit ("IN_NAMELIST", AB_IN_NAMELIST),
+ minit ("IN_COMMON", AB_IN_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->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->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_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_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);
+
+ /* Fix negative numbers. */
+ if (atom_string[2] == '-')
+ {
+ atom_string[0] = '-';
+ atom_string[1] = '0';
+ atom_string[2] = '.';
+ }
+
+ 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_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_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 ();
+}
+
+
+/* Load common blocks. */
+
+static void
+load_commons(void)
+{
+ char name[GFC_MAX_SYMBOL_LEN+1];
+ gfc_common_head *p;
+
+ mio_lparen ();
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ mio_lparen ();
+ mio_internal_string (name);
+
+ p = gfc_get_common (name);
+
+ mio_symbol_ref (&p->head);
+ mio_integer (&p->saved);
+ p->use_assoc = 1;
+
+ mio_rparen();
+ }
+
+ 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 ();
+ 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 ();
+
+ load_commons ();
+
+ /* 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 common block to the module */
+
+static void
+write_common (gfc_symtree *st)
+{
+ gfc_common_head *p;
+
+ if (st == NULL)
+ return;
+
+ write_common(st->left);
+ write_common(st->right);
+
+ mio_lparen();
+ mio_internal_string(st->name);
+
+ p = st->n.common;
+ mio_symbol_ref(&p->head);
+ mio_integer(&p->saved);
+
+ mio_rparen();
+}
+
+
+/* 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);
+
+
+ if (sym->attr.flavor == FL_VARIABLE && sym->ts.type == BT_UNKNOWN)
+ /* TODO: this is a workaround for some of the problems in PR15481,
+ and fixes the dependent bug PR13372. In an ideal frontend, this
+ should never happen. */
+ return;
+
+ 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 (sym->attr.flavor == FL_VARIABLE && sym->ts.type == BT_UNKNOWN)
+ /* TODO: this is a workaround for some of the problems in PR15481,
+ and fixes the dependent bug PR13372. In an ideal frontend, this
+ should never happen. */
+ 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');
+
+ mio_lparen ();
+ write_common (gfc_current_ns->common_root);
+ 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->sym_root, 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;
+ 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));
+
+ now = time (NULL);
+ p = ctime (&now);
+
+ *strchr (p, '\n') = '\0';
+
+ fprintf (module_fp, "GFORTRAN module created from %s on %s\n",
+ gfc_source_file, 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..b0f9a76e5f2
--- /dev/null
+++ b/gcc/fortran/options.c
@@ -0,0 +1,327 @@
+/* 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_underflow = 1;
+ 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_underflow = 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) + 2);
+ 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_Wunderflow:
+ gfc_option.warn_underflow = 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..15a53ea3e45
--- /dev/null
+++ b/gcc/fortran/parse.c
@@ -0,0 +1,2615 @@
+/* Main parser.
+ 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 <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_current_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_current_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_current_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_current_locus = old_locus;
+
+ if (gfc_match_where (&st) == MATCH_YES)
+ return st;
+ gfc_undo_symbols ();
+ gfc_current_locus = old_locus;
+
+ if (gfc_match_forall (&st) == MATCH_YES)
+ return st;
+ gfc_undo_symbols ();
+ gfc_current_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_current_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_end ())
+ {
+ st = ST_NONE;
+ break;
+ }
+
+ st =
+ (gfc_current_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:
+ 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_source_file);
+
+ /* 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;
+}
+
+
+/* Come here to complain about a global symbol already in use as
+ something else. */
+
+static void
+global_used (gfc_gsymbol *sym, locus *where)
+{
+ const char *name;
+
+ if (where == NULL)
+ where = &gfc_current_locus;
+
+ switch(sym->type)
+ {
+ case GSYM_PROGRAM:
+ name = "PROGRAM";
+ break;
+ case GSYM_FUNCTION:
+ name = "FUNCTION";
+ break;
+ case GSYM_SUBROUTINE:
+ name = "SUBROUTINE";
+ break;
+ case GSYM_COMMON:
+ name = "COMMON";
+ break;
+ case GSYM_BLOCK_DATA:
+ name = "BLOCK DATA";
+ break;
+ case GSYM_MODULE:
+ name = "MODULE";
+ break;
+ default:
+ gfc_internal_error ("gfc_gsymbol_type(): Bad type");
+ name = NULL;
+ }
+
+ gfc_error("Global name '%s' at %L is already being used as a %s at %L",
+ gfc_new_block->name, where, name, &sym->where);
+}
+
+
+/* Parse a block data program unit. */
+
+static void
+parse_block_data (void)
+{
+ gfc_statement st;
+ static locus blank_locus;
+ static int blank_block=0;
+ gfc_gsymbol *s;
+
+ if (gfc_new_block == NULL)
+ {
+ if (blank_block)
+ gfc_error ("Blank BLOCK DATA at %C conflicts with "
+ "prior BLOCK DATA at %L", &blank_locus);
+ else
+ {
+ blank_block = 1;
+ blank_locus = gfc_current_locus;
+ }
+ }
+ else
+ {
+ s = gfc_get_gsymbol (gfc_new_block->name);
+ if (s->type != GSYM_UNKNOWN)
+ global_used(s, NULL);
+ else
+ {
+ s->type = GSYM_BLOCK_DATA;
+ s->where = gfc_current_locus;
+ }
+ }
+
+ 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;
+ gfc_gsymbol *s;
+
+ s = gfc_get_gsymbol (gfc_new_block->name);
+ if (s->type != GSYM_UNKNOWN)
+ global_used(s, NULL);
+ else
+ {
+ s->type = GSYM_MODULE;
+ s->where = gfc_current_locus;
+ }
+
+ 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;
+ }
+}
+
+
+/* Add a procedure name to the global symbol table. */
+
+static void
+add_global_procedure (int sub)
+{
+ gfc_gsymbol *s;
+
+ s = gfc_get_gsymbol(gfc_new_block->name);
+
+ if (s->type != GSYM_UNKNOWN)
+ global_used(s, NULL);
+ else
+ {
+ s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
+ s->where = gfc_current_locus;
+ }
+}
+
+
+/* Add a program to the global symbol table. */
+
+static void
+add_global_program (void)
+{
+ gfc_gsymbol *s;
+
+ if (gfc_new_block == NULL)
+ return;
+ s = gfc_get_gsymbol (gfc_new_block->name);
+
+ if (s->type != GSYM_UNKNOWN)
+ global_used(s, NULL);
+ else
+ {
+ s->type = GSYM_PROGRAM;
+ s->where = gfc_current_locus;
+ }
+}
+
+
+/* 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);
+ add_global_program ();
+ parse_progunit (ST_NONE);
+ break;
+
+ case ST_SUBROUTINE:
+ add_global_procedure (1);
+ push_state (&s, COMP_SUBROUTINE, gfc_new_block);
+ accept_statement (st);
+ parse_progunit (ST_NONE);
+ break;
+
+ case ST_FUNCTION:
+ add_global_procedure (0);
+ 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..e1f40493256
--- /dev/null
+++ b/gcc/fortran/primary.c
@@ -0,0 +1,2219 @@
+/* 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_current_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_current_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_notify_std (GFC_STD_GNU, "Extension: Hexadecimal "
+ "constant at %C uses non-standard syntax.")
+ == FAILURE))
+ goto backup;
+
+ /* 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_current_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_current_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_current_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_current_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_current_locus = old_loc;
+ return MATCH_NO;
+ }
+
+ /* Convert the number. */
+ gfc_current_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:
+ if (gfc_option.warn_underflow)
+ gfc_warning ("Real constant underflows its kind at %C");
+ mpf_set_ui(e->value.real, 0);
+ break;
+
+ 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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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_current_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. */
+
+match
+gfc_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 = gfc_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..03851f5ad5e
--- /dev/null
+++ b/gcc/fortran/resolve.c
@@ -0,0 +1,4493 @@
+/* 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->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_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_IOLENGTH:
+ assert(code->ext.inquire != NULL);
+ 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;
+ int i;
+ const char *whynot;
+
+
+ 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);
+ }
+ }
+ }
+
+ /* Assumed size arrays and assumed shape arrays must be dummy
+ arguments. */
+
+ 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;
+ }
+
+ if (sym->attr.flavor == FL_PARAMETER
+ && sym->as != NULL && sym->as->type != AS_EXPLICIT)
+ {
+ gfc_error ("Parameter array '%s' at %L must have an explicit shape",
+ sym->name, &sym->declared_at);
+ return;
+ }
+
+ /* Make sure that character string variables with assumed length are
+ dummy arguments. */
+
+ 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;
+ }
+ }
+ }
+
+ if (sym->attr.flavor == FL_VARIABLE)
+ {
+ /* Can the sybol have an initializer? */
+ whynot = NULL;
+ if (sym->attr.allocatable)
+ whynot = "Allocatable";
+ else if (sym->attr.external)
+ whynot = "External";
+ else if (sym->attr.dummy)
+ whynot = "Dummy";
+ else if (sym->attr.intrinsic)
+ whynot = "Intrinsic";
+ else if (sym->attr.result)
+ whynot = "Function Result";
+ else if (sym->attr.dimension && !sym->attr.pointer)
+ {
+ /* Don't allow initialization of automatic arrays. */
+ for (i = 0; i < sym->as->rank; i++)
+ {
+ if (sym->as->lower[i] == NULL
+ || sym->as->lower[i]->expr_type != EXPR_CONSTANT
+ || sym->as->upper[i] == NULL
+ || sym->as->upper[i]->expr_type != EXPR_CONSTANT)
+ {
+ whynot = "Automatic array";
+ break;
+ }
+ }
+ }
+
+ /* Reject illegal initializers. */
+ if (sym->value && whynot)
+ {
+ gfc_error ("%s '%s' at %L cannot have an initializer",
+ whynot, sym->name, &sym->declared_at);
+ return;
+ }
+
+ /* Assign default initializer. */
+ if (sym->ts.type == BT_DERIVED && !(sym->value || whynot))
+ sym->value = gfc_default_initializer (&sym->ts);
+ }
+
+
+ /* 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;
+ ar_type mark = AR_UNKNOWN;
+ 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 = AR_FULL;
+ break;
+
+ case AR_SECTION:
+ ar = &ref->u.ar;
+ /* Get the start position of array section. */
+ gfc_get_section_index (ar, section_index, &offset);
+ mark = AR_SECTION;
+ 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 == AR_FULL)
+ mpz_add_ui (offset, offset, 1);
+
+ /* Modify the array section indexes and recalculate the offset for
+ next element. */
+ else if (mark == AR_SECTION)
+ gfc_advance_section (section_index, ar, &offset);
+
+ mpz_sub_ui (size, size, 1);
+ }
+ if (mark == AR_SECTION)
+ {
+ 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..8b8f0b0295e
--- /dev/null
+++ b/gcc/fortran/scanner.c
@@ -0,0 +1,1132 @@
+/* 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 *file_head, *current_file;
+
+static int continue_flag, end_flag;
+
+gfc_source_form gfc_current_form;
+static gfc_linebuf *line_head, *line_tail;
+
+locus gfc_current_locus;
+char *gfc_source_file;
+
+
+/* Main scanner initialization. */
+
+void
+gfc_scanner_init_1 (void)
+{
+ file_head = NULL;
+ line_head = NULL;
+ line_tail = NULL;
+
+ end_flag = 0;
+}
+
+
+/* Main scanner destructor. */
+
+void
+gfc_scanner_done_1 (void)
+{
+ gfc_linebuf *lb;
+ gfc_file *f;
+
+ while(line_head != NULL)
+ {
+ lb = line_head->next;
+ gfc_free(line_head);
+ line_head = lb;
+ }
+
+ while(file_head != NULL)
+ {
+ f = file_head->next;
+ gfc_free(file_head->filename);
+ gfc_free(file_head);
+ file_head = f;
+ }
+
+}
+
+
+/* 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;
+}
+
+/* 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 (line_head == NULL)
+ return 1; /* Null file */
+
+ if (gfc_current_locus.lb == NULL)
+ return 1;
+
+ return 0;
+}
+
+
+/* Test to see if we're at the beginning of a new line. */
+
+int
+gfc_at_bol (void)
+{
+ if (gfc_at_eof ())
+ return 1;
+
+ return (gfc_current_locus.nextc == gfc_current_locus.lb->line);
+}
+
+
+/* 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_locus.nextc == '\0');
+}
+
+
+/* Advance the current line pointer to the next line. */
+
+void
+gfc_advance_line (void)
+{
+ if (gfc_at_end ())
+ return;
+
+ if (gfc_current_locus.lb == NULL)
+ {
+ end_flag = 1;
+ return;
+ }
+
+ gfc_current_locus.lb = gfc_current_locus.lb->next;
+
+ if (gfc_current_locus.lb != NULL)
+ gfc_current_locus.nextc = gfc_current_locus.lb->line;
+ else
+ {
+ gfc_current_locus.nextc = NULL;
+ end_flag = 1;
+ }
+}
+
+
+/* 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)
+{
+ int c;
+
+ if (gfc_current_locus.nextc == NULL)
+ return '\n';
+
+ c = *gfc_current_locus.nextc++;
+ if (c == '\0')
+ {
+ gfc_current_locus.nextc--; /* Remain on this line. */
+ c = '\n';
+ }
+
+ return c;
+}
+
+/* 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_current_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_current_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_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_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_locus;
+
+ 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_current_locus = old_loc;
+ c = '&';
+ goto done;
+ }
+
+ if (c != '!' && c != '\n')
+ {
+ gfc_current_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_current_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_current_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_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_current_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_current_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, char *buffer, char *filename, int linenum)
+{
+ int c, maxlen, i, trunc_flag, preprocessor_flag;
+
+ maxlen = (gfc_current_form == FORM_FREE)
+ ? 132
+ : gfc_option.fixed_line_length;
+
+ i = 0;
+
+ preprocessor_flag = 0;
+ c = fgetc (input);
+ if (c == '#')
+ /* Don't truncate preprocessor lines. */
+ preprocessor_flag = 1;
+ ungetc (c, input);
+
+ for (;;)
+ {
+ c = fgetc (input);
+
+ if (c == EOF)
+ break;
+ if (c == '\n')
+ break;
+
+ if (c == '\r')
+ continue; /* Gobble characters. */
+ if (c == '\0')
+ continue;
+
+ if (c == '\032')
+ {
+ /* Ctrl-Z ends the file. */
+ while (fgetc (input) != EOF);
+ break;
+ }
+
+ if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
+ { /* Tab expandsion. */
+ while (i <= 6)
+ {
+ *buffer++ = ' ';
+ i++;
+ }
+
+ continue;
+ }
+
+ *buffer++ = c;
+ i++;
+
+ if (i >= maxlen && !preprocessor_flag)
+ { /* 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 ("%s:%d: Line is being truncated",
+ filename, linenum);
+ trunc_flag = 0;
+ }
+ }
+
+ ungetc ('\n', input);
+ }
+ }
+
+ *buffer = '\0';
+}
+
+
+/* Get a gfc_file structure, initialize it and add it to
+ the file stack. */
+
+static gfc_file *
+get_file (char *name)
+{
+ gfc_file *f;
+
+ f = gfc_getmem (sizeof (gfc_file));
+
+ f->filename = gfc_getmem (strlen (name) + 1);
+ strcpy (f->filename, name);
+
+ f->next = file_head;
+ file_head = f;
+
+ f->included_by = current_file;
+ if (current_file != NULL)
+ f->inclusion_line = current_file->line;
+
+ return f;
+}
+
+/* Deal with a line from the C preprocessor. The
+ initial octothorp has already been seen. */
+
+static void
+preprocessor_line (char *c)
+{
+ bool flag[5];
+ int i, line;
+ char *filename;
+ gfc_file *f;
+
+ c++;
+ while (*c == ' ' || *c == '\t')
+ c++;
+
+ if (*c < '0' || *c > '9')
+ goto bad_cpp_line;
+
+ line = atoi (c);
+
+ c = strchr (c, ' ');
+ if (c == NULL)
+ /* Something we don't understand has happened. */
+ goto bad_cpp_line;
+ c += 2; /* Skip space and quote. */
+ filename = c;
+
+ c = strchr (c, '"'); /* Make filename end at quote. */
+ if (c == NULL)
+ /* Preprocessor line has no closing quote. */
+ goto bad_cpp_line;
+ *c++ = '\0';
+
+ /* Get flags. */
+
+ flag[1] = flag[2] = flag[3] = flag[4] = flag[5] = false;
+
+ for (;;)
+ {
+ c = strchr (c, ' ');
+ if (c == NULL)
+ break;
+
+ c++;
+ i = atoi (c);
+
+ if (1 <= i && i <= 4)
+ flag[i] = true;
+ }
+
+ /* Interpret flags. */
+
+ if (flag[1] || flag[3]) /* Starting new file. */
+ {
+ f = get_file (filename);
+ f->up = current_file;
+ current_file = f;
+ }
+
+ if (flag[2]) /* Ending current file. */
+ {
+ current_file = current_file->up;
+ }
+
+ current_file->line = line;
+
+ /* The name of the file can be a temporary file produced by
+ cpp. Replace the name if it is different. */
+
+ if (strcmp (current_file->filename, filename) != 0)
+ {
+ gfc_free (current_file->filename);
+ current_file->filename = gfc_getmem (strlen (filename) + 1);
+ strcpy (current_file->filename, filename);
+ }
+
+ return;
+
+ bad_cpp_line:
+ gfc_warning_now ("%s:%d: Unknown preprocessor directive",
+ current_file->filename, current_file->line);
+ current_file->line++;
+}
+
+
+static try load_file (char *, bool);
+
+/* include_line()-- Checks a line buffer to see if it is an include
+ line. If so, we call load_file() recursively to load the included
+ file. We never return a syntax error because a statement like
+ "include = 5" is perfectly legal. We return false if no include was
+ processed or true if we matched an include. */
+
+static bool
+include_line (char *line)
+{
+ char quote, *c, *begin, *stop;
+
+ c = line;
+ while (*c == ' ' || *c == '\t')
+ c++;
+
+ if (strncasecmp (c, "include", 7))
+ return false;
+
+ c += 7;
+ while (*c == ' ' || *c == '\t')
+ c++;
+
+ /* Find filename between quotes. */
+
+ quote = *c++;
+ if (quote != '"' && quote != '\'')
+ return false;
+
+ begin = c;
+
+ while (*c != quote && *c != '\0')
+ c++;
+
+ if (*c == '\0')
+ return false;
+
+ stop = c++;
+
+ while (*c == ' ' || *c == '\t')
+ c++;
+
+ if (*c != '\0' && *c != '!')
+ return false;
+
+ /* We have an include line at this point. */
+
+ *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
+ read by anything else. */
+
+ load_file (begin, false);
+ return true;
+}
+
+/* Load a file into memory by calling load_line until the file ends. */
+
+static try
+load_file (char *filename, bool initial)
+{
+ char line[GFC_MAX_LINE+1];
+ gfc_linebuf *b;
+ gfc_file *f;
+ FILE *input;
+ int len;
+
+ for (f = current_file; f; f = f->up)
+ if (strcmp (filename, f->filename) == 0)
+ {
+ gfc_error_now ("File '%s' is being included recursively", filename);
+ return FAILURE;
+ }
+
+ if (initial)
+ {
+ input = gfc_open_file (filename);
+ if (input == NULL)
+ {
+ gfc_error_now ("Can't open file '%s'", filename);
+ return FAILURE;
+ }
+ }
+ else
+ {
+ input = gfc_open_included_file (filename);
+ if (input == NULL)
+ {
+ gfc_error_now ("Can't open included file '%s'", filename);
+ return FAILURE;
+ }
+ }
+
+ /* Load the file. */
+
+ f = get_file (filename);
+ f->up = current_file;
+ current_file = f;
+ current_file->line = 1;
+
+ for (;;)
+ {
+ load_line (input, line, filename, current_file->line);
+
+ len = strlen (line);
+ if (feof (input) && len == 0)
+ break;
+
+ /* There are three things this line can be: a line of Fortran
+ source, an include line or a C preprocessor directive. */
+
+ if (line[0] == '#')
+ {
+ preprocessor_line (line);
+ continue;
+ }
+
+ if (include_line (line))
+ {
+ current_file->line++;
+ continue;
+ }
+
+ /* Add line. */
+
+ b = gfc_getmem (sizeof (gfc_linebuf) + len + 1);
+
+ b->linenum = current_file->line++;
+ b->file = current_file;
+ strcpy (b->line, line);
+
+ if (line_head == NULL)
+ line_head = b;
+ else
+ line_tail->next = b;
+
+ line_tail = b;
+ }
+
+ fclose (input);
+
+ current_file = current_file->up;
+ return SUCCESS;
+}
+
+
+/* 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. Returns SUCCESS
+ if everything went OK, FAILURE otherwise. If form == FORM_UKNOWN
+ it tries to determine the source form from the filename, defaulting
+ to free form. */
+
+try
+gfc_new_file (const char *filename, gfc_source_form form)
+{
+ try result;
+
+ if (filename != NULL)
+ {
+ gfc_source_file = gfc_getmem (strlen (filename) + 1);
+ strcpy (gfc_source_file, filename);
+ }
+ else
+ gfc_source_file = NULL;
+
+ /* Decide which form the file will be read in as. */
+
+ if (form != FORM_UNKNOWN)
+ gfc_current_form = form;
+ else
+ {
+ gfc_current_form = form_from_filename (filename);
+
+ if (gfc_current_form == FORM_UNKNOWN)
+ {
+ gfc_current_form = FORM_FREE;
+ gfc_warning_now ("Reading file '%s' as free form.",
+ (filename[0] == '\0') ? "<stdin>" : filename);
+ }
+ }
+
+ result = load_file (gfc_source_file, true);
+
+ gfc_current_locus.lb = line_head;
+ gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
+
+#if 0 /* Debugging aid. */
+ for (; line_head; line_head = line_head->next)
+ gfc_status ("%s:%3d %s\n", line_head->file->filename,
+ line_head->linenum, line_head->line);
+
+ exit (0);
+#endif
+
+ return result;
+}
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
new file mode 100644
index 00000000000..a90d05d0460
--- /dev/null
+++ b/gcc/fortran/simplify.c
@@ -0,0 +1,4008 @@
+/* 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);
+
+ 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..743769c2c97
--- /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..9208d2205d9
--- /dev/null
+++ b/gcc/fortran/symbol.c
@@ -0,0 +1,2420 @@
+/* Maintain binary trees of symbols.
+ 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 <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;
+
+gfc_gsymbol *gfc_gsym_root = NULL;
+
+static gfc_symbol *changed_syms = NULL;
+
+
+/*********** IMPLICIT NONE and IMPLICIT statement handlers ***********/
+
+/* The following static variable indicates whether a particular element has
+ been explicitly set or not. */
+
+static int new_flag[GFC_LETTERS];
+
+
+/* Handle a correctly parsed IMPLICIT NONE. */
+
+void
+gfc_set_implicit_none (void)
+{
+ int i;
+
+ for (i = 0; i < GFC_LETTERS; i++)
+ {
+ gfc_clear_ts (&gfc_current_ns->default_type[i]);
+ gfc_current_ns->set_flag[i] = 1;
+ }
+}
+
+
+/* Reset the implicit range flags. */
+
+void
+gfc_clear_new_implicit (void)
+{
+ int i;
+
+ for (i = 0; i < GFC_LETTERS; i++)
+ new_flag[i] = 0;
+}
+
+
+/* Prepare for a new implicit range. Sets flags in new_flag[]. */
+
+try
+gfc_add_new_implicit_range (int c1, int c2)
+{
+ 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_flag[i] = 1;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Add a matched implicit range for gfc_set_implicit(). Check if merging
+ the new implicit types back into the existing types will work. */
+
+try
+gfc_merge_new_implicit (gfc_typespec * ts)
+{
+ 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;
+ }
+ gfc_current_ns->default_type[i] = *ts;
+ gfc_current_ns->set_flag[i] = 1;
+ }
+ }
+ 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_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_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_data (symbol_attribute *attr, locus *where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ attr->data = 1;
+ return check_conflict (attr, 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->result = 0;
+ attr->entry = 0;
+ attr->data = 0;
+ attr->use_assoc = 0;
+ attr->in_namelist = 0;
+
+ attr->in_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->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->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. */
+
+void
+gfc_traverse_symtree (gfc_symtree * st, void (*func) (gfc_symtree *))
+{
+ if (st != NULL)
+ {
+ (*func) (st);
+
+ gfc_traverse_symtree (st->left, func);
+ gfc_traverse_symtree (st->right, 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->sym_root, 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.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
+
+
+/************** Global symbol handling ************/
+
+
+/* Search a tree for the global symbol. */
+
+gfc_gsymbol *
+gfc_find_gsymbol (gfc_gsymbol *symbol, char *name)
+{
+ gfc_gsymbol *s;
+
+ if (symbol == NULL)
+ return NULL;
+ if (strcmp (symbol->name, name) == 0)
+ return symbol;
+
+ s = gfc_find_gsymbol (symbol->left, name);
+ if (s != NULL)
+ return s;
+
+ s = gfc_find_gsymbol (symbol->right, name);
+ if (s != NULL)
+ return s;
+
+ return NULL;
+}
+
+
+/* Compare two global symbols. Used for managing the BB tree. */
+
+static int
+gsym_compare (void * _s1, void * _s2)
+{
+ gfc_gsymbol *s1, *s2;
+
+ s1 = (gfc_gsymbol *)_s1;
+ s2 = (gfc_gsymbol *)_s2;
+ return strcmp(s1->name, s2->name);
+}
+
+
+/* Get a global symbol, creating it if it doesn't exist. */
+
+gfc_gsymbol *
+gfc_get_gsymbol (char *name)
+{
+ gfc_gsymbol *s;
+
+ s = gfc_find_gsymbol (gfc_gsym_root, name);
+ if (s != NULL)
+ return s;
+
+ s = gfc_getmem (sizeof (gfc_gsymbol));
+ s->type = GSYM_UNKNOWN;
+ strcpy (s->name, name);
+
+ gfc_insert_bbt (&gfc_gsym_root, s, gsym_compare);
+
+ return s;
+}
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
new file mode 100644
index 00000000000..731fb193099
--- /dev/null
+++ b/gcc/fortran/trans-array.c
@@ -0,0 +1,4165 @@
+/* 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 actually 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, NULL_TREE);
+}
+
+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, NULL_TREE);
+}
+
+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, NULL_TREE);
+}
+
+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, NULL_TREE);
+ 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, NULL_TREE);
+ 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, NULL_TREE);
+ 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, NULL_TREE);
+ 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, gfc_index_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] = gfc_index_zero_node;
+ }
+
+ info->delta[dim] = gfc_index_zero_node;
+ info->start[dim] = gfc_index_zero_node;
+ info->stride[dim] = gfc_index_one_node;
+ info->dim[dim] = dim;
+ }
+
+ /* Initialize 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 = gfc_index_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, gfc_index_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], gfc_index_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 scope. */
+ 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, gfc_index_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,
+ fold_convert (TREE_TYPE (ref), se.expr));
+ gfc_add_block_to_block (&body, &se.post);
+
+ *poffset = fold (build (PLUS_EXPR, gfc_array_index_type,
+ *poffset, gfc_index_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,
+ gfc_index_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 the 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 = gfc_index_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 because 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);
+
+ /* Initially 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
+ {
+ /* Descriptorless 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 gfc_index_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 = gfc_index_zero_node;
+
+ fault = gfc_index_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], gfc_index_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] = gfc_index_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] = gfc_index_zero_node;
+ ss->data.info.stride[n] = gfc_index_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 dependencies 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 constructor. */
+ /* TODO: avoid this by making the frontend set the shape. */
+ gfc_get_array_cons_size (&i, ss->expr->value.constructor);
+ /* A negative value means 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] = gfc_index_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] = gfc_index_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 = gfc_index_one_node;
+ offset = gfc_index_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 = gfc_index_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 = gfc_index_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,
+ gfc_index_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 = gfc_index_one_node;
+ offset = gfc_index_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,
+ gfc_index_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,
+ gfc_index_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 = gfc_index_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, fold_convert (type, tmp));
+
+ offset = gfc_index_zero_node;
+ size = gfc_index_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,
+ gfc_index_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 temporary, 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 variables, 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, gfc_index_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 = gfc_index_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 = gfc_index_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, gfc_array_index_type,
+ gfc_index_one_node, from));
+ to = fold (build (PLUS_EXPR, gfc_array_index_type, to, tmp));
+ from = gfc_index_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,
+ fold_convert (TREE_TYPE (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,
+ convert (TREE_TYPE (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 separately. */
+ 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..152f7d43850
--- /dev/null
+++ b/gcc/fortran/trans-common.c
@@ -0,0 +1,848 @@
+/* Common block and equivalence list handling
+ Copyright (C) 2000, 2003, 2004 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.
+
+ Each segment is described by a chain of segment_info structures. Each
+ segment_info structure describes the extents of a single varible within
+ the segment. This list is maintained in the order the elements are
+ positioned withing the segment. If two elements have the same starting
+ offset the smaller will come first. If they also have the same size their
+ ordering is undefined.
+
+ 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"
+#include <assert.h>
+
+
+typedef struct segment_info
+{
+ gfc_symbol *sym;
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT length;
+ tree field;
+ struct segment_info *next;
+} segment_info;
+
+static segment_info *current_segment, *current_common;
+static HOST_WIDE_INT current_offset;
+static gfc_namespace *gfc_common_ns = NULL;
+
+#define get_segment_info() gfc_getmem (sizeof (segment_info))
+
+#define BLANK_COMMON_NAME "__BLNK__"
+
+
+/* Add combine segment V and segement LIST. */
+
+static segment_info *
+add_segments (segment_info *list, segment_info *v)
+{
+ segment_info *s;
+ segment_info *p;
+ segment_info *next;
+
+ p = NULL;
+ s = list;
+
+ while (v)
+ {
+ /* Find the location of the new element. */
+ while (s)
+ {
+ if (v->offset < s->offset)
+ break;
+ if (v->offset == s->offset
+ && v->length <= s->length)
+ break;
+
+ p = s;
+ s = s->next;
+ }
+
+ /* Insert the new element in between p and s. */
+ next = v->next;
+ v->next = s;
+ if (p == NULL)
+ list = v;
+ else
+ p->next = v;
+
+ p = v;
+ v = next;
+ }
+ return list;
+}
+
+/* Construct mangled common block name from symbol name. */
+
+static tree
+gfc_sym_mangled_common_id (const char *name)
+{
+ int has_underscore;
+ char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
+
+ if (strcmp (name, BLANK_COMMON_NAME) == 0)
+ return get_identifier (name);
+ if (gfc_option.flag_underscoring)
+ {
+ has_underscore = strchr (name, '_') != 0;
+ if (gfc_option.flag_second_underscore && has_underscore)
+ snprintf (mangled_name, sizeof mangled_name, "%s__", name);
+ else
+ snprintf (mangled_name, sizeof mangled_name, "%s_", name);
+ return get_identifier (mangled_name);
+ }
+ else
+ return get_identifier (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 HOST_WIDE_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;
+
+ if (is_init)
+ {
+ decl = gfc_create_var (union_type, "equiv");
+ TREE_STATIC (decl) = 1;
+ return decl;
+ }
+
+ decl = build_decl (VAR_DECL, NULL, union_type);
+ DECL_ARTIFICIAL (decl) = 1;
+
+ 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_common_head *com, const char *name,
+ 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 (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 = TYPE_SIZE_UNIT (union_type);
+ 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 (name, BLANK_COMMON_NAME))
+ gfc_warning ("Named COMMON block '%s' at %L shall be of the "
+ "same size", name, &com->where);
+ 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 (name), union_type);
+ SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (name));
+ TREE_PUBLIC (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
+ DECL_USER_ALIGN (decl) = 0;
+
+ /* Place the back end declaration for this common block in
+ GLOBAL_BINDING_LEVEL. */
+ common_sym->backend_decl = pushdecl_top_level (decl);
+ }
+
+ /* Has no initial values. */
+ if (!is_init)
+ {
+ DECL_INITIAL (decl) = NULL_TREE;
+ DECL_COMMON (decl) = 1;
+ DECL_DEFER_OUTPUT (decl) = 1;
+
+ }
+ else
+ {
+ DECL_INITIAL (decl) = error_mark_node;
+ DECL_COMMON (decl) = 0;
+ DECL_DEFER_OUTPUT (decl) = 0;
+ }
+ 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_common_head *com, const char *name)
+{
+ 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 (com)
+ decl = build_common_decl (com, name, union_type, is_init);
+ else
+ decl = build_equiv_decl (union_type, is_init);
+
+ if (is_init)
+ {
+ tree list, ctor, tmp;
+ gfc_se se;
+ HOST_WIDE_INT offset = 0;
+
+ list = NULL_TREE;
+ for (h = current_common; h; h = h->next)
+ {
+ if (h->sym->value)
+ {
+ if (h->offset < offset)
+ {
+ /* We have overlapping initializers. It could either be
+ partially initilalized arrays (lagal), or the user
+ specified multiple initial values (illegal).
+ We don't implement this yet, so bail out. */
+ gfc_todo_error ("Initialization of overlapping variables");
+ }
+ if (h->sym->attr.dimension)
+ {
+ tmp = gfc_conv_array_initializer (TREE_TYPE (h->field),
+ h->sym->value);
+ list = tree_cons (h->field, tmp, list);
+ }
+ else
+ {
+ switch (h->sym->ts.type)
+ {
+ case BT_CHARACTER:
+ se.expr = gfc_conv_string_init
+ (h->sym->ts.cl->backend_decl, h->sym->value);
+ break;
+
+ case BT_DERIVED:
+ gfc_init_se (&se, NULL);
+ gfc_conv_structure (&se, h->sym->value, 1);
+ break;
+
+ default:
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, h->sym->value);
+ break;
+ }
+ list = tree_cons (h->field, se.expr, list);
+ }
+ offset = h->offset + h->length;
+ }
+ }
+ assert (list);
+ ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
+ TREE_CONSTANT (ctor) = 1;
+ TREE_INVARIANT (ctor) = 1;
+ TREE_STATIC (ctor) = 1;
+ DECL_INITIAL (decl) = ctor;
+
+#ifdef ENABLE_CHECKING
+ for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
+ assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
+#endif
+ }
+
+ /* 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, NULL_TREE);
+
+ 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 HOST_WIDE_INT
+calculate_length (gfc_symbol *symbol)
+{
+ HOST_WIDE_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 HOST_WIDE_INT
+element_number (gfc_array_ref *ar)
+{
+ mpz_t multiplier, offset, extent, l;
+ gfc_array_spec *as;
+ HOST_WIDE_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 HOST_WIDE_INT
+calculate_offset (gfc_expr *s)
+{
+ HOST_WIDE_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 segment. eq1 is already
+ in the list, eq2 is not. */
+
+static void
+new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
+{
+ HOST_WIDE_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);
+
+ current_segment = add_segments (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)
+{
+ HOST_WIDE_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);
+}
+
+
+/* Process a new equivalence condition. eq1 is know to be in segment f.
+ If eq2 is also present then confirm that the condition holds.
+ Otherwise add a new variable to the segment list. */
+
+static void
+add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
+{
+ segment_info *n;
+
+ n = find_segment_info (eq2->expr->symtree->n.sym);
+
+ if (n == NULL)
+ new_condition (f, eq1, eq2);
+ else
+ confirm_condition (f, eq1, n, eq2);
+}
+
+
+/* Given a segment element, search through the equivalence lists for unused
+ conditions that involve the symbol. Add these rules to the segment. Only
+ checks for rules involving the first symbol in the equivalence set. */
+
+static bool
+find_equivalence (segment_info *f)
+{
+ gfc_equiv *c, *l, *eq, *other;
+ bool found;
+
+ found = FALSE;
+ for (c = f->sym->ns->equiv; c; c = c->next)
+ {
+ other = NULL;
+ for (l = c->eq; l; l = l->eq)
+ {
+ if (l->used)
+ continue;
+
+ if (c->expr->symtree->n.sym == f-> sym)
+ {
+ eq = c;
+ other = l;
+ }
+ else if (l->expr->symtree->n.sym == f->sym)
+ {
+ eq = l;
+ other = c;
+ }
+ else
+ eq = NULL;
+
+ if (eq)
+ {
+ add_condition (f, eq, other);
+ eq->used = 1;
+ found = TRUE;
+ /* If this symbol is the first in the chain we may find other
+ matches. Otherwise we can skip to the next equivalence. */
+ if (eq == l)
+ break;
+ }
+ }
+ }
+ return found;
+}
+
+
+/* Add all symbols equivalenced within a segment. We need to scan the
+ segment list multiple times to include indirect equivalences. */
+
+static void
+add_equivalences (void)
+{
+ segment_info *f;
+ bool more;
+
+ more = TRUE;
+ while (more)
+ {
+ more = FALSE;
+ for (f = current_segment; f; f = f->next)
+ {
+ if (!f->sym->equiv_built)
+ {
+ f->sym->equiv_built = 1;
+ more = find_equivalence (f);
+ }
+ }
+ }
+}
+
+
+/* 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_common_head *common, const char *name, gfc_symbol *sym)
+{
+ HOST_WIDE_INT length;
+
+ current_segment = get_segment_info ();
+ current_segment->sym = sym;
+ current_segment->offset = current_offset;
+ length = calculate_length (sym);
+ current_segment->length = length;
+
+ /* Add all object directly or indirectly equivalenced with this common
+ variable. */
+ add_equivalences ();
+
+ if (current_segment->offset < 0)
+ gfc_error ("The equivalence set for '%s' cause an invalid extension "
+ "to COMMON '%s' at %L",
+ sym->name, name, &common->where);
+
+ /* The offset of the next common variable. */
+ current_offset += length;
+
+ /* Add these to the common block. */
+ current_common = add_segments (current_common, current_segment);
+}
+
+
+/* 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;
+ HOST_WIDE_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_segment = get_segment_info ();
+ current_segment->sym = sym;
+ current_segment->offset = 0;
+ current_segment->length = calculate_length (sym);
+
+ /* All objects directly or indrectly equivalenced with this symbol. */
+ add_equivalences ();
+
+ /* Calculate the minimal offset. */
+ min_offset = current_segment->offset;
+
+ /* Adjust the offset of each equivalence object. */
+ for (v = current_segment; v; v = v->next)
+ v->offset -= min_offset;
+
+ current_common = current_segment;
+ create_common (NULL, NULL);
+ break;
+ }
+}
+
+
+/* Translate a single common block. */
+
+static void
+translate_common (gfc_common_head *common, const char *name,
+ gfc_symbol *var_list)
+{
+ gfc_symbol *sym;
+
+ current_common = NULL;
+ current_offset = 0;
+
+ /* Add symbols to the segment. */
+ for (sym = var_list; sym; sym = sym->common_next)
+ {
+ if (! sym->equiv_built)
+ new_segment (common, name, sym);
+ }
+
+ create_common (common, name);
+}
+
+
+/* Work function for translating a named common block. */
+
+static void
+named_common (gfc_symtree *st)
+{
+ translate_common (st->n.common, st->name, st->n.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_common_head *c;
+
+ /* Translate the blank common block. */
+ if (ns->blank_common.head != NULL)
+ {
+ c = gfc_get_common_head ();
+ translate_common (c, BLANK_COMMON_NAME, ns->blank_common.head);
+ }
+
+ /* Translate all named common blocks. */
+ gfc_traverse_symtree (ns->common_root, 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..8a716de6c6c
--- /dev/null
+++ b/gcc/fortran/trans-const.c
@@ -0,0 +1,377 @@
+/* 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 or truncated to match
+ 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;
+
+ 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].max_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..97e831346fe
--- /dev/null
+++ b/gcc/fortran/trans-const.h
@@ -0,0 +1,61 @@
+/* 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]
+#define gfc_index_one_node gfc_rank_cst[1]
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
new file mode 100644
index 00000000000..47d9ba53a5a
--- /dev/null
+++ b/gcc/fortran/trans-decl.c
@@ -0,0 +1,2216 @@
+/* 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. */
+
+gfc_powdecl_list gfor_fndecl_math_powi[3][2];
+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;
+tree gfor_fndecl_iargc;
+
+/* 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.lb->linenum;
+ DECL_SOURCE_FILE (label_decl) = lp->where.lb->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;
+}
+
+
+/* Substitute a temporary variable in place of the real one. */
+
+void
+gfc_shadow_sym (gfc_symbol * sym, tree decl, gfc_saved_var * save)
+{
+ save->attr = sym->attr;
+ save->decl = sym->backend_decl;
+
+ gfc_clear_attr (&sym->attr);
+ sym->attr.referenced = 1;
+ sym->attr.flavor = FL_VARIABLE;
+
+ sym->backend_decl = decl;
+}
+
+
+/* Restore the original variable. */
+
+void
+gfc_restore_sym (gfc_symbol * sym, gfc_saved_var * save)
+{
+ sym->attr = save->attr;
+ sym->backend_decl = save->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)
+ {
+ if (sym->attr.function)
+ DECL_IS_PURE (fndecl) = 1;
+ /* TODO: check if pure SUBROUTINEs don't have INTENT(OUT)
+ parameters and don't use alternate returns (is this
+ allowed?). In that case, calls to them are meaningless, and
+ can be optimized away. See also in gfc_build_function_decl(). */
+ 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 declaring 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)
+ {
+ /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments
+ including a alternate return. In that case it can also be
+ marked as PURE. See also in gfc_get_extern_fucntion_decl(). */
+ if (attr.function)
+ 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. */
+ {
+ tree type;
+ tree itype;
+ int kind;
+ int ikind;
+ static int kinds[2] = {4, 8};
+ char name[PREFIX_LEN + 10]; /* _gfortran_pow_?n_?n */
+
+ for (ikind=0; ikind < 2; ikind++)
+ {
+ itype = gfc_get_int_type (kinds[ikind]);
+ for (kind = 0; kind < 2; kind ++)
+ {
+ type = gfc_get_int_type (kinds[kind]);
+ sprintf(name, PREFIX("pow_i%d_i%d"), kinds[kind], kinds[ikind]);
+ gfor_fndecl_math_powi[kind][ikind].integer =
+ gfc_build_library_function_decl (get_identifier (name),
+ type, 2, type, itype);
+
+ type = gfc_get_real_type (kinds[kind]);
+ sprintf(name, PREFIX("pow_r%d_i%d"), kinds[kind], kinds[ikind]);
+ gfor_fndecl_math_powi[kind][ikind].real =
+ gfc_build_library_function_decl (get_identifier (name),
+ type, 2, type, itype);
+
+ type = gfc_get_complex_type (kinds[kind]);
+ sprintf(name, PREFIX("pow_c%d_i%d"), kinds[kind], kinds[ikind]);
+ gfor_fndecl_math_powi[kind][ikind].cmplx =
+ gfc_build_library_function_decl (get_identifier (name),
+ type, 2, type, itype);
+ }
+ }
+ }
+
+ 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);
+
+ gfor_fndecl_iargc =
+ gfc_build_library_function_decl (get_identifier (PREFIX ("iargc")),
+ gfc_int4_type_node,
+ 0);
+}
+
+
+/* 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;
+
+ /* Since we don't use a DECL_STMT or equivalent, we have to deal
+ with getting these gimplified. But we can't gimplify it yet since
+ we're still generating statements.
+
+ ??? This should be cleaned up and handled like other front ends. */
+ gfc_add_expr_to_block (&body, save_expr (DECL_SIZE (decl)));
+ gfc_add_expr_to_block (&body, save_expr (DECL_SIZE_UNIT (decl)));
+
+ /* 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);
+ }
+
+ /* Only output variables and array valued parametes. */
+ if (sym->attr.flavor != FL_VARIABLE
+ && (sym->attr.flavor != FL_PARAMETER || sym->attr.dimension == 0))
+ return;
+
+ if (sym->attr.flavor == FL_VARIABLE && sym->ts.type == BT_UNKNOWN)
+ /* TODO: This is a workaround for the issue outlined in PR 15481,
+ and it fixes the bug in PR13372. This should never happen in an
+ ideal frontend. */
+ 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 if the frontend left the namespace in a reasonable state. */
+ assert (ns->proc_name && !ns->proc_name->tlink);
+
+ /* Create decls for all the module variables. */
+ 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 or are use_associated. */
+ else if (warn_unused_variable
+ && !(sym->attr.in_common || sym->attr.use_assoc))
+ 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);
+}
+
+/* Convert FNDECL's code to GIMPLE and handle any nested functions. */
+
+static void
+gfc_gimplify_function (tree fndecl)
+{
+ struct cgraph_node *cgn;
+
+ gimplify_function_tree (fndecl);
+ dump_function (TDI_generic, fndecl);
+
+ /* Convert all nested functions to GIMPLE 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)
+ gfc_gimplify_function (cgn->decl);
+}
+
+/* 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);
+
+ /* 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. */
+ 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);
+ else
+ {
+ gfc_gimplify_function (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);
+
+ 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..47a844d92d2
--- /dev/null
+++ b/gcc/fortran/trans-expr.c
@@ -0,0 +1,1925 @@
+/* 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,
+ fold_convert (TREE_TYPE (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,
+ fold_convert (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, NULL_TREE);
+
+ 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,
+ convert (type, integer_zero_node));
+ else
+ se->expr = build1 (code, type, operand.expr);
+
+}
+
+/* Expand power operator to optimal multiplications when a value is raised
+ to an constant integer n. See section 4.6.3, "Evaluation of Powers" of
+ Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
+ Programming", 3rd Edition, 1998. */
+
+/* This code is mostly duplicated from expand_powi in the backend.
+ We establish the "optimal power tree" lookup table with the defined size.
+ The items in the table are the exponents used to calculate the index
+ exponents. Any integer n less than the value can get an "addition chain",
+ with the first node being one. */
+#define POWI_TABLE_SIZE 256
+
+/* The table is from Builtins.c. */
+static const unsigned char powi_table[POWI_TABLE_SIZE] =
+ {
+ 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
+ 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
+ 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
+ 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
+ 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
+ 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
+ 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
+ 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
+ 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
+ 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
+ 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
+ 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
+ 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
+ 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
+ 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
+ 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
+ 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
+ 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
+ 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
+ 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
+ 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
+ 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
+ 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
+ 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
+ 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
+ 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
+ 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
+ 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
+ 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
+ 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
+ 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
+ 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
+ };
+
+/* If n is larger than lookup table's max index, we use "window method". */
+#define POWI_WINDOW_SIZE 3
+
+/* Recursive function to expand power operator. The temporary values are put
+ in tmpvar. The function return tmpvar[1] ** n. */
+static tree
+gfc_conv_powi (gfc_se * se, int n, tree * tmpvar)
+{
+ tree op0;
+ tree op1;
+ tree tmp;
+ int digit;
+
+ if (n < POWI_TABLE_SIZE)
+ {
+ if (tmpvar[n])
+ return tmpvar[n];
+
+ op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
+ op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
+ }
+ else if (n & 1)
+ {
+ digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
+ op0 = gfc_conv_powi (se, n - digit, tmpvar);
+ op1 = gfc_conv_powi (se, digit, tmpvar);
+ }
+ else
+ {
+ op0 = gfc_conv_powi (se, n >> 1, tmpvar);
+ op1 = op0;
+ }
+
+ tmp = fold (build (MULT_EXPR, TREE_TYPE (op0), op0, op1));
+ tmp = gfc_evaluate_now (tmp, &se->pre);
+
+ if (n < POWI_TABLE_SIZE)
+ tmpvar[n] = tmp;
+
+ return tmp;
+}
+
+/* Expand lhs ** rhs. rhs is an constant integer. If expand successfully,
+ return 1. Else return 0 and will call runtime library functions. */
+static int
+gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
+{
+ tree cond;
+ tree tmp;
+ tree type;
+ tree vartmp[POWI_TABLE_SIZE];
+ int n;
+ int sgn;
+
+ type = TREE_TYPE (lhs);
+ n = abs (TREE_INT_CST_LOW (rhs));
+ sgn = tree_int_cst_sgn (rhs);
+
+ if ((!flag_unsafe_math_optimizations || optimize_size) && (n > 2 || n < -1))
+ return 0;
+
+ /* rhs == 0 */
+ if (sgn == 0)
+ {
+ se->expr = gfc_build_const (type, integer_one_node);
+ return 1;
+ }
+ /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
+ if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
+ {
+ tmp = build (EQ_EXPR, boolean_type_node, lhs,
+ fold_convert (TREE_TYPE (lhs), integer_minus_one_node));
+ cond = build (EQ_EXPR, boolean_type_node, lhs,
+ convert (TREE_TYPE (lhs), integer_one_node));
+
+ /* If rhs is an even,
+ result = (lhs == 1 || lhs == -1) ? 1 : 0. */
+ if ((n & 1) == 0)
+ {
+ tmp = build (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
+ se->expr = build (COND_EXPR, type, tmp,
+ convert (type, integer_one_node),
+ convert (type, integer_zero_node));
+ return 1;
+ }
+ /* If rhs is an odd,
+ result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
+ tmp = build (COND_EXPR, type, tmp,
+ convert (type, integer_minus_one_node),
+ convert (type, integer_zero_node));
+ se->expr = build (COND_EXPR, type, cond,
+ convert (type, integer_one_node),
+ tmp);
+ return 1;
+ }
+
+ memset (vartmp, 0, sizeof (vartmp));
+ vartmp[1] = lhs;
+ if (sgn == -1)
+ {
+ tmp = gfc_build_const (type, integer_one_node);
+ vartmp[1] = build (RDIV_EXPR, type, tmp, vartmp[1]);
+ }
+
+ se->expr = gfc_conv_powi (se, n, vartmp);
+
+ return 1;
+}
+
+
+/* Power op (**). Constant integer exponent has special handling. */
+
+static void
+gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
+{
+ int kind;
+ int ikind;
+ gfc_se lse;
+ gfc_se rse;
+ tree fndecl;
+ tree tmp;
+
+ 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);
+
+ if (expr->op2->ts.type == BT_INTEGER
+ && expr->op2->expr_type == EXPR_CONSTANT)
+ if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
+ return;
+
+ kind = expr->op1->ts.kind;
+ switch (expr->op2->ts.type)
+ {
+ case BT_INTEGER:
+ ikind = expr->op2->ts.kind;
+ switch (ikind)
+ {
+ case 1:
+ case 2:
+ rse.expr = convert (gfc_int4_type_node, rse.expr);
+ /* Fall through. */
+
+ case 4:
+ ikind = 0;
+ break;
+
+ case 8:
+ ikind = 1;
+ break;
+
+ default:
+ abort();
+ }
+ switch (kind)
+ {
+ case 1:
+ case 2:
+ if (expr->op1->ts.type == BT_INTEGER)
+ lse.expr = convert (gfc_int4_type_node, lse.expr);
+ else
+ abort ();
+ /* Fall through. */
+
+ case 4:
+ kind = 0;
+ break;
+
+ case 8:
+ kind = 1;
+ break;
+
+ default:
+ abort();
+ }
+
+ switch (expr->op1->ts.type)
+ {
+ case BT_INTEGER:
+ fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
+ break;
+
+ case BT_REAL:
+ fndecl = gfor_fndecl_math_powi[kind][ikind].real;
+ break;
+
+ case BT_COMPLEX:
+ fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ case BT_REAL:
+ switch (kind)
+ {
+ case 4:
+ fndecl = built_in_decls[BUILT_IN_POWF];
+ break;
+ case 8:
+ fndecl = built_in_decls[BUILT_IN_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 = fold (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 (TREE_TYPE (len) != gfc_strlen_type_node)
+ abort ();
+
+ if (gfc_can_put_var_on_stack (len))
+ {
+ /* Create a temporary variable to hold the result. */
+ tmp = fold (build (MINUS_EXPR, gfc_strlen_type_node, len,
+ convert (gfc_strlen_type_node,
+ integer_one_node)));
+ tmp = build_range_type (gfc_array_index_type, gfc_index_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,
+ convert (TREE_TYPE (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 (arg->missing_arg_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
+ && arg->expr->expr_type != EXPR_NULL)
+ {
+ /* Scalar pointer dummy args require an extra level of
+ indirection. The null pointer already contains
+ this 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 ();
+ }
+}
+
+
+/* Generate code to copy a string. */
+
+static void
+gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
+ tree slen, tree src)
+{
+ tree tmp;
+
+ tmp = NULL_TREE;
+ tmp = gfc_chainon_list (tmp, dlen);
+ tmp = gfc_chainon_list (tmp, dest);
+ tmp = gfc_chainon_list (tmp, slen);
+ tmp = gfc_chainon_list (tmp, src);
+ tmp = gfc_build_function_call (gfor_fndecl_copy_string, tmp);
+ gfc_add_expr_to_block (block, tmp);
+}
+
+
+/* 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;
+ gfc_saved_var *saved_vars;
+ tree *temp_vars;
+ tree type;
+ tree tmp;
+ int n;
+
+ sym = expr->symtree->n.sym;
+ args = expr->value.function.actual;
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+
+ n = 0;
+ for (fargs = sym->formal; fargs; fargs = fargs->next)
+ n++;
+ saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
+ temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
+
+ for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
+ {
+ /* Each dummy shall be specified, explicitly or implicitly, to be
+ scalar. */
+ assert (fargs->sym->attr.dimension == 0);
+ fsym = fargs->sym;
+
+ /* Create a temporary to hold the value. */
+ type = gfc_typenode_for_spec (&fsym->ts);
+ temp_vars[n] = gfc_create_var (type, fsym->name);
+
+ if (fsym->ts.type == BT_CHARACTER)
+ {
+ /* Copy string arguments. */
+ tree arglen;
+
+ assert (fsym->ts.cl && fsym->ts.cl->length
+ && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
+
+ arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ tmp = gfc_build_addr_expr (build_pointer_type (type),
+ temp_vars[n]);
+
+ gfc_conv_expr (&rse, args->expr);
+ gfc_conv_string_parameter (&rse);
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+ gfc_add_block_to_block (&se->pre, &rse.pre);
+
+ gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
+ rse.expr);
+ 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. */
+ gfc_conv_expr (&lse, args->expr);
+
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+ gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
+ gfc_add_block_to_block (&se->pre, &lse.post);
+ }
+
+ args = args->next;
+ }
+
+ /* Use the temporary variables in place of the real ones. */
+ for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
+ gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
+
+ gfc_conv_expr (se, sym->value);
+
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ gfc_conv_const_charlen (sym->ts.cl);
+
+ /* Force the expression to the correct length. */
+ if (!INTEGER_CST_P (se->string_length)
+ || tree_int_cst_lt (se->string_length,
+ sym->ts.cl->backend_decl))
+ {
+ type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
+ tmp = gfc_create_var (type, sym->name);
+ tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
+ gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
+ se->string_length, se->expr);
+ se->expr = tmp;
+ }
+ se->string_length = sym->ts.cl->backend_decl;
+ }
+
+ /* Resore the original variables. */
+ for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
+ gfc_restore_sym (fargs->sym, &saved_vars[n]);
+ gfc_free (saved_vars);
+}
+
+
+/* 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;
+
+ 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,
+ fold_convert (TREE_TYPE (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 = fold_convert (TREE_TYPE (lse.expr), null_pointer_node);
+ gfc_add_modify_expr (&block, lse.expr, rse.expr);
+ }
+ 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)
+{
+ stmtblock_t block;
+
+ gfc_init_block (&block);
+
+ if (type == BT_CHARACTER)
+ {
+ 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);
+
+ gfc_trans_string_copy (&block, lse->string_length, lse->expr,
+ rse->string_length, rse->expr);
+ }
+ else
+ {
+ gfc_add_block_to_block (&block, &lse->pre);
+ gfc_add_block_to_block (&block, &rse->pre);
+
+ gfc_add_modify_expr (&block, lse->expr,
+ fold_convert (TREE_TYPE (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..1151da95256
--- /dev/null
+++ b/gcc/fortran/trans-intrinsic.c
@@ -0,0 +1,3067 @@
+/* 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,
+ convert (type, 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,
+ gfc_index_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,
+ convert (TREE_TYPE (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,
+ fold_convert (TREE_TYPE (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, convert (type, 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,
+ convert (TREE_TYPE (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], gfc_index_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],
+ gfc_index_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, convert (type, integer_one_node), arg2);
+ tmp = build (BIT_AND_EXPR, type, arg, tmp);
+ tmp = fold (build (NE_EXPR, boolean_type_node, tmp,
+ convert (type, 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,
+ convert (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,
+ convert (TREE_TYPE (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,
+ convert (TREE_TYPE (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,
+ convert (TREE_TYPE (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,
+ convert (TREE_TYPE (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 || (arg->ref->next == NULL
+ && arg->ref->type == REF_ARRAY)))
+ {
+ /* This doesn't catch all cases.
+ See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
+ and the surrounding thread. */
+ 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,
+ convert (TREE_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,
+ fold_convert (TREE_TYPE (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,
+ fold_convert (TREE_TYPE (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,
+ convert (masktype, 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,
+ convert (TREE_TYPE (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 the IARGC intrinsic. If args_only is true this is
+ actually the COMMAND_ARGUMENT_COUNT intrinsic, so return IARGC - 1. */
+
+static void
+gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr, bool args_only)
+{
+ tree tmp;
+ tree fndecl;
+ tree type;
+
+ /* Call the library function. This always returns an INTEGER(4). */
+ fndecl = gfor_fndecl_iargc;
+ tmp = gfc_build_function_call (fndecl, NULL_TREE);
+
+ /* Convert it to the required type. */
+ type = gfc_typenode_for_spec (&expr->ts);
+ tmp = fold_convert (type, tmp);
+
+ if (args_only)
+ tmp = build (MINUS_EXPR, type, tmp, convert (type, integer_one_node));
+ se->expr = tmp;
+}
+
+/* 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_COMMAND_ARGUMENT_COUNT:
+ gfc_conv_intrinsic_iargc (se, expr, TRUE);
+ 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_IARGC:
+ gfc_conv_intrinsic_iargc (se, expr, FALSE);
+ 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:
+ case GFC_ISYM_IRAND:
+ case GFC_ISYM_RAND:
+ case GFC_ISYM_ETIME:
+ case GFC_ISYM_SECOND:
+ 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..9c4acc5e035
--- /dev/null
+++ b/gcc/fortran/trans-io.c
@@ -0,0 +1,1223 @@
+/* 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_iolength;
+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_iolength;
+static GTY(()) tree iocall_iolength_done;
+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, IOLENGTH } 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_FIELD (iolength, 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_iolength =
+ gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
+ void_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_iolength_done =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_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, NULL_TREE);
+ 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, NULL_TREE);
+ 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, NULL_TREE);
+ len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len,
+ NULL_TREE);
+
+ /* 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, convert (TREE_TYPE (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, fold_convert (TREE_TYPE (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, type = TREE_TYPE (var);
+
+ tmp = build (COMPONENT_REF, type, ioparm_var, var, NULL_TREE);
+ gfc_add_modify_expr (block, tmp, convert (type, 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, NULL_TREE);
+
+ 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->lb->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->lb->linenum;
+ 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);
+}
+
+
+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;
+
+ assert (dt != NULL);
+
+ 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 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 * code)
+{
+ stmtblock_t block;
+ gfc_inquire *inq;
+ tree dt;
+
+ gfc_init_block (&block);
+
+ set_error_locus (&block, &code->loc);
+
+ inq = code->ext.inquire;
+
+ /* First check that preconditions are met. */
+ assert(inq != NULL);
+ assert(inq->iolength != NULL);
+
+ /* Connect to the iolength variable. */
+ if (inq->iolength)
+ set_parameter_ref (&block, ioparm_iolength, inq->iolength);
+
+ /* Actual logic. */
+ last_dt = IOLENGTH;
+ dt = build_dt(&iocall_iolength, code);
+
+ gfc_add_expr_to_block (&block, dt);
+
+ 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);
+
+ switch (last_dt)
+ {
+ case READ:
+ function = iocall_read_done;
+ break;
+
+ case WRITE:
+ function = iocall_write_done;
+ break;
+
+ case IOLENGTH:
+ function = iocall_iolength_done;
+ break;
+
+ default:
+ abort ();
+ }
+
+ tmp = gfc_build_function_call (function, NULL);
+ gfc_add_expr_to_block (&block, tmp);
+
+ if (last_dt != IOLENGTH)
+ {
+ assert(code->ext.dt != NULL);
+ 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,
+ NULL_TREE);
+
+ 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..794e2fc9017
--- /dev/null
+++ b/gcc/fortran/trans-stmt.c
@@ -0,0 +1,3144 @@
+/* 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, gfc_index_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, gfc_index_one_node);
+ gfc_add_modify_expr (&block, maskindex, tmp);
+ }
+ }
+ /* Decrement the loop counter. */
+ tmp = build (MINUS_EXPR, TREE_TYPE (var), count, gfc_index_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,
+ gfc_index_one_node));
+ }
+ else
+ tmp = NULL_TREE;
+
+ type = build_range_type (gfc_array_index_type, gfc_index_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, gfc_index_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, gfc_array_index_type,
+ count2, gfc_index_one_node));
+ gfc_add_modify_expr (&body, count2, tmp);
+
+ /* Increment count3. */
+ if (count3)
+ {
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type,
+ count3, gfc_index_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, gfc_index_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, gfc_index_one_node));
+ gfc_add_modify_expr (&body1, count2, tmp);
+
+ /* Increment count3. */
+ if (count3)
+ {
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type,
+ count3, gfc_index_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 = gfc_index_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, gfc_array_index_type,
+ gfc_index_one_node, loop.from[i]));
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type,
+ tmp, loop.to[i]));
+ size = fold (build (MULT_EXPR, gfc_array_index_type, 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, gfc_index_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, gfc_index_zero_node);
+ }
+ else
+ count = NULL;
+
+ /* Initialize count1. */
+ gfc_add_modify_expr (block, count1, gfc_index_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, gfc_index_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, gfc_index_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, gfc_index_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+
+ /* Reset count. */
+ if (wheremask)
+ gfc_add_modify_expr (block, count, gfc_index_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, gfc_index_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, gfc_array_index_type,
+ count, gfc_index_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, gfc_index_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, gfc_index_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, gfc_index_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, gfc_array_index_type,
+ count, gfc_index_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, gfc_array_index_type,
+ count, gfc_index_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, gfc_index_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, gfc_index_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, gfc_index_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, gfc_array_index_type,
+ count, gfc_index_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;
+ gfc_saved_var *saved_vars;
+ 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_vars = (gfc_saved_var *) gfc_getmem (nvar * sizeof (gfc_saved_var));
+
+ /* 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));
+
+ /* Create a temporary variable for the FORALL index. */
+ tmp = gfc_typenode_for_spec (&sym->ts);
+ var[n] = gfc_create_var (tmp, sym->name);
+ gfc_shadow_sym (sym, var[n], &saved_vars[n]);
+
+ /* 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 = gfc_index_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, gfc_index_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, gfc_index_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, gfc_index_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, gfc_index_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 original index variables. */
+ for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
+ gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[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_vars);
+
+ 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, gfc_index_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,
+ gfc_index_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, gfc_array_index_type,
+ count1, gfc_index_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, gfc_array_index_type,
+ count1, gfc_index_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, gfc_array_index_type,
+ count2, gfc_index_one_node));
+ gfc_add_modify_expr (&body, count2, tmp);
+ }
+ else
+ {
+ /* Increment count1. */
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type,
+ count1, gfc_index_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, gfc_index_zero_node);
+ gfc_add_modify_expr (block, count2, gfc_index_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, gfc_index_zero_node);
+ gfc_add_modify_expr (block, count2, gfc_index_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..46146a941a0
--- /dev/null
+++ b/gcc/fortran/trans-types.c
@@ -0,0 +1,1499 @@
+/* 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, gfc_index_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().
+ Actually 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 internally 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 originally 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 the GENERIC
+ 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 the 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] = gfc_index_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, gfc_index_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, gfc_index_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 = gfc_index_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,
+ gfc_index_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,
+ gfc_index_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,
+ gfc_index_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 was 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..00215f6a2a4
--- /dev/null
+++ b/gcc/fortran/trans.c
@@ -0,0 +1,693 @@
+/* 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;
+
+#ifdef ENABLE_CHECKING
+ /* Make sure that the types of the rhs and the lhs are the same
+ for scalar assignments. We should probably have something
+ similar for aggregates, but right now removing that check just
+ breaks everything. */
+ if (TREE_TYPE (rhs) != TREE_TYPE (lhs)
+ && !AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
+ abort ();
+#endif
+
+ 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 = stmtblock->head;
+ if (!expr)
+ expr = build_empty_stmt ();
+
+ 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, NULL_TREE, NULL_TREE);
+}
+
+
+/* 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 likely. */
+ 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 block. */
+
+void
+gfc_add_expr_to_block (stmtblock_t * block, tree expr)
+{
+ assert (block);
+
+ if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
+ return;
+
+ if (TREE_CODE (expr) != STATEMENT_LIST)
+ expr = fold (expr);
+
+ if (block->head)
+ {
+ if (TREE_CODE (block->head) != STATEMENT_LIST)
+ {
+ tree tmp;
+
+ tmp = block->head;
+ block->head = NULL_TREE;
+ append_to_statement_list (tmp, &block->head);
+ }
+ append_to_statement_list (expr, &block->head);
+ }
+ else
+ /* Don't bother creating a list if we only have a single statement. */
+ 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_backend_locus. */
+
+void
+gfc_get_backend_locus (locus * loc)
+{
+ loc->lb = gfc_getmem (sizeof (gfc_linebuf));
+ loc->lb->linenum = input_line - 1;
+ loc->lb->file = gfc_current_backend_file;
+}
+
+
+/* Set the current locus. */
+
+void
+gfc_set_backend_locus (locus * loc)
+{
+ input_line = loc->lb->linenum;
+ gfc_current_backend_file = loc->lb->file;
+ input_filename = loc->lb->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))
+ {
+ if (TREE_CODE (res) == STATEMENT_LIST)
+ annotate_all_with_locus (&res, input_location);
+ else
+ 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..6119e587129
--- /dev/null
+++ b/gcc/fortran/trans.h
@@ -0,0 +1,559 @@
+/* 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;
+ unsigned 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;
+
+
+/* Information about a symbol that has been shadowed by a temporary. */
+typedef struct
+{
+ symbol_attribute attr;
+ tree decl;
+}
+gfc_saved_var;
+
+
+/* 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 *);
+
+/* Substitute a temporary variable in place of the real one. */
+void gfc_shadow_sym (gfc_symbol *, tree, gfc_saved_var *);
+
+/* Restore the original variable. */
+void gfc_restore_sym (gfc_symbol *, gfc_saved_var *);
+
+/* 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. */
+
+typedef struct gfc_powdecl_list GTY(())
+{
+ tree integer;
+ tree real;
+ tree cmplx;
+}
+gfc_powdecl_list;
+
+extern GTY(()) gfc_powdecl_list gfor_fndecl_math_powi[3][2];
+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;
+extern GTY(()) tree gfor_fndecl_iargc;
+
+/* 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/gimple-low.c b/gcc/gimple-low.c
new file mode 100644
index 00000000000..c29f591fe54
--- /dev/null
+++ b/gcc/gimple-low.c
@@ -0,0 +1,544 @@
+/* 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;
+
+ /* A TREE_LIST of label and return statements to be moved to the end
+ of the function. */
+ tree return_statements;
+};
+
+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 void lower_return_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;
+ tree t, x;
+
+ 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;
+
+ data.return_statements = NULL_TREE;
+
+ *body_p = alloc_stmt_list ();
+ i = tsi_start (*body_p);
+ tsi_link_after (&i, bind, TSI_NEW_STMT);
+ lower_bind_expr (&i, &data);
+
+ i = tsi_last (*body_p);
+
+ /* If the function falls off the end, we need a null return statement.
+ If we've already got one in the return_statements list, we don't
+ need to do anything special. Otherwise build one by hand. */
+ if (block_may_fallthru (*body_p)
+ && (data.return_statements == NULL
+ || TREE_OPERAND (TREE_VALUE (data.return_statements), 0) != NULL))
+ {
+ x = build (RETURN_EXPR, void_type_node, NULL);
+ SET_EXPR_LOCATION (x, cfun->function_end_locus);
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ }
+
+ /* If we lowered any return statements, emit the representative
+ at the end of the function. */
+ for (t = data.return_statements ; t ; t = TREE_CHAIN (t))
+ {
+ x = build (LABEL_EXPR, void_type_node, TREE_PURPOSE (t));
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+
+ /* Remove the line number from the representative return statement.
+ It now fills in for many such returns. Failure to remove this
+ will result in incorrect results for coverage analysis. */
+ x = TREE_VALUE (t);
+#ifdef USE_MAPPED_LOCATION
+ SET_EXPR_LOCATION (x, UNKNOWN_LOCATION);
+#else
+ SET_EXPR_LOCUS (x, NULL);
+#endif
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ }
+
+ if (data.block != DECL_INITIAL (current_function_decl))
+ abort ();
+ BLOCK_SUBBLOCKS (data.block)
+ = blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
+
+ clear_block_marks (data.block);
+}
+
+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 RETURN_EXPR:
+ lower_return_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 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);
+}
+
+static void
+lower_return_expr (tree_stmt_iterator *tsi, struct lower_data *data)
+{
+ tree stmt = tsi_stmt (*tsi);
+ tree value, t, label;
+
+ /* Extract the value being returned. */
+ value = TREE_OPERAND (stmt, 0);
+ if (value && TREE_CODE (value) == MODIFY_EXPR)
+ value = TREE_OPERAND (value, 1);
+
+ /* Match this up with an existing return statement that's been created. */
+ for (t = data->return_statements; t ; t = TREE_CHAIN (t))
+ {
+ tree tvalue = TREE_OPERAND (TREE_VALUE (t), 0);
+ if (tvalue && TREE_CODE (tvalue) == MODIFY_EXPR)
+ tvalue = TREE_OPERAND (tvalue, 1);
+
+ if (value == tvalue)
+ {
+ label = TREE_PURPOSE (t);
+ goto found;
+ }
+ }
+
+ /* Not found. Create a new label and record the return statement. */
+ label = create_artificial_label ();
+ data->return_statements = tree_cons (label, stmt, data->return_statements);
+
+ /* Generate a goto statement and remove the return statement. */
+ found:
+ t = build (GOTO_EXPR, void_type_node, label);
+ SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
+ tsi_link_before (tsi, t, TSI_SAME_STMT);
+ tsi_delink (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;
+
+ /* 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..0493efa0b37
--- /dev/null
+++ b/gcc/gimplify.c
@@ -0,0 +1,4272 @@
+/* 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 "cgraph.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"
+#include "target.h"
+
+static struct gimplify_ctx
+{
+ tree current_bind_expr;
+ bool save_stack;
+ tree temps;
+ tree conditional_cleanups;
+ int conditions;
+ tree exit_label;
+ tree return_temp;
+ 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;
+
+/* Forward declarations. */
+static enum gimplify_status gimplify_modify_expr_rhs (tree *, tree *, tree *,
+ tree *, tree *, bool);
+static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+
+
+/* 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 (!side_effects)
+ return;
+
+ if (!list)
+ {
+ if (t && TREE_CODE (t) == STATEMENT_LIST)
+ {
+ *list_p = t;
+ return;
+ }
+ *list_p = list = alloc_stmt_list ();
+ }
+
+ 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);
+}
+
+/* Both gimplify the statement T and append it to LIST_P. */
+
+void
+gimplify_and_add (tree t, tree *list_p)
+{
+ gimplify_stmt (&t);
+ append_to_statement_list (t, list_p);
+}
+
+/* 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 identifier. */
+
+static GTY(()) unsigned int tmp_var_id_num;
+
+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
+ /* We don't allow types that are addressable (meaning we can't make copies),
+ incomplete, or of variable size. */
+ if (TREE_ADDRESSABLE (type)
+ || !COMPLETE_TYPE_P (type)
+ || 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);
+ TREE_READONLY (elt_p->temp) = 1;
+ *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_HAS_LOCATION (val))
+ SET_EXPR_LOCUS (mod, EXPR_LOCUS (val));
+ else
+ SET_EXPR_LOCATION (mod, input_location);
+
+ /* gimplify_modify_expr might want to reduce this further. */
+ gimplify_and_add (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. */
+
+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;
+ }
+}
+
+void
+gimple_add_tmp_var (tree tmp)
+{
+ if (TREE_CHAIN (tmp) || DECL_SEEN_IN_BIND_EXPR_P (tmp))
+ abort ();
+
+ DECL_CONTEXT (tmp) = current_function_decl;
+ DECL_SEEN_IN_BIND_EXPR_P (tmp) = 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;
+}
+
+static void
+annotate_one_with_locus (tree t, location_t locus)
+{
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t)))
+ && ! EXPR_HAS_LOCATION (t)
+ && should_carry_locus_p (t))
+ SET_EXPR_LOCATION (t, locus);
+}
+
+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
+
+ annotate_one_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, decls, constants and SAVE_EXPR nodes. */
+ if (TREE_CODE_CLASS (code) == 't'
+ || TREE_CODE_CLASS (code) == 'd'
+ || 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)
+{
+ tree t = *tp;
+ enum tree_code code = TREE_CODE (t);
+
+ /* Skip types, decls, and constants. But we do want to look at their
+ types and the bounds of types. Mark them as visited so we properly
+ unmark their subtrees on the unmark pass. If we've already seen them,
+ don't look down further. */
+ if (TREE_CODE_CLASS (code) == 't'
+ || TREE_CODE_CLASS (code) == 'd'
+ || TREE_CODE_CLASS (code) == 'c')
+ {
+ if (TREE_VISITED (t))
+ *walk_subtrees = 0;
+ else
+ TREE_VISITED (t) = 1;
+ }
+
+ /* If this node has been visited already, unshare it and don't look
+ any deeper. */
+ else if (TREE_VISITED (t))
+ {
+ walk_tree (tp, mostly_copy_tree_r, NULL, NULL);
+ *walk_subtrees = 0;
+ }
+
+ /* Otherwise, mark the tree as visited and keep looking. */
+ else
+ {
+ TREE_VISITED (t) = 1;
+ if (TREE_CODE (*tp) == VA_ARG_EXPR
+ && targetm.calls.gimplify_va_arg_expr == NULL)
+ {
+ /* Mark any _DECL inside the operand as volatile to avoid
+ the optimizers messing around with it. We have to do this
+ early, otherwise we might mark a variable as volatile
+ after we gimplify other statements that use the variable
+ assuming it's not volatile. */
+
+ /* FIXME once most targets define the above hook, this should
+ go away (perhaps along with the #include "target.h"). */
+ 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 all the trees in BODY_P, a pointer into the body of FNDECL, and the
+ bodies of any nested functions if we are unsharing the entire body of
+ FNDECL. */
+
+static void
+unshare_body (tree *body_p, tree fndecl)
+{
+ struct cgraph_node *cgn = cgraph_node (fndecl);
+
+ walk_tree (body_p, copy_if_shared_r, NULL, NULL);
+ if (body_p == &DECL_SAVED_TREE (fndecl))
+ for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+ unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+}
+
+/* Likewise, but mark all trees as not visited. */
+
+static void
+unvisit_body (tree *body_p, tree fndecl)
+{
+ struct cgraph_node *cgn = cgraph_node (fndecl);
+
+ walk_tree (body_p, unmark_visited_r, NULL, NULL);
+ if (body_p == &DECL_SAVED_TREE (fndecl))
+ for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+ unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+}
+
+/* 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, tree temp)
+{
+ if (!VOID_TYPE_P (TREE_TYPE (wrapper)))
+ {
+ tree *p, sub = wrapper;
+
+ restart:
+ /* Set p to point to the body of the wrapper. */
+ switch (TREE_CODE (sub))
+ {
+ case BIND_EXPR:
+ /* For a BIND_EXPR, the body is operand 1. */
+ p = &BIND_EXPR_BODY (sub);
+ break;
+
+ default:
+ p = &TREE_OPERAND (sub, 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 == NULL || IS_EMPTY_STMT (*p))
+ ;
+ /* Look through exception handling. */
+ else if (TREE_CODE (*p) == TRY_FINALLY_EXPR
+ || TREE_CODE (*p) == TRY_CATCH_EXPR)
+ {
+ sub = *p;
+ goto restart;
+ }
+ /* The C++ frontend already did this for us. */
+ else if (TREE_CODE (*p) == INIT_EXPR
+ || TREE_CODE (*p) == TARGET_EXPR)
+ temp = TREE_OPERAND (*p, 0);
+ /* If we're returning a dereference, move the dereference
+ outside the wrapper. */
+ else if (TREE_CODE (*p) == INDIRECT_REF)
+ {
+ 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
+ {
+ if (!temp)
+ temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
+ *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
+ a temporary through which they communicate. */
+
+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 temp, tree *pre_p)
+{
+ tree bind_expr = *expr_p;
+ bool old_save_stack = gimplify_ctxp->save_stack;
+ tree t;
+
+ temp = voidify_wrapper_expr (bind_expr, temp);
+
+ /* Mark variables seen in this bind expr. */
+ for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
+ DECL_SEEN_IN_BIND_EXPR_P (t) = 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_decl, 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_decl = NULL_TREE;
+ else
+ {
+ result_decl = TREE_OPERAND (ret_expr, 0);
+#ifdef ENABLE_CHECKING
+ if ((TREE_CODE (ret_expr) != MODIFY_EXPR
+ && TREE_CODE (ret_expr) != INIT_EXPR)
+ || TREE_CODE (result_decl) != RESULT_DECL)
+ abort ();
+#endif
+ }
+
+ /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
+ Recall that aggregate_value_p is FALSE for any aggregate type that is
+ returned in registers. If we're returning values in registers, then
+ we don't want to extend the lifetime of the RESULT_DECL, particularly
+ across another call. In addition, for those aggregates for which
+ hard_function_value generates a PARALLEL, we'll abort during normal
+ expansion of structure assignments; there's special code in expand_return
+ to handle this case that does not exist in expand_expr. */
+ if (!result_decl
+ || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
+ result = result_decl;
+ else if (gimplify_ctxp->return_temp)
+ result = gimplify_ctxp->return_temp;
+ else
+ {
+ result = create_tmp_var (TREE_TYPE (result_decl), NULL);
+
+ /* ??? With complex control flow (usually involving abnormal edges),
+ we can wind up warning about an uninitialized value for this. Due
+ to how this variable is constructed and initialized, this is never
+ true. Give up and never warn. */
+ TREE_NO_WARNING (result) = 1;
+
+ gimplify_ctxp->return_temp = result;
+ }
+
+ /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
+ Then gimplify the whole thing. */
+ if (result != result_decl)
+ TREE_OPERAND (ret_expr, 0) = result;
+
+ gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
+
+ /* If we didn't use a temporary, then the result is just the result_decl.
+ Otherwise we need a simple copy. This should already be gimple. */
+ if (result == result_decl)
+ ret_expr = result;
+ else
+ ret_expr = build (MODIFY_EXPR, TREE_TYPE (result), result_decl, result);
+ TREE_OPERAND (stmt, 0) = ret_expr;
+
+ return GS_ALL_DONE;
+}
+
+/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
+ and initialization explicit. */
+
+static enum gimplify_status
+gimplify_decl_expr (tree *stmt_p)
+{
+ tree stmt = *stmt_p;
+ tree decl = DECL_EXPR_DECL (stmt);
+
+ *stmt_p = NULL_TREE;
+
+ if (TREE_TYPE (decl) == error_mark_node)
+ return GS_ERROR;
+
+ else if (TREE_CODE (decl) == TYPE_DECL)
+ gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+
+ else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+ {
+ tree init = DECL_INITIAL (decl);
+
+ if (!TREE_CONSTANT (DECL_SIZE (decl)))
+ {
+ /* 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(). */
+ tree t, args;
+
+ gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+ gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
+ gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+
+ args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
+ t = build_fold_addr_expr (decl);
+ args = tree_cons (NULL, t, args);
+ t = implicit_built_in_decls[BUILT_IN_STACK_ALLOC];
+ t = build_function_call_expr (t, args);
+
+ gimplify_and_add (t, stmt_p);
+ DECL_DEFER_OUTPUT (decl) = 1;
+ }
+
+ if (init && init != error_mark_node)
+ {
+ if (!TREE_STATIC (decl))
+ {
+ DECL_INITIAL (decl) = NULL_TREE;
+ init = build (MODIFY_EXPR, void_type_node, decl, init);
+ gimplify_and_add (init, stmt_p);
+ }
+ 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);
+ }
+
+ 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_and_add (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;
+}
+
+/* Compare two case labels. Because the front end should already have
+ made sure that case ranges do not overlap, it is enough to only compare
+ the CASE_LOW values of each case label. */
+
+static int
+compare_case_labels (const void *p1, const void *p2)
+{
+ tree case1 = *(tree *)p1;
+ tree case2 = *(tree *)p2;
+
+ return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
+}
+
+/* Sort the case labels in LABEL_VEC in ascending order. */
+
+void
+sort_case_labels (tree label_vec)
+{
+ size_t len = TREE_VEC_LENGTH (label_vec);
+ tree default_case = TREE_VEC_ELT (label_vec, len - 1);
+
+ if (CASE_LOW (default_case))
+ {
+ size_t i;
+
+ /* The last label in the vector should be the default case
+ but it is not. */
+ for (i = 0; i < len; ++i)
+ {
+ tree t = TREE_VEC_ELT (label_vec, i);
+ if (!CASE_LOW (t))
+ {
+ default_case = t;
+ TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1);
+ TREE_VEC_ELT (label_vec, len - 1) = default_case;
+ break;
+ }
+ }
+ }
+
+ qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree),
+ compare_case_labels);
+}
+
+/* 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;
+ tree label_vec, default_case = NULL_TREE;
+ 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);
+
+ for (i = 0; i < len; ++i)
+ {
+ tree t = VARRAY_TREE (labels, i);
+ if (!CASE_LOW (t))
+ {
+ /* The default case must be the last label in the list. */
+ default_case = t;
+ VARRAY_TREE (labels, i) = VARRAY_TREE (labels, len - 1);
+ len--;
+ break;
+ }
+ }
+
+ label_vec = make_tree_vec (len + 1);
+ SWITCH_LABELS (*expr_p) = label_vec;
+ append_to_statement_list (switch_expr, pre_p);
+
+ if (! default_case)
+ {
+ /* If the switch has no default label, add one, so that we jump
+ around the switch body. */
+ default_case = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
+ NULL_TREE, create_artificial_label ());
+ append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
+ *expr_p = build (LABEL_EXPR, void_type_node,
+ CASE_LABEL (default_case));
+ }
+ else
+ *expr_p = SWITCH_BODY (switch_expr);
+
+ for (i = 0; i < len; ++i)
+ TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i);
+ TREE_VEC_ELT (label_vec, len) = default_case;
+
+ sort_case_labels (label_vec);
+
+ 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 NULL_TREE;
+
+ 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, NULL_TREE);
+ *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;
+}
+
+/* *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 by converting
+ T array[U];
+ (T *)&array
+ ==>
+ &array[L]
+ where L is the lower bound. For simplicity, only do this for constant
+ lower bound. */
+
+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;
+
+ /* The lower bound and element sizes must be constant. */
+ if (TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
+ || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
+ || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
+ return;
+
+ /* All checks succeeded. Build a new node to merge the cast. */
+ *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
+ TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
+ TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
+ size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype),
+ size_int (TYPE_ALIGN (dctype)
+ / BITS_PER_UNIT)));
+ *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
+}
+
+/* *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)
+{
+ /* 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;
+}
+
+/* Subroutine of gimplify_compound_lval.
+ 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 = array_ref_element_size (*expr_p);
+ tree ptrtype = build_pointer_type (elttype);
+ enum tree_code add_code = PLUS_EXPR;
+ tree idx = TREE_OPERAND (*expr_p, 1);
+ tree minidx = unshare_expr (array_ref_low_bound (*expr_p));
+ tree offset, addr, result;
+ enum gimplify_status ret;
+
+ /* If the array domain does not start at zero, apply the offset. */
+ if (!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 = fold_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_fold_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, fallback_t fallback)
+{
+ tree *p;
+ varray_type stack;
+ enum gimplify_status ret = GS_OK, tret;
+ int i;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (*expr_p) != ARRAY_REF
+ && TREE_CODE (*expr_p) != ARRAY_RANGE_REF
+ && TREE_CODE (*expr_p) != COMPONENT_REF
+ && TREE_CODE (*expr_p) != BIT_FIELD_REF
+ && TREE_CODE (*expr_p) != REALPART_EXPR
+ && TREE_CODE (*expr_p) != IMAGPART_EXPR)
+ abort ();
+#endif
+
+ /* Create a stack of the subexpressions so later we can walk them in
+ order from inner to outer. */
+ VARRAY_TREE_INIT (stack, 10, "stack");
+
+ /* We can either handle REALPART_EXPR, IMAGEPART_EXPR anything that
+ handled_components can deal with. */
+ for (p = expr_p;
+ (handled_component_p (*p)
+ || TREE_CODE (*p) == REALPART_EXPR || TREE_CODE (*p) == IMAGPART_EXPR);
+ p = &TREE_OPERAND (*p, 0))
+ VARRAY_PUSH_TREE (stack, *p);
+
+ /* Now STACK is a stack of pointers to all the refs we've walked through
+ and P points to the innermost expression.
+
+ Java requires that we elaborated nodes in source order. That
+ means we must gimplify the inner expression followed by each of
+ the indices, in order. But we can't gimplify the inner
+ expression until we deal with any variable bounds, sizes, or
+ positions in order to deal with PLACEHOLDER_EXPRs.
+
+ So we do this in three steps. First we deal with the annotations
+ for any variables in the components, then we gimplify the base,
+ then we gimplify any indices, from left to right. */
+ for (i = VARRAY_ACTIVE_SIZE (stack) - 1; i >= 0; i--)
+ {
+ tree t = VARRAY_TREE (stack, i);
+
+ if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
+ {
+ /* Gimplify the low bound and element type size and put them into
+ the ARRAY_REF. If these values are set, they have already been
+ gimplified. */
+ if (!TREE_OPERAND (t, 2))
+ {
+ tree low = unshare_expr (array_ref_low_bound (t));
+ if (!is_gimple_min_invariant (low))
+ {
+ TREE_OPERAND (t, 2) = low;
+ tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ is_gimple_tmp_var, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+ }
+
+ if (!TREE_OPERAND (t, 3))
+ {
+ tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
+ tree elmt_size = unshare_expr (array_ref_element_size (t));
+ tree factor = size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT);
+
+ /* Divide the element size by the alignment of the element
+ type (above). */
+ elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
+
+ if (!is_gimple_min_invariant (elmt_size))
+ {
+ TREE_OPERAND (t, 3) = elmt_size;
+ tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
+ is_gimple_tmp_var, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+ }
+ }
+ else if (TREE_CODE (t) == COMPONENT_REF)
+ {
+ /* Set the field offset into T and gimplify it. */
+ if (!TREE_OPERAND (t, 2))
+ {
+ tree offset = unshare_expr (component_ref_field_offset (t));
+ tree field = TREE_OPERAND (t, 1);
+ tree factor
+ = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
+
+ /* Divide the offset by its alignment. */
+ offset = size_binop (EXACT_DIV_EXPR, offset, factor);
+
+ if (!is_gimple_min_invariant (offset))
+ {
+ TREE_OPERAND (t, 2) = offset;
+ tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ is_gimple_tmp_var, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+ }
+ }
+ }
+
+ /* Step 2 is to gimplify the base expression. */
+ tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
+ ret = MIN (ret, tret);
+
+ /* And finally, the indices and operands to BIT_FIELD_REF. During this
+ loop we also remove any useless conversions. */
+ for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
+ {
+ tree t = VARRAY_TOP_TREE (stack);
+
+ if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
+ {
+ /* Gimplify the dimension.
+ 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);
+ ret = MIN (ret, tret);
+ }
+ }
+ else if (TREE_CODE (t) == BIT_FIELD_REF)
+ {
+ tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ ret = MIN (ret, tret);
+ tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+
+ STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
+
+ /* The innermost expression P may have originally had TREE_SIDE_EFFECTS
+ set which would have caused all the outer expressions in EXPR_P
+ leading to P to also have had TREE_SIDE_EFFECTS set. */
+ recalculate_side_effects (t);
+ VARRAY_POP (stack);
+ }
+
+ tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
+ ret = MIN (ret, tret);
+
+ /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
+ if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
+ {
+ canonicalize_component_ref (expr_p);
+ ret = MIN (ret, GS_OK);
+ }
+
+ return ret;
+}
+
+/* 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,
+ bool 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_and_add (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. PRE_P points to the
+ list where side effects that must happen before *EXPR_P should be stored.
+ WANT_VALUE is true if the result of the call is desired. */
+
+static enum gimplify_status
+gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
+{
+ 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_HAS_LOCATION (*expr_p))
+ SET_EXPR_LOCATION (*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, !want_value);
+
+ 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_call_addr, 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;
+ bool (*test) (tree);
+ fallback_t fb;
+
+ /* In general, we allow lvalues for function arguments to avoid
+ extra overhead of copying large aggregates out of even larger
+ aggregates into temporaries only to copy the temporaries to
+ the argument list. Make optimizers happy by pulling out to
+ temporaries those types that fit in registers. */
+ if (is_gimple_reg_type (TREE_TYPE (TREE_VALUE (arglist))))
+ test = is_gimple_val, fb = fb_rvalue;
+ else
+ test = is_gimple_lvalue, fb = fb_either;
+
+ /* 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, test, fb);
+
+ 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, !want_value);
+
+ 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;
+ bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
+ bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
+
+ /* First do simple transformations. */
+ if (!else_se)
+ {
+ /* 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_, NULL_TREE);
+ }
+ }
+ if (!then_se)
+ {
+ /* 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, NULL_TREE, 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 (then_
+ && TREE_CODE (then_) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
+ {
+ true_label = GOTO_DESTINATION (then_);
+ then_ = NULL;
+ then_se = false;
+ }
+
+ if (else_
+ && TREE_CODE (else_) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
+ {
+ false_label = GOTO_DESTINATION (else_);
+ else_ = NULL;
+ else_se = false;
+ }
+
+ /* 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 || else_se)
+ false_label_p = &false_label;
+ else
+ false_label_p = NULL;
+
+ /* If there was nothing else in our arms, just forward the label(s). */
+ if (!then_se && !else_se)
+ return shortcut_cond_r (pred, true_label_p, false_label_p);
+
+ /* If our last subexpression already has a terminal label, reuse it. */
+ if (else_se)
+ expr = expr_last (else_);
+ else if (then_se)
+ expr = expr_last (then_);
+ else
+ expr = NULL;
+ if (expr && 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 (else_se)
+ {
+ 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.
+
+ TARGET is the tree for T1 above.
+
+ 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, type;
+ enum gimplify_status ret;
+
+ type = TREE_TYPE (expr);
+ if (!type)
+ TREE_TYPE (expr) = void_type_node;
+
+ /* If this COND_EXPR has a value, copy the values into a temporary within
+ the arms. */
+ else if (! VOID_TYPE_P (type))
+ {
+ 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_and_add (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;
+}
+
+/* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
+ a call to __builtin_memcpy. */
+
+static enum gimplify_status
+gimplify_modify_expr_to_memcpy (tree *expr_p, bool want_value)
+{
+ tree args, t, to, to_ptr, from;
+
+ to = TREE_OPERAND (*expr_p, 0);
+ from = TREE_OPERAND (*expr_p, 1);
+
+ t = TYPE_SIZE_UNIT (TREE_TYPE (from));
+ t = unshare_expr (t);
+ t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
+ t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, from);
+ args = tree_cons (NULL, t, NULL);
+
+ t = build_fold_addr_expr (from);
+ args = tree_cons (NULL, t, args);
+
+ to_ptr = build_fold_addr_expr (to);
+ args = tree_cons (NULL, to_ptr, 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 (to_ptr), t);
+ t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
+ }
+
+ *expr_p = t;
+ return GS_OK;
+}
+
+/* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
+ a call to __builtin_memset. In this case we know that the RHS is
+ a CONSTRUCTOR with an empty element list. */
+
+static enum gimplify_status
+gimplify_modify_expr_to_memset (tree *expr_p, bool want_value)
+{
+ tree args, t, to, to_ptr;
+
+ to = TREE_OPERAND (*expr_p, 0);
+
+ t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (*expr_p, 1)));
+ t = unshare_expr (t);
+ t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
+ args = tree_cons (NULL, t, NULL);
+
+ args = tree_cons (NULL, integer_zero_node, args);
+
+ to_ptr = build_fold_addr_expr (to);
+ args = tree_cons (NULL, to_ptr, args);
+ t = implicit_built_in_decls[BUILT_IN_MEMSET];
+ t = build_function_call_expr (t, args);
+
+ if (want_value)
+ {
+ t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
+ t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
+ }
+
+ *expr_p = t;
+ return GS_OK;
+}
+
+/* A subroutine of gimplify_modify_expr. 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, bool 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_UNHANDLED;
+ }
+
+ 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 = NULL_TREE;
+ 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 behavior 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) + 1 != len)
+ cleared = 1;;
+ }
+ else if (len != fields_length (type))
+ cleared = 1;
+ }
+
+ if (cleared)
+ {
+ /* Zap the CONSTRUCTOR element list, which simplifies this case.
+ Note that we still have to gimplify, in order to handle the
+ case of variable sized types. Make an unshared copy of
+ OBJECT before that so we can match a PLACEHOLDER_EXPR to it
+ later, if needed. */
+ CONSTRUCTOR_ELTS (ctor) = NULL_TREE;
+ object = unshare_expr (TREE_OPERAND (*expr_p, 0));
+ gimplify_stmt (expr_p);
+ 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, unshare_expr (object), purpose,
+ NULL_TREE, NULL_TREE);
+ }
+ else
+ cref = build (COMPONENT_REF, TREE_TYPE (purpose),
+ unshare_expr (object), purpose, NULL_TREE);
+
+ init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
+
+ /* Each member initialization is a full-expression. */
+ gimplify_and_add (init, pre_p);
+ }
+
+ *expr_p = NULL_TREE;
+ }
+ 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;
+}
+
+/* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
+ based on the code of the RHS. We loop for as long as something changes. */
+
+static enum gimplify_status
+gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
+ tree *post_p, bool want_value)
+{
+ enum gimplify_status ret = GS_OK;
+
+ while (ret != GS_UNHANDLED)
+ switch (TREE_CODE (*from_p))
+ {
+ case TARGET_EXPR:
+ {
+ /* If we are initializing something from a TARGET_EXPR, strip the
+ TARGET_EXPR and initialize it directly, if possible. This can't
+ be done if the initializer is void, since that implies that the
+ temporary is set in some non-trivial way.
+
+ ??? 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. */
+ tree init = TARGET_EXPR_INITIAL (*from_p);
+
+ if (!VOID_TYPE_P (TREE_TYPE (init)))
+ {
+ *from_p = init;
+ ret = GS_OK;
+ }
+ else
+ ret = GS_UNHANDLED;
+ }
+ break;
+
+ case COMPOUND_EXPR:
+ /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
+ caught. */
+ gimplify_compound_expr (from_p, pre_p, true);
+ ret = GS_OK;
+ break;
+
+ case CONSTRUCTOR:
+ /* If we're initializing from a CONSTRUCTOR, break this into
+ individual MODIFY_EXPRs. */
+ return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
+
+ case COND_EXPR:
+ /* 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_ADDRESSABLE (TREE_TYPE (*from_p)))
+ {
+ *expr_p = *from_p;
+ return gimplify_cond_expr (expr_p, pre_p, *to_p);
+ }
+ else
+ ret = GS_UNHANDLED;
+ break;
+
+ default:
+ ret = GS_UNHANDLED;
+ break;
+ }
+
+ 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 = GS_UNHANDLED;
+
+#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);
+
+ /* See if any simplifications can be done based on what the RHS is. */
+ ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
+ want_value);
+ if (ret != GS_UNHANDLED)
+ return ret;
+
+ /* If the value being copied is of variable width, expose the length
+ if the copy by converting the whole thing to a memcpy/memset.
+ Note that we need to do this before gimplifying any of the operands
+ so that we can resolve any PLACEHOLDER_EXPRs in the size.
+ Also note that the RTL expander uses the size of the expression to
+ be copied, not of the destination, so that is what we must here.
+ The types on both sides of the MODIFY_EXPR should be the same,
+ but they aren't always and there are problems with class-wide types
+ in Ada where it's hard to make it "correct". */
+ if (TREE_CODE (TREE_TYPE (*from_p)) != ERROR_MARK
+ && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
+ && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*from_p))) != INTEGER_CST)
+ {
+ if (TREE_CODE (*from_p) == CONSTRUCTOR)
+ return gimplify_modify_expr_to_memset (expr_p, want_value);
+ else
+ return gimplify_modify_expr_to_memcpy (expr_p, want_value);
+ }
+
+ ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+ if (ret == GS_ERROR)
+ return ret;
+
+ ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
+ if (ret == GS_ERROR)
+ return ret;
+
+ /* Now see if the above changed *from_p to something we handle specially. */
+ ret = gimplify_modify_expr_rhs (expr_p, from_p, to_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 (aggregate_value_p (TREE_TYPE (*from_p), NULL_TREE))
+ /* Don't force a temp of a large aggregate type; the copy could be
+ arbitrarily expensive. Instead we will generate a V_MAY_DEF for
+ the assignment. */;
+ else 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);
+
+ 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 a comparison between two variable-sized objects. Do this
+ with a call to BUILT_IN_MEMCMP. */
+
+static enum gimplify_status
+gimplify_variable_sized_compare (tree *expr_p)
+{
+ tree op0 = TREE_OPERAND (*expr_p, 0);
+ tree op1 = TREE_OPERAND (*expr_p, 1);
+ tree args, t, dest;
+
+ t = TYPE_SIZE_UNIT (TREE_TYPE (op0));
+ t = unshare_expr (t);
+ t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0);
+ args = tree_cons (NULL, t, NULL);
+ t = build_fold_addr_expr (op1);
+ args = tree_cons (NULL, t, args);
+ dest = build_fold_addr_expr (op0);
+ args = tree_cons (NULL, dest, args);
+ t = implicit_built_in_decls[BUILT_IN_MEMCMP];
+ t = build_function_call_expr (t, args);
+ *expr_p
+ = build (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
+
+ return GS_OK;
+}
+
+/* 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
+ enlightened 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 (t == NULL)
+ tsi_delink (&i);
+ else 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 = NULL;
+ }
+ 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. */
+ *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+ break;
+
+ case VIEW_CONVERT_EXPR:
+ /* Take the address of our operand and then convert it to the type of
+ this ADDR_EXPR.
+
+ ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
+ all clear. The impact of this transformation is even less clear. */
+ *expr_p = fold_convert (TREE_TYPE (expr),
+ build_fold_addr_expr (TREE_OPERAND (op0, 0)));
+ ret = GS_OK;
+ 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)
+ {
+ /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
+ 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, NULL);
+
+ /* 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, NULL);
+ 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);
+
+ /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
+ expression is supposed to initialize the slot. */
+ if (VOID_TYPE_P (TREE_TYPE (init)))
+ ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+ else
+ {
+ /* Special handling for BIND_EXPR can result in fewer temps. */
+ ret = GS_OK;
+ if (TREE_CODE (init) == BIND_EXPR)
+ gimplify_bind_expr (&init, temp, pre_p);
+ if (init != temp)
+ {
+ 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 (!DECL_SEEN_IN_BIND_EXPR_P (temp))
+ /* 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 STATEMENT_LIST. */
+
+void
+gimplify_stmt (tree *stmt_p)
+{
+ gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
+}
+
+/* Similarly, but force the result to be a STATEMENT_LIST. */
+
+void
+gimplify_to_stmt_list (tree *stmt_p)
+{
+ gimplify_stmt (stmt_p);
+ if (!*stmt_p)
+ *stmt_p = alloc_stmt_list ();
+ else if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
+ {
+ tree t = *stmt_p;
+ *stmt_p = alloc_stmt_list ();
+ 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 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
+ && EXPR_HAS_LOCATION (*expr_p))
+ input_location = EXPR_LOCATION (*expr_p);
+
+ /* Loop over the specific gimplifiers until the toplevel node
+ remains the same. */
+ do
+ {
+ /* Strip away as many useless type conversions as possible
+ at the toplevel. */
+ STRIP_USELESS_TYPE_CONVERSION (*expr_p);
+
+ /* Remember the expr. */
+ save_expr = *expr_p;
+
+ /* Die, die, die, my darling. */
+ if (save_expr == error_mark_node
+ || (TREE_TYPE (save_expr)
+ && 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:
+ case ARRAY_RANGE_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case COMPONENT_REF:
+ ret = gimplify_compound_lval (expr_p, pre_p, post_p,
+ fallback ? fallback : fb_rvalue);
+ 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, fallback != fb_none);
+ break;
+
+ case TREE_LIST:
+ abort ();
+
+ case COMPOUND_EXPR:
+ ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
+ 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:
+ ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
+ break;
+
+ case VIEW_CONVERT_EXPR:
+ 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;
+ }
+
+ /* If both types are BLKmode or if one type is of variable size,
+ convert this into a pointer punning operation. This avoids
+ copies of large data or making a variable-size temporary.
+
+ ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
+ all clear. The impact of this transformation is even less
+ clear. */
+
+ if ((TYPE_MODE (TREE_TYPE (*expr_p)) == BLKmode
+ && TYPE_MODE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) == BLKmode)
+ || !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (*expr_p)))
+ || !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE
+ (TREE_OPERAND (*expr_p,0)))))
+ {
+ tree restype = TREE_TYPE (*expr_p);
+ *expr_p = build1 (INDIRECT_REF, TREE_TYPE (*expr_p),
+ fold_convert (build_pointer_type (restype),
+ build_fold_addr_expr
+ (TREE_OPERAND (*expr_p, 0))));
+ break;
+ }
+ goto unary;
+
+ 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:
+ /* 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 DECL_EXPR:
+ ret = gimplify_decl_expr (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, NULL, 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. Buf if we're just elaborating this for side effects, just
+ gimplify any element that has side-effects. */
+ if (fallback == fb_none)
+ {
+ for (tmp = CONSTRUCTOR_ELTS (*expr_p); tmp;
+ tmp = TREE_CHAIN (tmp))
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (tmp)))
+ gimplify_expr (&TREE_VALUE (tmp), pre_p, post_p,
+ gimple_test_f, fallback);
+
+ *expr_p = NULL_TREE;
+ }
+
+ 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_lvalue, 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 OBJ_TYPE_REF:
+ {
+ enum gimplify_status r0, r1;
+ r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ ret = MIN (r0, r1);
+ }
+ 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
+ && !DECL_SEEN_IN_BIND_EXPR_P (tmp))
+ {
+#ifdef ENABLE_CHECKING
+ if (!errorcount && !sorrycount)
+ abort ();
+#endif
+ ret = GS_ERROR;
+ }
+ else
+ ret = GS_ALL_DONE;
+ break;
+
+ default:
+ /* If this is a comparison of objects of aggregate type, handle
+ it specially (by converting to a call to memcmp). It would be
+ nice to only have to do this for variable-sized objects, but
+ then we'd have to allow the same nest of reference nodes we
+ allow for MODIFY_EXPR and that's too complex. */
+ if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<'
+ && (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 1)))))
+ ret = gimplify_variable_sized_compare (expr_p);
+
+ /* If *EXPR_P does not need to be special-cased, handle it
+ according to its class. */
+ else 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 = NULL;
+ 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 (fallback == fb_none && *expr_p && !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 = NULL;
+ else if (!TREE_THIS_VOLATILE (*expr_p))
+ {
+ /* This is probably a _REF that contains something nested that
+ has side effects. Recurse through the operands to find it. */
+ enum tree_code code = TREE_CODE (*expr_p);
+
+ if (code == COMPONENT_REF
+ || code == REALPART_EXPR || code == IMAGPART_EXPR)
+ gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ gimple_test_f, fallback);
+ else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
+ {
+ gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ gimple_test_f, fallback);
+ gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+ gimple_test_f, fallback);
+ }
+ else
+ /* Anything else with side-effects
+ must be converted to a valid statement before we get here. */
+ abort ();
+
+ *expr_p = NULL;
+ }
+ 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 = NULL;
+ }
+
+ /* If we are gimplifying at the statement level, we're done. Tack
+ everything together and replace the original statement with the
+ gimplified form. */
+ if (fallback == fb_none || is_statement)
+ {
+ if (internal_pre || internal_post)
+ {
+ 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;
+ }
+ else if (!*expr_p)
+ ;
+ else if (TREE_CODE (*expr_p) == STATEMENT_LIST)
+ annotate_all_with_locus (expr_p, input_location);
+ else
+ annotate_one_with_locus (*expr_p, input_location);
+ 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_fold_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;
+}
+
+/* Look through TYPE for variable-sized objects and gimplify each such
+ size that we find. Add to LIST_P any statements generated. */
+
+void
+gimplify_type_sizes (tree type, tree *list_p)
+{
+ tree field;
+
+ switch (TREE_CODE (type))
+ {
+ case ERROR_MARK:
+ return;
+
+ case INTEGER_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case CHAR_TYPE:
+ case REAL_TYPE:
+ gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
+ gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
+ break;
+
+ case ARRAY_TYPE:
+ /* These anonymous types don't have declarations, so handle them here. */
+ gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
+ break;
+
+ default:
+ break;
+ }
+
+ gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
+ gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
+}
+
+/* Subroutine of the above to gimplify one size or position, *EXPR_P.
+ We add any required statements to STMT_P. */
+
+void
+gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
+{
+ /* We don't do anything if the value isn't there, is constant, or contains
+ A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
+ a VAR_DECL. If it's a VAR_DECL from another function, the gimplfier
+ will want to replace it with a new variable, but that will cause problems
+ if this type is from outside the function. It's OK to have that here. */
+ if (*expr_p == NULL_TREE || TREE_CONSTANT (*expr_p)
+ || TREE_CODE (*expr_p) == VAR_DECL
+ || CONTAINS_PLACEHOLDER_P (*expr_p))
+ return;
+
+ gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
+}
+
+#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. We must allow this in order to
+ properly represent assigning the address of an array in C into
+ pointer to the element 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 and in that of any nested functions.
+ It would seem we don't have to do this for nested functions because
+ they are supposed to be output and then the outer function gimplified
+ first, but the g++ front end doesn't always do it that way. */
+ unshare_body (body_p, fndecl);
+ unvisit_body (body_p, fndecl);
+
+ /* 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 (!body)
+ body = alloc_stmt_list ();
+ else if (TREE_CODE (body) == STATEMENT_LIST)
+ {
+ tree t = expr_only (*body_p);
+ if (t)
+ body = t;
+ }
+
+ /* If there isn't an outer BIND_EXPR, add one. */
+ 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_force (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/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/java-gimplify.c b/gcc/java/java-gimplify.c
new file mode 100644
index 00000000000..766995e8254
--- /dev/null
+++ b/gcc/java/java-gimplify.c
@@ -0,0 +1,282 @@
+/* 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 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;
+
+ /* 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;
+}
+
+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;
+
+ /* The TREE_USED flag on a block determines whether the debug ouput
+ routines generate info for the variables in that block. */
+ TREE_USED (block) = 1;
+
+ 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, NULL_TREE);
+ tree assignment = build (MODIFY_EXPR, element_type,
+ build (ARRAY_REF, element_type, lhs,
+ build_int_2 (index++, 0),
+ NULL_TREE, NULL_TREE),
+ 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/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/libgcc-darwin.ver b/gcc/libgcc-darwin.ver
new file mode 100644
index 00000000000..0e9f95db734
--- /dev/null
+++ b/gcc/libgcc-darwin.ver
@@ -0,0 +1,218 @@
+GCC_3.0 {
+ # libgcc1 integer symbols
+ ___absvsi2
+ ___addvsi3
+ ___ashlsi3
+ ___ashrsi3
+ ___divsi3
+ ___lshrsi3
+ ___modsi3
+ ___mulsi3
+ ___mulvsi3
+ ___negvsi2
+ ___subvsi3
+ ___udivsi3
+ ___umodsi3
+
+ # libgcc1 floating point symbols
+ ___addsf3
+ ___adddf3
+ ___addxf3
+ ___addtf3
+ ___divsf3
+ ___divdf3
+ ___divxf3
+ ___divtf3
+ ___eqsf2
+ ___eqdf2
+ ___eqxf2
+ ___eqtf2
+ ___extenddfxf2
+ ___extenddftf2
+ ___extendsfdf2
+ ___extendsfxf2
+ ___extendsftf2
+ ___fixsfsi
+ ___fixdfsi
+ ___fixxfsi
+ ___fixtfsi
+ ___floatsisf
+ ___floatsidf
+ ___floatsixf
+ ___floatsitf
+ ___gesf2
+ ___gedf2
+ ___gexf2
+ ___getf2
+ ___gtsf2
+ ___gtdf2
+ ___gtxf2
+ ___gttf2
+ ___lesf2
+ ___ledf2
+ ___lexf2
+ ___letf2
+ ___ltsf2
+ ___ltdf2
+ ___ltxf2
+ ___lttf2
+ ___mulsf3
+ ___muldf3
+ ___mulxf3
+ ___multf3
+ ___negsf2
+ ___negdf2
+ ___negxf2
+ ___negtf2
+ ___nesf2
+ ___nedf2
+ ___nexf2
+ ___netf2
+ ___subsf3
+ ___subdf3
+ ___subxf3
+ ___subtf3
+ ___truncdfsf2
+ ___truncxfsf2
+ ___trunctfsf2
+ ___truncxfdf2
+ ___trunctfdf2
+
+ # libgcc2 DImode arithmetic (for 32-bit targets).
+ ___absvdi2
+ ___addvdi3
+ ___ashldi3
+ ___ashrdi3
+ ___cmpdi2
+ ___divdi3
+ ___ffsdi2
+ ___fixdfdi
+ ___fixsfdi
+ ___fixtfdi
+ ___fixxfdi
+ ___fixunsdfdi
+ ___fixunsdfsi
+ ___fixunssfsi
+ ___fixunssfdi
+ ___fixunstfdi
+ ___fixunstfsi
+ ___fixunsxfdi
+ ___fixunsxfsi
+ ___floatdidf
+ ___floatdisf
+ ___floatdixf
+ ___floatditf
+ ___lshrdi3
+ ___moddi3
+ ___muldi3
+ ___mulvdi3
+ ___negdi2
+ ___negvdi2
+ ___subvdi3
+ ___ucmpdi2
+ ___udivdi3
+ ___udivmoddi4
+ ___umoddi3
+
+ # libgcc2 TImode arithmetic (for 64-bit targets).
+ ___ashlti3
+ ___ashrti3
+ ___cmpti2
+ ___divti3
+ ___ffsti2
+ ___fixdfti
+ ___fixsfti
+ ___fixtfti
+ ___fixxfti
+ ___lshrti3
+ ___modti3
+ ___multi3
+ ___negti2
+ ___ucmpti2
+ ___udivmodti4
+ ___udivti3
+ ___umodti3
+ ___fixunsdfti
+ ___fixunssfti
+ ___fixunstfti
+ ___fixunsxfti
+ ___floattidf
+ ___floattisf
+ ___floattixf
+ ___floattitf
+
+ # Used to deal with trampoline initialization on some platforms
+ ___clear_cache
+
+ # EH symbols
+ __Unwind_DeleteException
+ __Unwind_Find_FDE
+ __Unwind_ForcedUnwind
+ __Unwind_GetGR
+ __Unwind_GetIP
+ __Unwind_GetLanguageSpecificData
+ __Unwind_GetRegionStart
+ __Unwind_GetTextRelBase
+ __Unwind_GetDataRelBase
+ __Unwind_RaiseException
+ __Unwind_Resume
+ __Unwind_SetGR
+ __Unwind_SetIP
+ ___deregister_frame
+ ___deregister_frame_info
+ ___deregister_frame_info_bases
+ ___register_frame
+ ___register_frame_info
+ ___register_frame_info_bases
+ ___register_frame_info_table
+ ___register_frame_info_table_bases
+ ___register_frame_table
+
+ # SjLj EH symbols
+ __Unwind_SjLj_Register
+ __Unwind_SjLj_Unregister
+ __Unwind_SjLj_RaiseException
+ __Unwind_SjLj_ForcedUnwind
+ __Unwind_SjLj_Resume
+}
+
+%inherit GCC_3.3 GCC_3.0
+GCC_3.3 {
+ __Unwind_FindEnclosingFunction
+ __Unwind_GetCFA
+ __Unwind_Backtrace
+ __Unwind_Resume_or_Rethrow
+ __Unwind_SjLj_Resume_or_Rethrow
+}
+
+%inherit GCC_3.3.1 GCC_3.3
+GCC_3.3.1 {
+ __gcc_personality_sj0
+ __gcc_personality_v0
+}
+
+%inherit GCC_3.3.2 GCC_3.3.1
+GCC_3.3.2 {
+}
+%inherit GCC_3.3.4 GCC_3.3.2
+GCC_3.3.4 {
+ __unorddf2
+ __unordsf2
+}
+
+%inherit GCC_3.4 GCC_3.3.4
+GCC_3.4 {
+ # bit scanning and counting built-ins
+ ___clzsi2
+ ___clzdi2
+ ___clzti2
+ ___ctzsi2
+ ___ctzdi2
+ ___ctzti2
+ ___popcountsi2
+ ___popcountdi2
+ ___popcountti2
+ ___paritysi2
+ ___paritydi2
+ ___parityti2
+}
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
new file mode 100644
index 00000000000..d8d3edf500e
--- /dev/null
+++ b/gcc/loop-doloop.c
@@ -0,0 +1,560 @@
+/* Perform doloop optimizations
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
+
+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 "rtl.h"
+#include "flags.h"
+#include "expr.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "toplev.h"
+#include "tm_p.h"
+#include "cfgloop.h"
+#include "output.h"
+#include "params.h"
+
+/* This module is used to modify loops with a determinable number of
+ iterations to use special low-overhead looping instructions.
+
+ It first validates whether the loop is well behaved and has a
+ determinable number of iterations (either at compile or run-time).
+ It then modifies the loop to use a low-overhead looping pattern as
+ follows:
+
+ 1. A pseudo register is allocated as the loop iteration counter.
+
+ 2. The number of loop iterations is calculated and is stored
+ in the loop counter.
+
+ 3. At the end of the loop, the jump insn is replaced by the
+ doloop_end pattern. The compare must remain because it might be
+ used elsewhere. If the loop-variable or condition register are
+ used elsewhere, they will be eliminated by flow.
+
+ 4. An optional doloop_begin pattern is inserted at the top of the
+ loop.
+
+ TODO The optimization should only performed when either the biv used for exit
+ condition is unused at all except for the exit test, or if we do not have to
+ change its value, since otherwise we have to add a new induction variable,
+ which usually will not pay up (unless the cost of the doloop pattern is
+ somehow extremely lower than the cost of compare & jump, or unless the bct
+ register cannot be used for anything else but doloop -- ??? detect these
+ cases). */
+
+#ifdef HAVE_doloop_end
+
+/* Return the loop termination condition for PATTERN or zero
+ if it is not a decrement and branch jump insn. */
+
+static rtx
+doloop_condition_get (rtx pattern)
+{
+ rtx cmp;
+ rtx inc;
+ rtx reg;
+ rtx condition;
+
+ /* The canonical doloop pattern we expect is:
+
+ (parallel [(set (pc) (if_then_else (condition)
+ (label_ref (label))
+ (pc)))
+ (set (reg) (plus (reg) (const_int -1)))
+ (additional clobbers and uses)])
+
+ Some machines (IA-64) make the decrement conditional on
+ the condition as well, so we don't bother verifying the
+ actual decrement. In summary, the branch must be the
+ first entry of the parallel (also required by jump.c),
+ and the second entry of the parallel must be a set of
+ the loop counter register. */
+
+ if (GET_CODE (pattern) != PARALLEL)
+ return 0;
+
+ cmp = XVECEXP (pattern, 0, 0);
+ inc = XVECEXP (pattern, 0, 1);
+
+ /* Check for (set (reg) (something)). */
+ if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
+ return 0;
+
+ /* Extract loop counter register. */
+ reg = SET_DEST (inc);
+
+ /* Check for (set (pc) (if_then_else (condition)
+ (label_ref (label))
+ (pc))). */
+ if (GET_CODE (cmp) != SET
+ || SET_DEST (cmp) != pc_rtx
+ || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
+ || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
+ || XEXP (SET_SRC (cmp), 2) != pc_rtx)
+ return 0;
+
+ /* Extract loop termination condition. */
+ condition = XEXP (SET_SRC (cmp), 0);
+
+ if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
+ || GET_CODE (XEXP (condition, 1)) != CONST_INT)
+ return 0;
+
+ if (XEXP (condition, 0) == reg)
+ return condition;
+
+ if (GET_CODE (XEXP (condition, 0)) == PLUS
+ && XEXP (XEXP (condition, 0), 0) == reg)
+ return condition;
+
+ /* ??? If a machine uses a funny comparison, we could return a
+ canonicalized form here. */
+
+ return 0;
+}
+
+/* Return nonzero if the loop specified by LOOP is suitable for
+ the use of special low-overhead looping instructions. DESC
+ describes the number of iterations of the loop. */
+
+static bool
+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
+ || desc->assumptions
+ || desc->infinite)
+ {
+ /* There are some cases that would require a special attention.
+ For example if the comparison is LEU and the comparison value
+ is UINT_MAX then the loop will not terminate. Similarly, if the
+ comparison code is GEU and the comparison value is 0, the
+ loop will not terminate.
+
+ If the absolute increment is not 1, the loop can be infinite
+ even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2)
+
+ ??? We could compute these conditions at run-time and have a
+ additional jump around the loop to ensure an infinite loop.
+ However, it is very unlikely that this is the intended
+ behavior of the loop and checking for these rare boundary
+ conditions would pessimize all other code.
+
+ If the loop is executed only a few times an extra check to
+ restart the loop could use up most of the benefits of using a
+ count register loop. Note however, that normally, this
+ restart branch would never execute, so it could be predicted
+ well by the CPU. We should generate the pessimistic code by
+ default, and have an option, e.g. -funsafe-loops that would
+ enable count-register loops in this case. */
+ if (dump_file)
+ fprintf (dump_file, "Doloop: Possible infinite iteration case.\n");
+ result = false;
+ goto cleanup;
+ }
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ bb = body[i];
+
+ for (insn = BB_HEAD (bb);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ /* A called function may clobber any special registers required for
+ low-overhead looping. */
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Doloop: Function call in loop.\n");
+ result = false;
+ goto cleanup;
+ }
+
+ /* Some targets (eg, PPC) use the count register for branch on table
+ instructions. ??? This should be a target specific check. */
+ if (GET_CODE (insn) == JUMP_INSN
+ && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_VEC))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Doloop: Computed branch in the loop.\n");
+ result = false;
+ goto cleanup;
+ }
+ }
+ }
+ result = true;
+
+cleanup:
+ free (body);
+
+ return result;
+}
+
+/* Adds test of COND jumping to DEST to the end of BB. */
+
+static void
+add_test (rtx cond, basic_block bb, basic_block dest)
+{
+ rtx seq, jump, label;
+ enum machine_mode mode;
+ rtx op0 = XEXP (cond, 0), op1 = XEXP (cond, 1);
+ enum rtx_code code = GET_CODE (cond);
+
+ mode = GET_MODE (XEXP (cond, 0));
+ if (mode == VOIDmode)
+ mode = GET_MODE (XEXP (cond, 1));
+
+ start_sequence ();
+ op0 = force_operand (op0, NULL_RTX);
+ op1 = force_operand (op1, NULL_RTX);
+ label = block_label (dest);
+ do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label);
+
+ jump = get_last_insn ();
+ JUMP_LABEL (jump) = label;
+
+ /* The jump is supposed to handle an unlikely special case. */
+ REG_NOTES (jump)
+ = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ const0_rtx, REG_NOTES (jump));
+
+ LABEL_NUSES (label)++;
+
+ seq = get_insns ();
+ end_sequence ();
+ emit_insn_after (seq, BB_END (bb));
+}
+
+/* Modify the loop to use the low-overhead looping insn where LOOP
+ describes the loop, DESC describes the number of iterations of the
+ loop, and DOLOOP_INSN is the low-overhead looping insn to emit at the
+ end of the loop. CONDITION is the condition separated from the
+ DOLOOP_SEQ. */
+
+static void
+doloop_modify (struct loop *loop, struct niter_desc *desc,
+ rtx doloop_seq, rtx condition)
+{
+ rtx counter_reg;
+ rtx count, tmp, noloop = NULL_RTX;
+ rtx sequence;
+ rtx jump_insn;
+ rtx jump_label;
+ int nonneg = 0, irr;
+ bool increment_count;
+ basic_block loop_end = desc->out_edge->src;
+
+ jump_insn = BB_END (loop_end);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Doloop: Inserting doloop pattern (");
+ if (desc->const_iter)
+ fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, desc->niter);
+ else
+ fputs ("runtime", dump_file);
+ fputs (" iterations).\n", dump_file);
+ }
+
+ /* Discard original jump to continue loop. The original compare
+ result may still be live, so it cannot be discarded explicitly. */
+ delete_insn (jump_insn);
+
+ counter_reg = XEXP (condition, 0);
+ if (GET_CODE (counter_reg) == PLUS)
+ counter_reg = XEXP (counter_reg, 0);
+
+ count = desc->niter_expr;
+ increment_count = false;
+ switch (GET_CODE (condition))
+ {
+ case NE:
+ /* Currently only NE tests against zero and one are supported. */
+ if (XEXP (condition, 1) == const1_rtx)
+ {
+ increment_count = true;
+ noloop = const1_rtx;
+ }
+ else if (XEXP (condition, 1) == const0_rtx)
+ noloop = const0_rtx;
+ else
+ abort ();
+ break;
+
+ case GE:
+ /* Currently only GE tests against zero are supported. */
+ if (XEXP (condition, 1) != const0_rtx)
+ abort ();
+
+ noloop = constm1_rtx;
+
+ /* The iteration count does not need incrementing for a GE test. */
+ increment_count = false;
+
+ /* Determine if the iteration counter will be non-negative.
+ Note that the maximum value loaded is iterations_max - 1. */
+ if (desc->niter_max
+ <= ((unsigned HOST_WIDEST_INT) 1
+ << (GET_MODE_BITSIZE (GET_MODE (counter_reg)) - 1)))
+ nonneg = 1;
+ break;
+
+ /* Abort if an invalid doloop pattern has been generated. */
+ default:
+ abort ();
+ }
+
+ if (increment_count)
+ count = simplify_gen_binary (PLUS, desc->mode, count, const1_rtx);
+
+ /* Insert initialization of the count register into the loop header. */
+ start_sequence ();
+ tmp = force_operand (count, counter_reg);
+ convert_move (counter_reg, tmp, 1);
+ sequence = get_insns ();
+ end_sequence ();
+ emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src));
+
+ if (desc->noloop_assumptions)
+ {
+ rtx ass = desc->noloop_assumptions;
+ basic_block preheader = loop_preheader_edge (loop)->src;
+ basic_block set_zero
+ = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ basic_block new_preheader
+ = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ basic_block bb;
+ edge te;
+ gcov_type cnt;
+
+ /* Expand the condition testing the assumptions and if it does not pass,
+ reset the count register to 0. */
+ add_test (XEXP (ass, 0), preheader, set_zero);
+ preheader->succ->flags &= ~EDGE_FALLTHRU;
+ cnt = preheader->succ->count;
+ preheader->succ->probability = 0;
+ preheader->succ->count = 0;
+ irr = preheader->succ->flags & EDGE_IRREDUCIBLE_LOOP;
+ te = make_edge (preheader, new_preheader, EDGE_FALLTHRU | irr);
+ te->probability = REG_BR_PROB_BASE;
+ te->count = cnt;
+ set_immediate_dominator (CDI_DOMINATORS, new_preheader, preheader);
+
+ set_zero->count = 0;
+ set_zero->frequency = 0;
+
+ for (ass = XEXP (ass, 1); ass; ass = XEXP (ass, 1))
+ {
+ bb = loop_split_edge_with (te, NULL_RTX);
+ te = bb->succ;
+ add_test (XEXP (ass, 0), bb, set_zero);
+ make_edge (bb, set_zero, irr);
+ }
+
+ start_sequence ();
+ convert_move (counter_reg, noloop, 0);
+ sequence = get_insns ();
+ end_sequence ();
+ emit_insn_after (sequence, BB_END (set_zero));
+ }
+
+ /* Some targets (eg, C4x) need to initialize special looping
+ registers. */
+#ifdef HAVE_doloop_begin
+ {
+ rtx init;
+ unsigned level = get_loop_level (loop) + 1;
+ init = gen_doloop_begin (counter_reg,
+ desc->const_iter ? desc->niter_expr : const0_rtx,
+ desc->niter_max,
+ GEN_INT (level));
+ if (init)
+ {
+ start_sequence ();
+ emit_insn (init);
+ sequence = get_insns ();
+ end_sequence ();
+ emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src));
+ }
+ }
+#endif
+
+ /* Insert the new low-overhead looping insn. */
+ emit_jump_insn_after (doloop_seq, BB_END (loop_end));
+ jump_insn = BB_END (loop_end);
+ jump_label = block_label (desc->in_edge->dest);
+ JUMP_LABEL (jump_insn) = jump_label;
+ LABEL_NUSES (jump_label)++;
+
+ /* Ensure the right fallthru edge is marked, for case we have reversed
+ the condition. */
+ desc->in_edge->flags &= ~EDGE_FALLTHRU;
+ desc->out_edge->flags |= EDGE_FALLTHRU;
+
+ /* Add a REG_NONNEG note if the actual or estimated maximum number
+ of iterations is non-negative. */
+ if (nonneg)
+ {
+ REG_NOTES (jump_insn)
+ = gen_rtx_EXPR_LIST (REG_NONNEG, NULL_RTX, REG_NOTES (jump_insn));
+ }
+}
+
+/* Process loop described by LOOP validating that the loop is suitable for
+ conversion to use a low overhead looping instruction, replacing the jump
+ insn where suitable. Returns true if the loop was successfully
+ modified. */
+
+static bool
+doloop_optimize (struct loop *loop)
+{
+ enum machine_mode mode;
+ rtx doloop_seq, doloop_pat, doloop_reg;
+ rtx iterations;
+ rtx iterations_max;
+ rtx start_label;
+ rtx condition;
+ unsigned level, est_niter;
+ struct niter_desc *desc;
+
+ if (dump_file)
+ fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
+
+ iv_analysis_loop_init (loop);
+
+ /* Find the simple exit of a LOOP. */
+ desc = get_simple_loop_desc (loop);
+
+ /* Check that loop is a candidate for a low-overhead looping insn. */
+ if (!doloop_valid_p (loop, desc))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Doloop: The loop is not suitable.\n");
+ return false;
+ }
+ mode = desc->mode;
+
+ est_niter = 3;
+ if (desc->const_iter)
+ est_niter = desc->niter;
+ /* If the estimate on number of iterations is reliable (comes from profile
+ feedback), use it. Do not use it normally, since the expected number
+ of iterations of an unrolled loop is 2. */
+ if (loop->header->count)
+ est_niter = expected_loop_iterations (loop);
+
+ if (est_niter < 3)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Doloop: Too few iterations (%u) to be profitable.\n",
+ est_niter);
+ return false;
+ }
+
+ iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
+ iterations_max = GEN_INT (desc->niter_max);
+ level = get_loop_level (loop) + 1;
+
+ /* Generate looping insn. If the pattern FAILs then give up trying
+ to modify the loop since there is some aspect the back-end does
+ not like. */
+ start_label = block_label (desc->in_edge->dest);
+ doloop_reg = gen_reg_rtx (mode);
+ doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
+ GEN_INT (level), start_label);
+ if (! doloop_seq && mode != word_mode)
+ {
+ PUT_MODE (doloop_reg, word_mode);
+ doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
+ GEN_INT (level), start_label);
+ }
+ if (! doloop_seq)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Doloop: Target unwilling to use doloop pattern!\n");
+ return false;
+ }
+
+ /* If multiple instructions were created, the last must be the
+ jump instruction. Also, a raw define_insn may yield a plain
+ pattern. */
+ doloop_pat = doloop_seq;
+ if (INSN_P (doloop_pat))
+ {
+ while (NEXT_INSN (doloop_pat) != NULL_RTX)
+ doloop_pat = NEXT_INSN (doloop_pat);
+ if (GET_CODE (doloop_pat) == JUMP_INSN)
+ doloop_pat = PATTERN (doloop_pat);
+ else
+ doloop_pat = NULL_RTX;
+ }
+
+ if (! doloop_pat
+ || ! (condition = doloop_condition_get (doloop_pat)))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Doloop: Unrecognizable doloop pattern!\n");
+ return false;
+ }
+
+ doloop_modify (loop, desc, doloop_seq, condition);
+ return true;
+}
+
+/* This is the main entry point. Process all LOOPS using doloop_optimize. */
+
+void
+doloop_optimize_loops (struct loops *loops)
+{
+ unsigned i;
+ struct loop *loop;
+
+ for (i = 1; i < loops->num; i++)
+ {
+ loop = loops->parray[i];
+ if (!loop)
+ continue;
+
+ doloop_optimize (loop);
+ }
+
+ iv_analysis_done ();
+
+#ifdef ENABLE_CHECKING
+ verify_dominators (CDI_DOMINATORS);
+ verify_loop_structure (loops);
+#endif
+}
+#endif /* HAVE_doloop_end */
+
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
new file mode 100644
index 00000000000..f839ae51635
--- /dev/null
+++ b/gcc/loop-invariant.c
@@ -0,0 +1,933 @@
+/* Rtl-level loop invariant motion.
+ 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. */
+
+/* This implements the loop invariant motion pass. It is very simple
+ (no calls, libcalls, etc.). This should be sufficient to cleanup things like
+ address arithmetics -- other more complicated invariants should be
+ eliminated on tree level either in tree-ssa-loop-im.c or in tree-ssa-pre.c.
+
+ We proceed loop by loop -- it is simpler than trying to handle things
+ globally and should not lose much. First we inspect all sets inside loop
+ and create a dependency graph on insns (saying "to move this insn, you must
+ also move the following insns").
+
+ We then need to determine what to move. We estimate the number of registers
+ used and move as many invariants as possible while we still have enough free
+ registers. We prefer the expensive invariants.
+
+ Then we move the selected invariants out of the loop, creating a new
+ temporaries for them if necessary. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "expr.h"
+#include "output.h"
+#include "function.h"
+#include "flags.h"
+#include "df.h"
+
+/* The data stored for the loop. */
+
+struct loop_data
+{
+ struct loop *outermost_exit; /* The outermost exit of the loop. */
+ bool has_call; /* True if the loop contains a call. */
+};
+
+#define LOOP_DATA(LOOP) ((struct loop_data *) (LOOP)->aux)
+
+/* The description of an use. */
+
+struct use
+{
+ rtx *pos; /* Position of the use. */
+ rtx insn; /* The insn in that the use occurs. */
+
+ struct use *next; /* Next use in the list. */
+};
+
+/* The description of a def. */
+
+struct def
+{
+ struct use *uses; /* The list of uses that are uniquely reached
+ by it. */
+ unsigned n_uses; /* Number of such uses. */
+ unsigned invno; /* The corresponding invariant. */
+};
+
+/* The data stored for each invariant. */
+
+struct invariant
+{
+ /* The number of the invariant. */
+ unsigned invno;
+
+ /* Whether we already processed the invariant. */
+ bool processed;
+
+ /* The definition of the invariant. */
+ struct def *def;
+
+ /* The insn in that it is defined. */
+ rtx insn;
+
+ /* Whether it is always executed. */
+ bool always_executed;
+
+ /* Whether to move the invariant. */
+ bool move;
+
+ /* Cost if the invariant. */
+ unsigned cost;
+
+ /* The invariants it depends on. */
+ bitmap depends_on;
+
+ /* Used for detecting already visited invariants during determining
+ costs of movements. */
+ unsigned stamp;
+};
+
+/* The actual stamp for marking already visited invariants during determining
+ costs of movements. */
+
+static unsigned actual_stamp;
+
+/* The invariants. */
+
+static varray_type invariants;
+
+/* Test for possibility of invariantness of X. */
+
+static bool
+check_maybe_invariant (rtx x)
+{
+ enum rtx_code code = GET_CODE (x);
+ int i, j;
+ const char *fmt;
+
+ switch (code)
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case SYMBOL_REF:
+ case CONST:
+ case LABEL_REF:
+ return true;
+
+ case PC:
+ case CC0:
+ case UNSPEC_VOLATILE:
+ case CALL:
+ return false;
+
+ case REG:
+ return true;
+
+ case MEM:
+ /* Load/store motion is done elsewhere. ??? Perhaps also add it here?
+ It should not be hard, and might be faster than "elsewhere". */
+
+ /* Just handle the most trivial case where we load from an unchanging
+ location (most importantly, pic tables). */
+ if (RTX_UNCHANGING_P (x))
+ break;
+
+ return false;
+
+ case ASM_OPERANDS:
+ /* Don't mess with insns declared volatile. */
+ if (MEM_VOLATILE_P (x))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ if (!check_maybe_invariant (XEXP (x, i)))
+ return false;
+ }
+ else if (fmt[i] == 'E')
+ {
+ for (j = 0; j < XVECLEN (x, i); j++)
+ if (!check_maybe_invariant (XVECEXP (x, i, j)))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Determines the basic blocks inside LOOP that are always executed and
+ stores their bitmap to ALWAYS_REACHED. MAY_EXIT is a bitmap of
+ basic blocks that may either exit the loop, or contain the call that
+ does not have to return. BODY is body of the loop obtained by
+ get_loop_body_in_dom_order. */
+
+static void
+compute_always_reached (struct loop *loop, basic_block *body,
+ bitmap may_exit, bitmap always_reached)
+{
+ unsigned i;
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ if (dominated_by_p (CDI_DOMINATORS, loop->latch, body[i]))
+ bitmap_set_bit (always_reached, i);
+
+ if (bitmap_bit_p (may_exit, i))
+ return;
+ }
+}
+
+/* Finds exits out of the LOOP with body BODY. Marks blocks in that we may
+ exit the loop by cfg edge to HAS_EXIT and MAY_EXIT. In MAY_EXIT
+ additionally mark blocks that may exit due to a call. */
+
+static void
+find_exits (struct loop *loop, basic_block *body,
+ bitmap may_exit, bitmap has_exit)
+{
+ unsigned i;
+ edge e;
+ struct loop *outermost_exit = loop, *aexit;
+ bool has_call = false;
+ rtx insn;
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ if (body[i]->loop_father == loop)
+ {
+ FOR_BB_INSNS (body[i], insn)
+ {
+ if (GET_CODE (insn) == CALL_INSN
+ && !CONST_OR_PURE_CALL_P (insn))
+ {
+ has_call = true;
+ bitmap_set_bit (may_exit, i);
+ break;
+ }
+ }
+
+ for (e = body[i]->succ; e; e = e->succ_next)
+ {
+ if (flow_bb_inside_loop_p (loop, e->dest))
+ continue;
+
+ bitmap_set_bit (may_exit, i);
+ bitmap_set_bit (has_exit, i);
+ outermost_exit = find_common_loop (outermost_exit,
+ e->dest->loop_father);
+ }
+ continue;
+ }
+
+ /* Use the data stored for the subloop to decide whether we may exit
+ through it. It is sufficient to do this for header of the loop,
+ as other basic blocks inside it must be dominated by it. */
+ if (body[i]->loop_father->header != body[i])
+ continue;
+
+ if (LOOP_DATA (body[i]->loop_father)->has_call)
+ {
+ has_call = true;
+ bitmap_set_bit (may_exit, i);
+ }
+ aexit = LOOP_DATA (body[i]->loop_father)->outermost_exit;
+ if (aexit != loop)
+ {
+ bitmap_set_bit (may_exit, i);
+ bitmap_set_bit (has_exit, i);
+
+ if (flow_loop_nested_p (aexit, outermost_exit))
+ outermost_exit = aexit;
+ }
+ }
+
+ loop->aux = xcalloc (1, sizeof (struct loop_data));
+ LOOP_DATA (loop)->outermost_exit = outermost_exit;
+ LOOP_DATA (loop)->has_call = has_call;
+}
+
+/* Check whether we may assign a value to X from a register. */
+
+static bool
+may_assign_reg_p (rtx x)
+{
+ return can_copy_p (GET_MODE (x));
+}
+
+/* Finds definitions that may correspond to invariants in LOOP with body BODY.
+ DF is the dataflow object. */
+
+static void
+find_defs (struct loop *loop, basic_block *body, struct df *df)
+{
+ unsigned i;
+ bitmap blocks = BITMAP_XMALLOC ();
+
+ for (i = 0; i < loop->num_nodes; i++)
+ bitmap_set_bit (blocks, body[i]->index);
+
+ df_analyze_subcfg (df, blocks, DF_UD_CHAIN | DF_HARD_REGS | DF_EQUIV_NOTES);
+ BITMAP_XFREE (blocks);
+}
+
+/* Creates a new invariant for definition DEF in INSN, depending on invariants
+ in DEPENDS_ON. ALWAYS_EXECUTED is true if the insn is always executed,
+ unless the program ends due to a function call. */
+
+static void
+create_new_invariant (struct def *def, rtx insn, bitmap depends_on,
+ bool always_executed)
+{
+ struct invariant *inv = xmalloc (sizeof (struct invariant));
+ rtx set = single_set (insn);
+
+ inv->def = def;
+ inv->always_executed = always_executed;
+ inv->depends_on = depends_on;
+
+ /* If the set is simple, usually by moving it we move the whole store out of
+ the loop. Otherwise we save only cost of the computation. */
+ if (def)
+ inv->cost = rtx_cost (set, SET);
+ else
+ inv->cost = rtx_cost (SET_SRC (set), SET);
+
+ inv->move = false;
+ inv->processed = false;
+ inv->stamp = 0;
+ inv->insn = insn;
+
+ inv->invno = VARRAY_ACTIVE_SIZE (invariants);
+ if (def)
+ def->invno = inv->invno;
+ VARRAY_PUSH_GENERIC_PTR_NOGC (invariants, inv);
+
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "Set in insn %d is invariant (%d), cost %d, depends on ",
+ INSN_UID (insn), inv->invno, inv->cost);
+ dump_bitmap (dump_file, inv->depends_on);
+ }
+}
+
+/* Record USE at DEF. */
+
+static void
+record_use (struct def *def, rtx *use, rtx insn)
+{
+ struct use *u = xmalloc (sizeof (struct use));
+
+ if (GET_CODE (*use) == SUBREG)
+ use = &SUBREG_REG (*use);
+ if (!REG_P (*use))
+ abort ();
+
+ u->pos = use;
+ u->insn = insn;
+ u->next = def->uses;
+ def->uses = u;
+ def->n_uses++;
+}
+
+/* Finds the invariants INSN depends on and store them to the DEPENDS_ON
+ bitmap. DF is the dataflow object. */
+
+static bool
+check_dependencies (rtx insn, struct df *df, bitmap depends_on)
+{
+ struct df_link *uses, *defs;
+ struct ref *use, *def;
+ basic_block bb = BLOCK_FOR_INSN (insn), def_bb;
+ struct def *def_data;
+
+ for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
+ {
+ use = uses->ref;
+
+ defs = DF_REF_CHAIN (use);
+ if (!defs)
+ continue;
+
+ if (defs->next)
+ return false;
+
+ def = defs->ref;
+ def_data = DF_REF_DATA (def);
+ if (!def_data)
+ return false;
+
+ def_bb = DF_REF_BB (def);
+ if (!dominated_by_p (CDI_DOMINATORS, bb, def_bb))
+ return false;
+
+ bitmap_set_bit (depends_on, def_data->invno);
+ }
+
+ return true;
+}
+
+/* Finds invariant in INSN. ALWAYS_REACHED is true if the insn is always
+ executed. ALWAYS_EXECUTED is true if the insn is always executed,
+ unless the program ends due to a function call. DF is the dataflow
+ object. */
+
+static void
+find_invariant_insn (rtx insn, bool always_reached, bool always_executed,
+ struct df *df)
+{
+ struct ref *ref;
+ struct def *def;
+ bitmap depends_on;
+ rtx set, dest;
+ bool simple = true;
+
+ /* Until we get rid of LIBCALLS. */
+ if (find_reg_note (insn, REG_RETVAL, NULL_RTX)
+ || find_reg_note (insn, REG_LIBCALL, NULL_RTX)
+ || find_reg_note (insn, REG_NO_CONFLICT, NULL_RTX))
+ return;
+
+ set = single_set (insn);
+ if (!set)
+ return;
+ dest = SET_DEST (set);
+
+ if (GET_CODE (dest) != REG
+ || HARD_REGISTER_P (dest))
+ simple = false;
+
+ if (!check_maybe_invariant (SET_SRC (set))
+ || !may_assign_reg_p (SET_DEST (set)))
+ return;
+
+ if (may_trap_p (PATTERN (insn)))
+ {
+ if (!always_reached)
+ return;
+
+ /* Unless the exceptions are handled, the behavior is undefined
+ if the trap occurs. */
+ if (flag_non_call_exceptions)
+ return;
+ }
+
+ depends_on = BITMAP_XMALLOC ();
+ if (!check_dependencies (insn, df, depends_on))
+ {
+ BITMAP_XFREE (depends_on);
+ return;
+ }
+
+ if (simple)
+ {
+ ref = df_find_def (df, insn, dest);
+ def = xcalloc (1, sizeof (struct def));
+ DF_REF_DATA (ref) = def;
+ }
+ else
+ def = NULL;
+
+ create_new_invariant (def, insn, depends_on, always_executed);
+}
+
+/* Record registers used in INSN that have an unique invariant definition.
+ DF is the dataflow object. */
+
+static void
+record_uses (rtx insn, struct df *df)
+{
+ struct df_link *uses, *defs;
+ struct ref *use, *def;
+ basic_block bb = BLOCK_FOR_INSN (insn), def_bb;
+
+ for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
+ {
+ use = uses->ref;
+
+ defs = DF_REF_CHAIN (use);
+ if (!defs || defs->next)
+ continue;
+ def = defs->ref;
+ if (!DF_REF_DATA (def))
+ continue;
+
+ def_bb = DF_REF_BB (def);
+ if (!dominated_by_p (CDI_DOMINATORS, bb, def_bb))
+ continue;
+
+ record_use (DF_REF_DATA (def), DF_REF_LOC (use), DF_REF_INSN (use));
+ }
+}
+
+/* Finds invariants in INSN. ALWAYS_REACHED is true if the insn is always
+ executed. ALWAYS_EXECUTED is true if the insn is always executed,
+ unless the program ends due to a function call. DF is the dataflow
+ object. */
+
+static void
+find_invariants_insn (rtx insn, bool always_reached, bool always_executed,
+ struct df *df)
+{
+ find_invariant_insn (insn, always_reached, always_executed, df);
+ record_uses (insn, df);
+}
+
+/* Finds invariants in basic block BB. ALWAYS_REACHED is true if the
+ basic block is always executed. ALWAYS_EXECUTED is true if the basic
+ block is always executed, unless the program ends due to a function
+ call. DF is the dataflow object. */
+
+static void
+find_invariants_bb (basic_block bb, bool always_reached, bool always_executed,
+ struct df *df)
+{
+ rtx insn;
+
+ FOR_BB_INSNS (bb, insn)
+ {
+ if (!INSN_P (insn))
+ continue;
+
+ find_invariants_insn (insn, always_reached, always_executed, df);
+
+ if (always_reached
+ && GET_CODE (insn) == CALL_INSN
+ && !CONST_OR_PURE_CALL_P (insn))
+ always_reached = false;
+ }
+}
+
+/* Finds invariants in LOOP with body BODY. ALWAYS_REACHED is the bitmap of
+ basic blocks in BODY that are always executed. ALWAYS_EXECUTED is the
+ bitmap of basic blocks in BODY that are always executed unless the program
+ ends due to a function call. DF is the dataflow object. */
+
+static void
+find_invariants_body (struct loop *loop, basic_block *body,
+ bitmap always_reached, bitmap always_executed,
+ struct df *df)
+{
+ unsigned i;
+
+ for (i = 0; i < loop->num_nodes; i++)
+ find_invariants_bb (body[i],
+ bitmap_bit_p (always_reached, i),
+ bitmap_bit_p (always_executed, i),
+ df);
+}
+
+/* Finds invariants in LOOP. DF is the dataflow object. */
+
+static void
+find_invariants (struct loop *loop, struct df *df)
+{
+ bitmap may_exit = BITMAP_XMALLOC ();
+ bitmap always_reached = BITMAP_XMALLOC ();
+ bitmap has_exit = BITMAP_XMALLOC ();
+ bitmap always_executed = BITMAP_XMALLOC ();
+ basic_block *body = get_loop_body_in_dom_order (loop);
+
+ find_exits (loop, body, may_exit, has_exit);
+ compute_always_reached (loop, body, may_exit, always_reached);
+ compute_always_reached (loop, body, has_exit, always_executed);
+
+ find_defs (loop, body, df);
+ find_invariants_body (loop, body, always_reached, always_executed, df);
+
+ BITMAP_XFREE (always_reached);
+ BITMAP_XFREE (always_executed);
+ BITMAP_XFREE (may_exit);
+ BITMAP_XFREE (has_exit);
+ free (body);
+}
+
+/* Frees a list of uses USE. */
+
+static void
+free_use_list (struct use *use)
+{
+ struct use *next;
+
+ for (; use; use = next)
+ {
+ next = use->next;
+ free (use);
+ }
+}
+
+/* Calculates cost and number of registers needed for moving invariant INV
+ out of the loop and stores them to *COST and *REGS_NEEDED. */
+
+static void
+get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed)
+{
+ int acomp_cost;
+ unsigned aregs_needed;
+ unsigned depno;
+ struct invariant *dep;
+
+ *comp_cost = 0;
+ *regs_needed = 0;
+ if (inv->move
+ || inv->stamp == actual_stamp)
+ return;
+ inv->stamp = actual_stamp;
+
+ (*regs_needed)++;
+ (*comp_cost) += inv->cost;
+
+ EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno,
+ {
+ dep = VARRAY_GENERIC_PTR_NOGC (invariants, depno);
+
+ get_inv_cost (dep, &acomp_cost, &aregs_needed);
+
+ if (aregs_needed
+ /* We need to check always_executed, since if the original value of
+ the invariant may be preserved, we may need to keep it in a
+ separate register. TODO check whether the register has an
+ use outside of the loop. */
+ && dep->always_executed
+ && !dep->def->uses->next)
+ {
+ /* If this is a single use, after moving the dependency we will not
+ need a new register. */
+ aregs_needed--;
+ }
+
+ (*regs_needed) += aregs_needed;
+ (*comp_cost) += acomp_cost;
+ });
+}
+
+/* Calculates gain for eliminating invariant INV. REGS_USED is the number
+ of registers used in the loop, N_INV_USES is the number of uses of
+ invariants, NEW_REGS is the number of new variables already added due to
+ the invariant motion. The number of registers needed for it is stored in
+ *REGS_NEEDED. */
+
+static int
+gain_for_invariant (struct invariant *inv, unsigned *regs_needed,
+ unsigned new_regs, unsigned regs_used, unsigned n_inv_uses)
+{
+ int comp_cost, size_cost;
+
+ get_inv_cost (inv, &comp_cost, regs_needed);
+ actual_stamp++;
+
+ size_cost = (global_cost_for_size (new_regs + *regs_needed,
+ regs_used, n_inv_uses)
+ - global_cost_for_size (new_regs, regs_used, n_inv_uses));
+
+ return comp_cost - size_cost;
+}
+
+/* Finds invariant with best gain for moving. Returns the gain, stores
+ the invariant in *BEST and number of registers needed for it to
+ *REGS_NEEDED. REGS_USED is the number of registers used in
+ the loop, N_INV_USES is the number of uses of invariants. NEW_REGS
+ is the number of new variables already added due to invariant motion. */
+
+static int
+best_gain_for_invariant (struct invariant **best, unsigned *regs_needed,
+ unsigned new_regs, unsigned regs_used,
+ unsigned n_inv_uses)
+{
+ struct invariant *inv;
+ int gain = 0, again;
+ unsigned aregs_needed, invno;
+
+ for (invno = 0; invno < VARRAY_ACTIVE_SIZE (invariants); invno++)
+ {
+ inv = VARRAY_GENERIC_PTR_NOGC (invariants, invno);
+ if (inv->move)
+ continue;
+
+ again = gain_for_invariant (inv, &aregs_needed,
+ new_regs, regs_used, n_inv_uses);
+ if (again > gain)
+ {
+ gain = again;
+ *best = inv;
+ *regs_needed = aregs_needed;
+ }
+ }
+
+ return gain;
+}
+
+/* Marks invariant INVNO and all its dependencies for moving. */
+
+static void
+set_move_mark (unsigned invno)
+{
+ struct invariant *inv = VARRAY_GENERIC_PTR_NOGC (invariants, invno);
+
+ if (inv->move)
+ return;
+ inv->move = true;
+
+ if (dump_file)
+ fprintf (dump_file, "Decided to move invariant %d\n", invno);
+
+ EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, invno, set_move_mark (invno));
+}
+
+/* Determines which invariants to move. DF is the dataflow object. */
+
+static void
+find_invariants_to_move (struct df *df)
+{
+ unsigned i, regs_used, n_inv_uses, regs_needed = 0, new_regs;
+ struct invariant *inv = NULL;
+
+ if (flag_move_all_movables)
+ {
+ /* This is easy & stupid. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ {
+ inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
+ inv->move = true;
+ }
+ return;
+ }
+
+ if (!VARRAY_ACTIVE_SIZE (invariants))
+ return;
+
+ /* Now something slightly more involved. First estimate the number of used
+ registers. */
+ n_inv_uses = 0;
+
+ /* We do not really do a good job in this estimation; put some initial bound
+ here to stand for induction variables etc. that we do not detect. */
+ regs_used = 2;
+
+ for (i = 0; i < df->n_regs; i++)
+ {
+ if (!DF_REGNO_FIRST_DEF (df, i) && DF_REGNO_LAST_USE (df, i))
+ {
+ /* This is a value that is used but not changed inside loop. */
+ regs_used++;
+ }
+ }
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ {
+ inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
+ if (inv->def)
+ n_inv_uses += inv->def->n_uses;
+ }
+
+ new_regs = 0;
+ while (best_gain_for_invariant (&inv, &regs_needed,
+ new_regs, regs_used, n_inv_uses) > 0)
+ {
+ set_move_mark (inv->invno);
+ new_regs += regs_needed;
+ }
+}
+
+/* Move invariant INVNO out of the LOOP. DF is the dataflow object. */
+
+static void
+move_invariant_reg (struct loop *loop, unsigned invno, struct df *df)
+{
+ struct invariant *inv = VARRAY_GENERIC_PTR_NOGC (invariants, invno);
+ unsigned i;
+ basic_block preheader = loop_preheader_edge (loop)->src;
+ rtx reg, set;
+ struct use *use;
+
+ if (inv->processed)
+ return;
+ inv->processed = true;
+
+ if (inv->depends_on)
+ {
+ EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i,
+ {
+ move_invariant_reg (loop, i, df);
+ });
+ }
+
+ /* Move the set out of the loop. If the set is always executed (we could
+ omit this condition if we know that the register is unused outside of the
+ loop, but it does not seem worth finding out) and it has no uses that
+ would not be dominated by it, we may just move it (TODO). Otherwise we
+ need to create a temporary register. */
+ set = single_set (inv->insn);
+ reg = gen_reg_rtx (GET_MODE (SET_DEST (set)));
+ df_pattern_emit_after (df, gen_move_insn (SET_DEST (set), reg),
+ BLOCK_FOR_INSN (inv->insn), inv->insn);
+ SET_DEST (set) = reg;
+ reorder_insns (inv->insn, inv->insn, BB_END (preheader));
+ df_insn_modify (df, preheader, inv->insn);
+
+ /* Replace the uses we know to be dominated. It saves work for copy
+ propagation, and also it is necessary so that dependent invariants
+ are computed right. */
+ if (inv->def)
+ {
+ for (use = inv->def->uses; use; use = use->next)
+ {
+ *use->pos = reg;
+ df_insn_modify (df, BLOCK_FOR_INSN (use->insn), use->insn);
+ }
+ }
+}
+
+/* Move selected invariant out of the LOOP. Newly created regs are marked
+ in TEMPORARY_REGS. DF is the dataflow object. */
+
+static void
+move_invariants (struct loop *loop, struct df *df)
+{
+ struct invariant *inv;
+ unsigned i;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ {
+ inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
+ if (inv->move)
+ move_invariant_reg (loop, i, df);
+ }
+}
+
+/* Initializes invariant motion data. */
+
+static void
+init_inv_motion_data (void)
+{
+ actual_stamp = 1;
+
+ if (!invariants)
+ VARRAY_GENERIC_PTR_NOGC_INIT (invariants, 100, "invariants");
+}
+
+/* Frees the data allocated by invariant motion. DF is the dataflow
+ object. */
+
+static void
+free_inv_motion_data (struct df *df)
+{
+ unsigned i;
+ struct def *def;
+ struct invariant *inv;
+
+ for (i = 0; i < df->n_defs; i++)
+ {
+ if (!df->defs[i])
+ continue;
+
+ def = DF_REF_DATA (df->defs[i]);
+ if (!def)
+ continue;
+
+ free_use_list (def->uses);
+ free (def);
+ DF_REF_DATA (df->defs[i]) = NULL;
+ }
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ {
+ inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
+ BITMAP_XFREE (inv->depends_on);
+ free (inv);
+ }
+ VARRAY_POP_ALL (invariants);
+}
+
+/* Move the invariants out of the LOOP. DF is the dataflow object. */
+
+static void
+move_single_loop_invariants (struct loop *loop, struct df *df)
+{
+ init_inv_motion_data ();
+
+ find_invariants (loop, df);
+ find_invariants_to_move (df);
+ move_invariants (loop, df);
+
+ free_inv_motion_data (df);
+}
+
+/* Releases the auxiliary data for LOOP. */
+
+static void
+free_loop_data (struct loop *loop)
+{
+ struct loop_data *data = LOOP_DATA (loop);
+
+ free (data);
+ loop->aux = NULL;
+}
+
+/* Move the invariants out of the LOOPS. */
+
+void
+move_loop_invariants (struct loops *loops)
+{
+ struct loop *loop;
+ unsigned i;
+ struct df *df = df_init ();
+
+ /* Process the loops, innermost first. */
+ loop = loops->tree_root;
+ while (loop->inner)
+ loop = loop->inner;
+
+ while (loop != loops->tree_root)
+ {
+ move_single_loop_invariants (loop, df);
+
+ if (loop->next)
+ {
+ loop = loop->next;
+ while (loop->inner)
+ loop = loop->inner;
+ }
+ else
+ loop = loop->outer;
+ }
+
+ for (i = 1; i < loops->num; i++)
+ if (loops->parray[i])
+ free_loop_data (loops->parray[i]);
+
+ df_finish (df);
+}
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
new file mode 100644
index 00000000000..e739a852bce
--- /dev/null
+++ b/gcc/loop-iv.c
@@ -0,0 +1,2584 @@
+/* Rtl-level induction variable analysis.
+ 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. */
+
+/* This is just a very simplistic analysis of induction variables of the loop.
+ The major use is for determining the number of iterations of a loop for
+ loop unrolling, doloop optimization and branch prediction. For this we
+ are only interested in bivs and a fairly limited set of givs that are
+ needed in the exit condition. We also only compute the iv information on
+ demand.
+
+ The interesting registers are determined. A register is interesting if
+
+ -- it is set only in the blocks that dominate the latch of the current loop
+ -- all its sets are simple -- i.e. in the form we understand
+
+ We also number the insns sequentially in each basic block. For a use of the
+ interesting reg, it is now easy to find a reaching definition (there may be
+ only one).
+
+ Induction variable is then simply analyzed by walking the use-def
+ chains.
+
+ Usage:
+
+ iv_analysis_loop_init (loop);
+ insn = iv_get_reaching_def (where, reg);
+ if (iv_analyze (insn, reg, &iv))
+ {
+ ...
+ }
+ iv_analysis_done (); */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "expr.h"
+#include "output.h"
+
+/* The insn information. */
+
+struct insn_info
+{
+ /* Id of the insn. */
+ unsigned luid;
+
+ /* The previous definition of the register defined by the single
+ set in the insn. */
+ rtx prev_def;
+
+ /* The description of the iv. */
+ struct rtx_iv iv;
+};
+
+static struct insn_info *insn_info;
+
+/* The last definition of register. */
+
+static rtx *last_def;
+
+/* The bivs. */
+
+static struct rtx_iv *bivs;
+
+/* Maximal insn number for that there is place in insn_info array. */
+
+static unsigned max_insn_no;
+
+/* Maximal register number for that there is place in bivs and last_def
+ arrays. */
+
+static unsigned max_reg_no;
+
+/* Dumps information about IV to FILE. */
+
+extern void dump_iv_info (FILE *, struct rtx_iv *);
+void
+dump_iv_info (FILE *file, struct rtx_iv *iv)
+{
+ if (!iv->base)
+ {
+ fprintf (file, "not simple");
+ return;
+ }
+
+ if (iv->step == const0_rtx)
+ {
+ fprintf (file, "invariant ");
+ print_rtl (file, iv->base);
+ return;
+ }
+
+ print_rtl (file, iv->base);
+ fprintf (file, " + ");
+ print_rtl (file, iv->step);
+ fprintf (file, " * iteration");
+ fprintf (file, " (in %s)", GET_MODE_NAME (iv->mode));
+
+ if (iv->mode != iv->extend_mode)
+ fprintf (file, " %s to %s",
+ rtx_name[iv->extend],
+ GET_MODE_NAME (iv->extend_mode));
+
+ if (iv->mult != const1_rtx)
+ {
+ fprintf (file, " * ");
+ print_rtl (file, iv->mult);
+ }
+ if (iv->delta != const0_rtx)
+ {
+ fprintf (file, " + ");
+ print_rtl (file, iv->delta);
+ }
+ if (iv->first_special)
+ fprintf (file, " (first special)");
+}
+
+/* Assigns luids to insns in basic block BB. */
+
+static void
+assign_luids (basic_block bb)
+{
+ unsigned i = 0, uid;
+ rtx insn;
+
+ FOR_BB_INSNS (bb, insn)
+ {
+ uid = INSN_UID (insn);
+ insn_info[uid].luid = i++;
+ insn_info[uid].prev_def = NULL_RTX;
+ insn_info[uid].iv.analysed = false;
+ }
+}
+
+/* Generates a subreg to get the least significant part of EXPR (in mode
+ INNER_MODE) to OUTER_MODE. */
+
+static rtx
+lowpart_subreg (enum machine_mode outer_mode, rtx expr,
+ enum machine_mode inner_mode)
+{
+ return simplify_gen_subreg (outer_mode, expr, inner_mode,
+ subreg_lowpart_offset (outer_mode, inner_mode));
+}
+
+/* Checks whether REG is a well-behaved register. */
+
+static bool
+simple_reg_p (rtx reg)
+{
+ unsigned r;
+
+ if (GET_CODE (reg) == SUBREG)
+ {
+ if (!subreg_lowpart_p (reg))
+ return false;
+ reg = SUBREG_REG (reg);
+ }
+
+ if (!REG_P (reg))
+ return false;
+
+ r = REGNO (reg);
+ if (HARD_REGISTER_NUM_P (r))
+ return false;
+
+ if (GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
+ return false;
+
+ if (last_def[r] == const0_rtx)
+ return false;
+
+ return true;
+}
+
+/* Checks whether assignment LHS = RHS is simple enough for us to process. */
+
+static bool
+simple_set_p (rtx lhs, rtx rhs)
+{
+ rtx op0, op1;
+
+ if (!REG_P (lhs)
+ || !simple_reg_p (lhs))
+ return false;
+
+ if (CONSTANT_P (rhs))
+ return true;
+
+ switch (GET_CODE (rhs))
+ {
+ case SUBREG:
+ case REG:
+ return simple_reg_p (rhs);
+
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+ case NEG:
+ return simple_reg_p (XEXP (rhs, 0));
+
+ case PLUS:
+ case MINUS:
+ case MULT:
+ case ASHIFT:
+ op0 = XEXP (rhs, 0);
+ op1 = XEXP (rhs, 1);
+
+ if (!simple_reg_p (op0)
+ && !CONSTANT_P (op0))
+ return false;
+
+ if (!simple_reg_p (op1)
+ && !CONSTANT_P (op1))
+ return false;
+
+ if (GET_CODE (rhs) == MULT
+ && !CONSTANT_P (op0)
+ && !CONSTANT_P (op1))
+ return false;
+
+ if (GET_CODE (rhs) == ASHIFT
+ && CONSTANT_P (op0))
+ return false;
+
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Mark single SET in INSN. */
+
+static rtx
+mark_single_set (rtx insn, rtx set)
+{
+ rtx def = SET_DEST (set), src;
+ unsigned regno, uid;
+
+ src = find_reg_equal_equiv_note (insn);
+ if (src)
+ src = XEXP (src, 0);
+ else
+ src = SET_SRC (set);
+
+ if (!simple_set_p (SET_DEST (set), src))
+ return NULL_RTX;
+
+ regno = REGNO (def);
+ uid = INSN_UID (insn);
+
+ bivs[regno].analysed = false;
+ insn_info[uid].prev_def = last_def[regno];
+ last_def[regno] = insn;
+
+ return def;
+}
+
+/* Invalidate register REG unless it is equal to EXCEPT. */
+
+static void
+kill_sets (rtx reg, rtx by ATTRIBUTE_UNUSED, void *except)
+{
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ if (!REG_P (reg))
+ return;
+ if (reg == except)
+ return;
+
+ last_def[REGNO (reg)] = const0_rtx;
+}
+
+/* Marks sets in basic block BB. If DOM is true, BB dominates the loop
+ latch. */
+
+static void
+mark_sets (basic_block bb, bool dom)
+{
+ rtx insn, set, def;
+
+ FOR_BB_INSNS (bb, insn)
+ {
+ if (!INSN_P (insn))
+ continue;
+
+ if (dom
+ && (set = single_set (insn)))
+ def = mark_single_set (insn, set);
+ else
+ def = NULL_RTX;
+
+ note_stores (PATTERN (insn), kill_sets, def);
+ }
+}
+
+/* Prepare the data for an induction variable analysis of a LOOP. */
+
+void
+iv_analysis_loop_init (struct loop *loop)
+{
+ basic_block *body = get_loop_body_in_dom_order (loop);
+ unsigned b;
+
+ if ((unsigned) get_max_uid () >= max_insn_no)
+ {
+ /* Add some reserve for insns and registers produced in optimizations. */
+ max_insn_no = get_max_uid () + 100;
+ if (insn_info)
+ free (insn_info);
+ insn_info = xmalloc (max_insn_no * sizeof (struct insn_info));
+ }
+
+ if ((unsigned) max_reg_num () >= max_reg_no)
+ {
+ max_reg_no = max_reg_num () + 100;
+ if (last_def)
+ free (last_def);
+ last_def = xmalloc (max_reg_no * sizeof (rtx));
+ if (bivs)
+ free (bivs);
+ bivs = xmalloc (max_reg_no * sizeof (struct rtx_iv));
+ }
+
+ memset (last_def, 0, max_reg_num () * sizeof (rtx));
+
+ for (b = 0; b < loop->num_nodes; b++)
+ {
+ assign_luids (body[b]);
+ mark_sets (body[b], just_once_each_iteration_p (loop, body[b]));
+ }
+
+ free (body);
+}
+
+/* Gets definition of REG reaching the INSN. If REG is not simple, const0_rtx
+ is returned. If INSN is before the first def in the loop, NULL_RTX is
+ returned. */
+
+rtx
+iv_get_reaching_def (rtx insn, rtx reg)
+{
+ unsigned regno, luid, auid;
+ rtx ainsn;
+ basic_block bb, abb;
+
+ if (GET_CODE (reg) == SUBREG)
+ {
+ if (!subreg_lowpart_p (reg))
+ return const0_rtx;
+ reg = SUBREG_REG (reg);
+ }
+ if (!REG_P (reg))
+ return NULL_RTX;
+
+ regno = REGNO (reg);
+ if (!last_def[regno]
+ || last_def[regno] == const0_rtx)
+ return last_def[regno];
+
+ bb = BLOCK_FOR_INSN (insn);
+ luid = insn_info[INSN_UID (insn)].luid;
+
+ ainsn = last_def[regno];
+ while (1)
+ {
+ abb = BLOCK_FOR_INSN (ainsn);
+
+ if (dominated_by_p (CDI_DOMINATORS, bb, abb))
+ break;
+
+ auid = INSN_UID (ainsn);
+ ainsn = insn_info[auid].prev_def;
+
+ if (!ainsn)
+ return NULL_RTX;
+ }
+
+ while (1)
+ {
+ abb = BLOCK_FOR_INSN (ainsn);
+ if (abb != bb)
+ return ainsn;
+
+ auid = INSN_UID (ainsn);
+ if (luid > insn_info[auid].luid)
+ return ainsn;
+
+ ainsn = insn_info[auid].prev_def;
+ if (!ainsn)
+ return NULL_RTX;
+ }
+}
+
+/* Sets IV to invariant CST in MODE. Always returns true (just for
+ consistency with other iv manipulation functions that may fail). */
+
+static bool
+iv_constant (struct rtx_iv *iv, rtx cst, enum machine_mode mode)
+{
+ if (mode == VOIDmode)
+ mode = GET_MODE (cst);
+
+ iv->analysed = true;
+ iv->mode = mode;
+ iv->base = cst;
+ iv->step = const0_rtx;
+ iv->first_special = false;
+ iv->extend = NIL;
+ iv->extend_mode = iv->mode;
+ iv->delta = const0_rtx;
+ iv->mult = const1_rtx;
+
+ return true;
+}
+
+/* Evaluates application of subreg to MODE on IV. */
+
+static bool
+iv_subreg (struct rtx_iv *iv, enum machine_mode mode)
+{
+ if (iv->extend_mode == mode)
+ return true;
+
+ if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (iv->mode))
+ return false;
+
+ iv->extend = NIL;
+ iv->mode = mode;
+
+ iv->base = simplify_gen_binary (PLUS, iv->extend_mode, iv->delta,
+ simplify_gen_binary (MULT, iv->extend_mode,
+ iv->base, iv->mult));
+ iv->step = simplify_gen_binary (MULT, iv->extend_mode, iv->step, iv->mult);
+ iv->mult = const1_rtx;
+ iv->delta = const0_rtx;
+ iv->first_special = false;
+
+ return true;
+}
+
+/* Evaluates application of EXTEND to MODE on IV. */
+
+static bool
+iv_extend (struct rtx_iv *iv, enum rtx_code extend, enum machine_mode mode)
+{
+ if (mode != iv->extend_mode)
+ return false;
+
+ if (iv->extend != NIL
+ && iv->extend != extend)
+ return false;
+
+ iv->extend = extend;
+
+ return true;
+}
+
+/* Evaluates negation of IV. */
+
+static bool
+iv_neg (struct rtx_iv *iv)
+{
+ if (iv->extend == NIL)
+ {
+ iv->base = simplify_gen_unary (NEG, iv->extend_mode,
+ iv->base, iv->extend_mode);
+ iv->step = simplify_gen_unary (NEG, iv->extend_mode,
+ iv->step, iv->extend_mode);
+ }
+ else
+ {
+ iv->delta = simplify_gen_unary (NEG, iv->extend_mode,
+ iv->delta, iv->extend_mode);
+ iv->mult = simplify_gen_unary (NEG, iv->extend_mode,
+ iv->mult, iv->extend_mode);
+ }
+
+ return true;
+}
+
+/* Evaluates addition or subtraction (according to OP) of IV1 to IV0. */
+
+static bool
+iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op)
+{
+ enum machine_mode mode;
+ rtx arg;
+
+ /* Extend the constant to extend_mode of the other operand if necessary. */
+ if (iv0->extend == NIL
+ && iv0->mode == iv0->extend_mode
+ && iv0->step == const0_rtx
+ && GET_MODE_SIZE (iv0->extend_mode) < GET_MODE_SIZE (iv1->extend_mode))
+ {
+ iv0->extend_mode = iv1->extend_mode;
+ iv0->base = simplify_gen_unary (ZERO_EXTEND, iv0->extend_mode,
+ iv0->base, iv0->mode);
+ }
+ if (iv1->extend == NIL
+ && iv1->mode == iv1->extend_mode
+ && iv1->step == const0_rtx
+ && GET_MODE_SIZE (iv1->extend_mode) < GET_MODE_SIZE (iv0->extend_mode))
+ {
+ iv1->extend_mode = iv0->extend_mode;
+ iv1->base = simplify_gen_unary (ZERO_EXTEND, iv1->extend_mode,
+ iv1->base, iv1->mode);
+ }
+
+ mode = iv0->extend_mode;
+ if (mode != iv1->extend_mode)
+ return false;
+
+ if (iv0->extend == NIL && iv1->extend == NIL)
+ {
+ if (iv0->mode != iv1->mode)
+ return false;
+
+ iv0->base = simplify_gen_binary (op, mode, iv0->base, iv1->base);
+ iv0->step = simplify_gen_binary (op, mode, iv0->step, iv1->step);
+
+ return true;
+ }
+
+ /* Handle addition of constant. */
+ if (iv1->extend == NIL
+ && iv1->mode == mode
+ && iv1->step == const0_rtx)
+ {
+ iv0->delta = simplify_gen_binary (op, mode, iv0->delta, iv1->base);
+ return true;
+ }
+
+ if (iv0->extend == NIL
+ && iv0->mode == mode
+ && iv0->step == const0_rtx)
+ {
+ arg = iv0->base;
+ *iv0 = *iv1;
+ if (op == MINUS
+ && !iv_neg (iv0))
+ return false;
+
+ iv0->delta = simplify_gen_binary (PLUS, mode, iv0->delta, arg);
+ return true;
+ }
+
+ return false;
+}
+
+/* Evaluates multiplication of IV by constant CST. */
+
+static bool
+iv_mult (struct rtx_iv *iv, rtx mby)
+{
+ enum machine_mode mode = iv->extend_mode;
+
+ if (GET_MODE (mby) != VOIDmode
+ && GET_MODE (mby) != mode)
+ return false;
+
+ if (iv->extend == NIL)
+ {
+ iv->base = simplify_gen_binary (MULT, mode, iv->base, mby);
+ iv->step = simplify_gen_binary (MULT, mode, iv->step, mby);
+ }
+ else
+ {
+ iv->delta = simplify_gen_binary (MULT, mode, iv->delta, mby);
+ iv->mult = simplify_gen_binary (MULT, mode, iv->mult, mby);
+ }
+
+ return true;
+}
+
+/* Evaluates shift of IV by constant CST. */
+
+static bool
+iv_shift (struct rtx_iv *iv, rtx mby)
+{
+ enum machine_mode mode = iv->extend_mode;
+
+ if (GET_MODE (mby) != VOIDmode
+ && GET_MODE (mby) != mode)
+ return false;
+
+ if (iv->extend == NIL)
+ {
+ iv->base = simplify_gen_binary (ASHIFT, mode, iv->base, mby);
+ iv->step = simplify_gen_binary (ASHIFT, mode, iv->step, mby);
+ }
+ else
+ {
+ iv->delta = simplify_gen_binary (ASHIFT, mode, iv->delta, mby);
+ iv->mult = simplify_gen_binary (ASHIFT, mode, iv->mult, mby);
+ }
+
+ return true;
+}
+
+/* The recursive part of get_biv_step. Gets the value of the single value
+ defined in INSN wrto initial value of REG inside loop, in shape described
+ at get_biv_step. */
+
+static bool
+get_biv_step_1 (rtx insn, rtx reg,
+ rtx *inner_step, enum machine_mode *inner_mode,
+ enum rtx_code *extend, enum machine_mode outer_mode,
+ rtx *outer_step)
+{
+ rtx set, lhs, rhs, op0 = NULL_RTX, op1 = NULL_RTX;
+ rtx next, nextr, def_insn, tmp;
+ enum rtx_code code;
+
+ set = single_set (insn);
+ rhs = find_reg_equal_equiv_note (insn);
+ if (rhs)
+ rhs = XEXP (rhs, 0);
+ else
+ rhs = SET_SRC (set);
+ lhs = SET_DEST (set);
+
+ code = GET_CODE (rhs);
+ switch (code)
+ {
+ case SUBREG:
+ case REG:
+ next = rhs;
+ break;
+
+ case PLUS:
+ case MINUS:
+ op0 = XEXP (rhs, 0);
+ op1 = XEXP (rhs, 1);
+
+ if (code == PLUS && CONSTANT_P (op0))
+ {
+ tmp = op0; op0 = op1; op1 = tmp;
+ }
+
+ if (!simple_reg_p (op0)
+ || !CONSTANT_P (op1))
+ return false;
+
+ if (GET_MODE (rhs) != outer_mode)
+ {
+ /* ppc64 uses expressions like
+
+ (set x:SI (plus:SI (subreg:SI y:DI) 1)).
+
+ this is equivalent to
+
+ (set x':DI (plus:DI y:DI 1))
+ (set x:SI (subreg:SI (x':DI)). */
+ if (GET_CODE (op0) != SUBREG)
+ return false;
+ if (GET_MODE (SUBREG_REG (op0)) != outer_mode)
+ return false;
+ }
+
+ next = op0;
+ break;
+
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+ if (GET_MODE (rhs) != outer_mode)
+ return false;
+
+ op0 = XEXP (rhs, 0);
+ if (!simple_reg_p (op0))
+ return false;
+
+ next = op0;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (GET_CODE (next) == SUBREG)
+ {
+ if (!subreg_lowpart_p (next))
+ return false;
+
+ nextr = SUBREG_REG (next);
+ if (GET_MODE (nextr) != outer_mode)
+ return false;
+ }
+ else
+ nextr = next;
+
+ def_insn = iv_get_reaching_def (insn, nextr);
+ if (def_insn == const0_rtx)
+ return false;
+
+ if (!def_insn)
+ {
+ if (!rtx_equal_p (nextr, reg))
+ return false;
+
+ *inner_step = const0_rtx;
+ *extend = NIL;
+ *inner_mode = outer_mode;
+ *outer_step = const0_rtx;
+ }
+ else if (!get_biv_step_1 (def_insn, reg,
+ inner_step, inner_mode, extend, outer_mode,
+ outer_step))
+ return false;
+
+ if (GET_CODE (next) == SUBREG)
+ {
+ enum machine_mode amode = GET_MODE (next);
+
+ if (GET_MODE_SIZE (amode) > GET_MODE_SIZE (*inner_mode))
+ return false;
+
+ *inner_mode = amode;
+ *inner_step = simplify_gen_binary (PLUS, outer_mode,
+ *inner_step, *outer_step);
+ *outer_step = const0_rtx;
+ *extend = NIL;
+ }
+
+ switch (code)
+ {
+ case REG:
+ case SUBREG:
+ break;
+
+ case PLUS:
+ case MINUS:
+ if (*inner_mode == outer_mode
+ /* See comment in previous switch. */
+ || GET_MODE (rhs) != outer_mode)
+ *inner_step = simplify_gen_binary (code, outer_mode,
+ *inner_step, op1);
+ else
+ *outer_step = simplify_gen_binary (code, outer_mode,
+ *outer_step, op1);
+ break;
+
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+ if (GET_MODE (op0) != *inner_mode
+ || *extend != NIL
+ || *outer_step != const0_rtx)
+ abort ();
+
+ *extend = code;
+ break;
+
+ default:
+ abort ();
+ }
+
+ return true;
+}
+
+/* Gets the operation on register REG inside loop, in shape
+
+ OUTER_STEP + EXTEND_{OUTER_MODE} (SUBREG_{INNER_MODE} (REG + INNER_STEP))
+
+ If the operation cannot be described in this shape, return false. */
+
+static bool
+get_biv_step (rtx reg, rtx *inner_step, enum machine_mode *inner_mode,
+ enum rtx_code *extend, enum machine_mode *outer_mode,
+ rtx *outer_step)
+{
+ *outer_mode = GET_MODE (reg);
+
+ if (!get_biv_step_1 (last_def[REGNO (reg)], reg,
+ inner_step, inner_mode, extend, *outer_mode,
+ outer_step))
+ return false;
+
+ if (*inner_mode != *outer_mode
+ && *extend == NIL)
+ abort ();
+
+ if (*inner_mode == *outer_mode
+ && *extend != NIL)
+ abort ();
+
+ if (*inner_mode == *outer_mode
+ && *outer_step != const0_rtx)
+ abort ();
+
+ return true;
+}
+
+/* Determines whether DEF is a biv and if so, stores its description
+ to *IV. */
+
+static bool
+iv_analyze_biv (rtx def, struct rtx_iv *iv)
+{
+ unsigned regno;
+ rtx inner_step, outer_step;
+ enum machine_mode inner_mode, outer_mode;
+ enum rtx_code extend;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Analysing ");
+ print_rtl (dump_file, def);
+ fprintf (dump_file, " for bivness.\n");
+ }
+
+ if (!REG_P (def))
+ {
+ if (!CONSTANT_P (def))
+ return false;
+
+ return iv_constant (iv, def, VOIDmode);
+ }
+
+ regno = REGNO (def);
+ if (last_def[regno] == const0_rtx)
+ {
+ if (dump_file)
+ fprintf (dump_file, " not simple.\n");
+ return false;
+ }
+
+ if (last_def[regno] && bivs[regno].analysed)
+ {
+ if (dump_file)
+ fprintf (dump_file, " already analysed.\n");
+
+ *iv = bivs[regno];
+ return iv->base != NULL_RTX;
+ }
+
+ if (!last_def[regno])
+ {
+ iv_constant (iv, def, VOIDmode);
+ goto end;
+ }
+
+ iv->analysed = true;
+ if (!get_biv_step (def, &inner_step, &inner_mode, &extend,
+ &outer_mode, &outer_step))
+ {
+ iv->base = NULL_RTX;
+ goto end;
+ }
+
+ /* Loop transforms base to es (base + inner_step) + outer_step,
+ where es means extend of subreg between inner_mode and outer_mode.
+ The corresponding induction variable is
+
+ es ((base - outer_step) + i * (inner_step + outer_step)) + outer_step */
+
+ iv->base = simplify_gen_binary (MINUS, outer_mode, def, outer_step);
+ iv->step = simplify_gen_binary (PLUS, outer_mode, inner_step, outer_step);
+ iv->mode = inner_mode;
+ iv->extend_mode = outer_mode;
+ iv->extend = extend;
+ iv->mult = const1_rtx;
+ iv->delta = outer_step;
+ iv->first_special = inner_mode != outer_mode;
+
+ end:
+ if (dump_file)
+ {
+ fprintf (dump_file, " ");
+ dump_iv_info (dump_file, iv);
+ fprintf (dump_file, "\n");
+ }
+
+ bivs[regno] = *iv;
+
+ return iv->base != NULL_RTX;
+}
+
+/* Analyzes operand OP of INSN and stores the result to *IV. */
+
+static bool
+iv_analyze_op (rtx insn, rtx op, struct rtx_iv *iv)
+{
+ rtx def_insn;
+ unsigned regno;
+ bool inv = CONSTANT_P (op);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Analysing operand ");
+ print_rtl (dump_file, op);
+ fprintf (dump_file, " of insn ");
+ print_rtl_single (dump_file, insn);
+ }
+
+ if (GET_CODE (op) == SUBREG)
+ {
+ if (!subreg_lowpart_p (op))
+ return false;
+
+ if (!iv_analyze_op (insn, SUBREG_REG (op), iv))
+ return false;
+
+ return iv_subreg (iv, GET_MODE (op));
+ }
+
+ if (!inv)
+ {
+ regno = REGNO (op);
+ if (!last_def[regno])
+ inv = true;
+ else if (last_def[regno] == const0_rtx)
+ {
+ if (dump_file)
+ fprintf (dump_file, " not simple.\n");
+ return false;
+ }
+ }
+
+ if (inv)
+ {
+ iv_constant (iv, op, VOIDmode);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, " ");
+ dump_iv_info (dump_file, iv);
+ fprintf (dump_file, "\n");
+ }
+ return true;
+ }
+
+ def_insn = iv_get_reaching_def (insn, op);
+ if (def_insn == const0_rtx)
+ {
+ if (dump_file)
+ fprintf (dump_file, " not simple.\n");
+ return false;
+ }
+
+ return iv_analyze (def_insn, op, iv);
+}
+
+/* Analyzes iv DEF defined in INSN and stores the result to *IV. */
+
+bool
+iv_analyze (rtx insn, rtx def, struct rtx_iv *iv)
+{
+ unsigned uid;
+ rtx set, rhs, mby = NULL_RTX, tmp;
+ rtx op0 = NULL_RTX, op1 = NULL_RTX;
+ struct rtx_iv iv0, iv1;
+ enum machine_mode amode;
+ enum rtx_code code;
+
+ if (insn == const0_rtx)
+ return false;
+
+ if (GET_CODE (def) == SUBREG)
+ {
+ if (!subreg_lowpart_p (def))
+ return false;
+
+ if (!iv_analyze (insn, SUBREG_REG (def), iv))
+ return false;
+
+ return iv_subreg (iv, GET_MODE (def));
+ }
+
+ if (!insn)
+ return iv_analyze_biv (def, iv);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Analysing def of ");
+ print_rtl (dump_file, def);
+ fprintf (dump_file, " in insn ");
+ print_rtl_single (dump_file, insn);
+ }
+
+ uid = INSN_UID (insn);
+ if (insn_info[uid].iv.analysed)
+ {
+ if (dump_file)
+ fprintf (dump_file, " already analysed.\n");
+ *iv = insn_info[uid].iv;
+ return iv->base != NULL_RTX;
+ }
+
+ iv->mode = VOIDmode;
+ iv->base = NULL_RTX;
+ iv->step = NULL_RTX;
+
+ set = single_set (insn);
+ rhs = find_reg_equal_equiv_note (insn);
+ if (rhs)
+ rhs = XEXP (rhs, 0);
+ else
+ rhs = SET_SRC (set);
+ code = GET_CODE (rhs);
+
+ if (CONSTANT_P (rhs))
+ {
+ op0 = rhs;
+ amode = GET_MODE (def);
+ }
+ else
+ {
+ switch (code)
+ {
+ case SUBREG:
+ if (!subreg_lowpart_p (rhs))
+ goto end;
+ op0 = rhs;
+ break;
+
+ case REG:
+ op0 = rhs;
+ break;
+
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+ case NEG:
+ op0 = XEXP (rhs, 0);
+ break;
+
+ case PLUS:
+ case MINUS:
+ op0 = XEXP (rhs, 0);
+ op1 = XEXP (rhs, 1);
+ break;
+
+ case MULT:
+ op0 = XEXP (rhs, 0);
+ mby = XEXP (rhs, 1);
+ if (!CONSTANT_P (mby))
+ {
+ if (!CONSTANT_P (op0))
+ abort ();
+ tmp = op0;
+ op0 = mby;
+ mby = tmp;
+ }
+ break;
+
+ case ASHIFT:
+ if (CONSTANT_P (XEXP (rhs, 0)))
+ abort ();
+ op0 = XEXP (rhs, 0);
+ mby = XEXP (rhs, 1);
+ break;
+
+ default:
+ abort ();
+ }
+
+ amode = GET_MODE (rhs);
+ }
+
+ if (op0)
+ {
+ if (!iv_analyze_op (insn, op0, &iv0))
+ goto end;
+
+ if (iv0.mode == VOIDmode)
+ {
+ iv0.mode = amode;
+ iv0.extend_mode = amode;
+ }
+ }
+
+ if (op1)
+ {
+ if (!iv_analyze_op (insn, op1, &iv1))
+ goto end;
+
+ if (iv1.mode == VOIDmode)
+ {
+ iv1.mode = amode;
+ iv1.extend_mode = amode;
+ }
+ }
+
+ switch (code)
+ {
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+ if (!iv_extend (&iv0, code, amode))
+ goto end;
+ break;
+
+ case NEG:
+ if (!iv_neg (&iv0))
+ goto end;
+ break;
+
+ case PLUS:
+ case MINUS:
+ if (!iv_add (&iv0, &iv1, code))
+ goto end;
+ break;
+
+ case MULT:
+ if (!iv_mult (&iv0, mby))
+ goto end;
+ break;
+
+ case ASHIFT:
+ if (!iv_shift (&iv0, mby))
+ goto end;
+ break;
+
+ default:
+ break;
+ }
+
+ *iv = iv0;
+
+ end:
+ iv->analysed = true;
+ insn_info[uid].iv = *iv;
+
+ if (dump_file)
+ {
+ print_rtl (dump_file, def);
+ fprintf (dump_file, " in insn ");
+ print_rtl_single (dump_file, insn);
+ fprintf (dump_file, " is ");
+ dump_iv_info (dump_file, iv);
+ fprintf (dump_file, "\n");
+ }
+
+ return iv->base != NULL_RTX;
+}
+
+/* Calculates value of IV at ITERATION-th iteration. */
+
+rtx
+get_iv_value (struct rtx_iv *iv, rtx iteration)
+{
+ rtx val;
+
+ /* We would need to generate some if_then_else patterns, and so far
+ it is not needed anywhere. */
+ if (iv->first_special)
+ abort ();
+
+ if (iv->step != const0_rtx && iteration != const0_rtx)
+ val = simplify_gen_binary (PLUS, iv->extend_mode, iv->base,
+ simplify_gen_binary (MULT, iv->extend_mode,
+ iv->step, iteration));
+ else
+ val = iv->base;
+
+ if (iv->extend_mode == iv->mode)
+ return val;
+
+ val = lowpart_subreg (iv->mode, val, iv->extend_mode);
+
+ if (iv->extend == NIL)
+ return val;
+
+ val = simplify_gen_unary (iv->extend, iv->extend_mode, val, iv->mode);
+ val = simplify_gen_binary (PLUS, iv->extend_mode, iv->delta,
+ simplify_gen_binary (MULT, iv->extend_mode,
+ iv->mult, val));
+
+ return val;
+}
+
+/* Free the data for an induction variable analysis. */
+
+void
+iv_analysis_done (void)
+{
+ max_insn_no = 0;
+ max_reg_no = 0;
+ if (insn_info)
+ {
+ free (insn_info);
+ insn_info = NULL;
+ }
+ if (last_def)
+ {
+ free (last_def);
+ last_def = NULL;
+ }
+ if (bivs)
+ {
+ free (bivs);
+ bivs = NULL;
+ }
+}
+
+/* Computes inverse to X modulo (1 << MOD). */
+
+static unsigned HOST_WIDEST_INT
+inverse (unsigned HOST_WIDEST_INT x, int mod)
+{
+ unsigned HOST_WIDEST_INT mask =
+ ((unsigned HOST_WIDEST_INT) 1 << (mod - 1) << 1) - 1;
+ unsigned HOST_WIDEST_INT rslt = 1;
+ int i;
+
+ for (i = 0; i < mod - 1; i++)
+ {
+ rslt = (rslt * x) & mask;
+ x = (x * x) & mask;
+ }
+
+ return rslt;
+}
+
+/* Tries to estimate the maximum number of iterations. */
+
+static unsigned HOST_WIDEST_INT
+determine_max_iter (struct niter_desc *desc)
+{
+ rtx niter = desc->niter_expr;
+ rtx mmin, mmax, left, right;
+ unsigned HOST_WIDEST_INT nmax, inc;
+
+ if (GET_CODE (niter) == AND
+ && GET_CODE (XEXP (niter, 0)) == CONST_INT)
+ {
+ nmax = INTVAL (XEXP (niter, 0));
+ if (!(nmax & (nmax + 1)))
+ {
+ desc->niter_max = nmax;
+ return nmax;
+ }
+ }
+
+ get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax);
+ nmax = INTVAL (mmax) - INTVAL (mmin);
+
+ if (GET_CODE (niter) == UDIV)
+ {
+ if (GET_CODE (XEXP (niter, 1)) != CONST_INT)
+ {
+ desc->niter_max = nmax;
+ return nmax;
+ }
+ inc = INTVAL (XEXP (niter, 1));
+ niter = XEXP (niter, 0);
+ }
+ else
+ inc = 1;
+
+ if (GET_CODE (niter) == PLUS)
+ {
+ left = XEXP (niter, 0);
+ right = XEXP (niter, 0);
+
+ if (GET_CODE (right) == CONST_INT)
+ right = GEN_INT (-INTVAL (right));
+ }
+ else if (GET_CODE (niter) == MINUS)
+ {
+ left = XEXP (niter, 0);
+ right = XEXP (niter, 0);
+ }
+ else
+ {
+ left = niter;
+ right = mmin;
+ }
+
+ if (GET_CODE (left) == CONST_INT)
+ mmax = left;
+ if (GET_CODE (right) == CONST_INT)
+ mmin = right;
+ nmax = INTVAL (mmax) - INTVAL (mmin);
+
+ desc->niter_max = nmax / inc;
+ return nmax / inc;
+}
+
+/* Checks whether register *REG is in set ALT. Callback for for_each_rtx. */
+
+static int
+altered_reg_used (rtx *reg, void *alt)
+{
+ if (!REG_P (*reg))
+ return 0;
+
+ return REGNO_REG_SET_P (alt, REGNO (*reg));
+}
+
+/* Marks registers altered by EXPR in set ALT. */
+
+static void
+mark_altered (rtx expr, rtx by ATTRIBUTE_UNUSED, void *alt)
+{
+ if (GET_CODE (expr) == SUBREG)
+ expr = SUBREG_REG (expr);
+ if (!REG_P (expr))
+ return;
+
+ SET_REGNO_REG_SET (alt, REGNO (expr));
+}
+
+/* Checks whether RHS is simple enough to process. */
+
+static bool
+simple_rhs_p (rtx rhs)
+{
+ rtx op0, op1;
+
+ if (CONSTANT_P (rhs)
+ || REG_P (rhs))
+ return true;
+
+ switch (GET_CODE (rhs))
+ {
+ case PLUS:
+ case MINUS:
+ op0 = XEXP (rhs, 0);
+ op1 = XEXP (rhs, 1);
+ /* Allow reg + const sets only. */
+ if (REG_P (op0) && CONSTANT_P (op1))
+ return true;
+ if (REG_P (op1) && CONSTANT_P (op0))
+ return true;
+
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+/* Simplifies *EXPR using assignment in INSN. ALTERED is the set of registers
+ altered so far. */
+
+static void
+simplify_using_assignment (rtx insn, rtx *expr, regset altered)
+{
+ rtx set = single_set (insn);
+ rtx lhs, rhs;
+ bool ret = false;
+
+ if (set)
+ {
+ lhs = SET_DEST (set);
+ if (!REG_P (lhs)
+ || altered_reg_used (&lhs, altered))
+ ret = true;
+ }
+ else
+ ret = true;
+
+ note_stores (PATTERN (insn), mark_altered, altered);
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ int i;
+
+ /* Kill all call clobbered registers. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
+ SET_REGNO_REG_SET (altered, i);
+ }
+
+ if (ret)
+ return;
+
+ rhs = find_reg_equal_equiv_note (insn);
+ if (rhs)
+ rhs = XEXP (rhs, 0);
+ else
+ rhs = SET_SRC (set);
+
+ if (!simple_rhs_p (rhs))
+ return;
+
+ if (for_each_rtx (&rhs, altered_reg_used, altered))
+ return;
+
+ *expr = simplify_replace_rtx (*expr, lhs, rhs);
+}
+
+/* Checks whether A implies B. */
+
+static bool
+implies_p (rtx a, rtx b)
+{
+ rtx op0, op1, opb0, opb1, r;
+ enum machine_mode mode;
+
+ if (GET_CODE (a) == EQ)
+ {
+ op0 = XEXP (a, 0);
+ op1 = XEXP (a, 1);
+
+ if (REG_P (op0))
+ {
+ r = simplify_replace_rtx (b, op0, op1);
+ if (r == const_true_rtx)
+ return true;
+ }
+
+ if (REG_P (op1))
+ {
+ r = simplify_replace_rtx (b, op1, op0);
+ if (r == const_true_rtx)
+ return true;
+ }
+ }
+
+ /* A < B implies A + 1 <= B. */
+ if ((GET_CODE (a) == GT || GET_CODE (a) == LT)
+ && (GET_CODE (b) == GE || GET_CODE (b) == LE))
+ {
+ op0 = XEXP (a, 0);
+ op1 = XEXP (a, 1);
+ opb0 = XEXP (b, 0);
+ opb1 = XEXP (b, 1);
+
+ if (GET_CODE (a) == GT)
+ {
+ r = op0;
+ op0 = op1;
+ op1 = r;
+ }
+
+ if (GET_CODE (b) == GE)
+ {
+ r = opb0;
+ opb0 = opb1;
+ opb1 = r;
+ }
+
+ mode = GET_MODE (op0);
+ if (mode != GET_MODE (opb0))
+ mode = VOIDmode;
+ else if (mode == VOIDmode)
+ {
+ mode = GET_MODE (op1);
+ if (mode != GET_MODE (opb1))
+ mode = VOIDmode;
+ }
+
+ if (mode != VOIDmode
+ && rtx_equal_p (op1, opb1)
+ && simplify_gen_binary (MINUS, mode, opb0, op0) == const1_rtx)
+ return true;
+ }
+
+ return false;
+}
+
+/* Canonicalizes COND so that
+
+ (1) Ensure that operands are ordered according to
+ swap_commutative_operands_p.
+ (2) (LE x const) will be replaced with (LT x <const+1>) and similarly
+ for GE, GEU, and LEU. */
+
+rtx
+canon_condition (rtx cond)
+{
+ rtx tem;
+ rtx op0, op1;
+ enum rtx_code code;
+ enum machine_mode mode;
+
+ code = GET_CODE (cond);
+ op0 = XEXP (cond, 0);
+ op1 = XEXP (cond, 1);
+
+ if (swap_commutative_operands_p (op0, op1))
+ {
+ code = swap_condition (code);
+ tem = op0;
+ op0 = op1;
+ op1 = tem;
+ }
+
+ mode = GET_MODE (op0);
+ if (mode == VOIDmode)
+ mode = GET_MODE (op1);
+ if (mode == VOIDmode)
+ abort ();
+
+ if (GET_CODE (op1) == CONST_INT
+ && GET_MODE_CLASS (mode) != MODE_CC
+ && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ {
+ HOST_WIDE_INT const_val = INTVAL (op1);
+ unsigned HOST_WIDE_INT uconst_val = const_val;
+ unsigned HOST_WIDE_INT max_val
+ = (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode);
+
+ switch (code)
+ {
+ case LE:
+ if ((unsigned HOST_WIDE_INT) const_val != max_val >> 1)
+ code = LT, op1 = gen_int_mode (const_val + 1, GET_MODE (op0));
+ break;
+
+ /* When cross-compiling, const_val might be sign-extended from
+ BITS_PER_WORD to HOST_BITS_PER_WIDE_INT */
+ case GE:
+ if ((HOST_WIDE_INT) (const_val & max_val)
+ != (((HOST_WIDE_INT) 1
+ << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
+ code = GT, op1 = gen_int_mode (const_val - 1, mode);
+ break;
+
+ case LEU:
+ if (uconst_val < max_val)
+ code = LTU, op1 = gen_int_mode (uconst_val + 1, mode);
+ break;
+
+ case GEU:
+ if (uconst_val != 0)
+ code = GTU, op1 = gen_int_mode (uconst_val - 1, mode);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (op0 != XEXP (cond, 0)
+ || op1 != XEXP (cond, 1)
+ || code != GET_CODE (cond)
+ || GET_MODE (cond) != SImode)
+ cond = gen_rtx_fmt_ee (code, SImode, op0, op1);
+
+ return cond;
+}
+
+/* Tries to use the fact that COND holds to simplify EXPR. ALTERED is the
+ set of altered regs. */
+
+void
+simplify_using_condition (rtx cond, rtx *expr, regset altered)
+{
+ rtx rev, reve, exp = *expr;
+
+ if (!COMPARISON_P (exp))
+ return;
+
+ /* If some register gets altered later, we do not really speak about its
+ value at the time of comparison. */
+ if (altered
+ && for_each_rtx (&cond, altered_reg_used, altered))
+ return;
+
+ rev = reversed_condition (cond);
+ reve = reversed_condition (exp);
+
+ cond = canon_condition (cond);
+ exp = canon_condition (exp);
+ if (rev)
+ rev = canon_condition (rev);
+ if (reve)
+ reve = canon_condition (reve);
+
+ if (rtx_equal_p (exp, cond))
+ {
+ *expr = const_true_rtx;
+ return;
+ }
+
+
+ if (rev && rtx_equal_p (exp, rev))
+ {
+ *expr = const0_rtx;
+ return;
+ }
+
+ if (implies_p (cond, exp))
+ {
+ *expr = const_true_rtx;
+ return;
+ }
+
+ if (reve && implies_p (cond, reve))
+ {
+ *expr = const0_rtx;
+ return;
+ }
+
+ /* A proof by contradiction. If *EXPR implies (not cond), *EXPR must
+ be false. */
+ if (rev && implies_p (exp, rev))
+ {
+ *expr = const0_rtx;
+ return;
+ }
+
+ /* Similarly, If (not *EXPR) implies (not cond), *EXPR must be true. */
+ if (rev && reve && implies_p (reve, rev))
+ {
+ *expr = const_true_rtx;
+ return;
+ }
+
+ /* We would like to have some other tests here. TODO. */
+
+ return;
+}
+
+/* Use relationship between A and *B to eventually eliminate *B.
+ OP is the operation we consider. */
+
+static void
+eliminate_implied_condition (enum rtx_code op, rtx a, rtx *b)
+{
+ if (op == AND)
+ {
+ /* If A implies *B, we may replace *B by true. */
+ if (implies_p (a, *b))
+ *b = const_true_rtx;
+ }
+ else if (op == IOR)
+ {
+ /* If *B implies A, we may replace *B by false. */
+ if (implies_p (*b, a))
+ *b = const0_rtx;
+ }
+ else
+ abort ();
+}
+
+/* Eliminates the conditions in TAIL that are implied by HEAD. OP is the
+ operation we consider. */
+
+static void
+eliminate_implied_conditions (enum rtx_code op, rtx *head, rtx tail)
+{
+ rtx elt;
+
+ for (elt = tail; elt; elt = XEXP (elt, 1))
+ eliminate_implied_condition (op, *head, &XEXP (elt, 0));
+ for (elt = tail; elt; elt = XEXP (elt, 1))
+ eliminate_implied_condition (op, XEXP (elt, 0), head);
+}
+
+/* Simplifies *EXPR using initial values at the start of the LOOP. If *EXPR
+ is a list, its elements are assumed to be combined using OP. */
+
+static void
+simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
+{
+ rtx head, tail, insn;
+ rtx neutral, aggr;
+ regset altered;
+ regset_head altered_head;
+ edge e;
+
+ if (!*expr)
+ return;
+
+ if (CONSTANT_P (*expr))
+ return;
+
+ if (GET_CODE (*expr) == EXPR_LIST)
+ {
+ head = XEXP (*expr, 0);
+ tail = XEXP (*expr, 1);
+
+ eliminate_implied_conditions (op, &head, tail);
+
+ if (op == AND)
+ {
+ neutral = const_true_rtx;
+ aggr = const0_rtx;
+ }
+ else if (op == IOR)
+ {
+ neutral = const0_rtx;
+ aggr = const_true_rtx;
+ }
+ else
+ abort ();
+
+ simplify_using_initial_values (loop, NIL, &head);
+ if (head == aggr)
+ {
+ XEXP (*expr, 0) = aggr;
+ XEXP (*expr, 1) = NULL_RTX;
+ return;
+ }
+ else if (head == neutral)
+ {
+ *expr = tail;
+ simplify_using_initial_values (loop, op, expr);
+ return;
+ }
+ simplify_using_initial_values (loop, op, &tail);
+
+ if (tail && XEXP (tail, 0) == aggr)
+ {
+ *expr = tail;
+ return;
+ }
+
+ XEXP (*expr, 0) = head;
+ XEXP (*expr, 1) = tail;
+ return;
+ }
+
+ if (op != NIL)
+ abort ();
+
+ e = loop_preheader_edge (loop);
+ if (e->src == ENTRY_BLOCK_PTR)
+ return;
+
+ altered = INITIALIZE_REG_SET (altered_head);
+
+ while (1)
+ {
+ insn = BB_END (e->src);
+ if (any_condjump_p (insn))
+ {
+ /* FIXME -- slightly wrong -- what if compared register
+ gets altered between start of the condition and insn? */
+ rtx cond = get_condition (BB_END (e->src), NULL, false);
+
+ if (cond && (e->flags & EDGE_FALLTHRU))
+ cond = reversed_condition (cond);
+ if (cond)
+ {
+ simplify_using_condition (cond, expr, altered);
+ if (CONSTANT_P (*expr))
+ {
+ FREE_REG_SET (altered);
+ return;
+ }
+ }
+ }
+
+ FOR_BB_INSNS_REVERSE (e->src, insn)
+ {
+ if (!INSN_P (insn))
+ continue;
+
+ simplify_using_assignment (insn, expr, altered);
+ if (CONSTANT_P (*expr))
+ {
+ FREE_REG_SET (altered);
+ return;
+ }
+ }
+
+ e = e->src->pred;
+ if (e->pred_next
+ || e->src == ENTRY_BLOCK_PTR)
+ break;
+ }
+
+ FREE_REG_SET (altered);
+}
+
+/* Transforms invariant IV into MODE. Adds assumptions based on the fact
+ that IV occurs as left operands of comparison COND and its signedness
+ is SIGNED_P to DESC. */
+
+static void
+shorten_into_mode (struct rtx_iv *iv, enum machine_mode mode,
+ enum rtx_code cond, bool signed_p, struct niter_desc *desc)
+{
+ rtx mmin, mmax, cond_over, cond_under;
+
+ get_mode_bounds (mode, signed_p, iv->extend_mode, &mmin, &mmax);
+ cond_under = simplify_gen_relational (LT, SImode, iv->extend_mode,
+ iv->base, mmin);
+ cond_over = simplify_gen_relational (GT, SImode, iv->extend_mode,
+ iv->base, mmax);
+
+ switch (cond)
+ {
+ case LE:
+ case LT:
+ case LEU:
+ case LTU:
+ if (cond_under != const0_rtx)
+ desc->infinite =
+ alloc_EXPR_LIST (0, cond_under, desc->infinite);
+ if (cond_over != const0_rtx)
+ desc->noloop_assumptions =
+ alloc_EXPR_LIST (0, cond_over, desc->noloop_assumptions);
+ break;
+
+ case GE:
+ case GT:
+ case GEU:
+ case GTU:
+ if (cond_over != const0_rtx)
+ desc->infinite =
+ alloc_EXPR_LIST (0, cond_over, desc->infinite);
+ if (cond_under != const0_rtx)
+ desc->noloop_assumptions =
+ alloc_EXPR_LIST (0, cond_under, desc->noloop_assumptions);
+ break;
+
+ case NE:
+ if (cond_over != const0_rtx)
+ desc->infinite =
+ alloc_EXPR_LIST (0, cond_over, desc->infinite);
+ if (cond_under != const0_rtx)
+ desc->infinite =
+ alloc_EXPR_LIST (0, cond_under, desc->infinite);
+ break;
+
+ default:
+ abort ();
+ }
+
+ iv->mode = mode;
+ iv->extend = signed_p ? SIGN_EXTEND : ZERO_EXTEND;
+}
+
+/* Transforms IV0 and IV1 compared by COND so that they are both compared as
+ subregs of the same mode if possible (sometimes it is necessary to add
+ some assumptions to DESC). */
+
+static bool
+canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1,
+ enum rtx_code cond, struct niter_desc *desc)
+{
+ enum machine_mode comp_mode;
+ bool signed_p;
+
+ /* If the ivs behave specially in the first iteration, or are
+ added/multiplied after extending, we ignore them. */
+ if (iv0->first_special || iv0->mult != const1_rtx || iv0->delta != const0_rtx)
+ return false;
+ if (iv1->first_special || iv1->mult != const1_rtx || iv1->delta != const0_rtx)
+ return false;
+
+ /* If there is some extend, it must match signedness of the comparison. */
+ switch (cond)
+ {
+ case LE:
+ case LT:
+ if (iv0->extend == ZERO_EXTEND
+ || iv1->extend == ZERO_EXTEND)
+ return false;
+ signed_p = true;
+ break;
+
+ case LEU:
+ case LTU:
+ if (iv0->extend == SIGN_EXTEND
+ || iv1->extend == SIGN_EXTEND)
+ return false;
+ signed_p = false;
+ break;
+
+ case NE:
+ if (iv0->extend != NIL
+ && iv1->extend != NIL
+ && iv0->extend != iv1->extend)
+ return false;
+
+ signed_p = false;
+ if (iv0->extend != NIL)
+ signed_p = iv0->extend == SIGN_EXTEND;
+ if (iv1->extend != NIL)
+ signed_p = iv1->extend == SIGN_EXTEND;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Values of both variables should be computed in the same mode. These
+ might indeed be different, if we have comparison like
+
+ (compare (subreg:SI (iv0)) (subreg:SI (iv1)))
+
+ and iv0 and iv1 are both ivs iterating in SI mode, but calculated
+ in different modes. This does not seem impossible to handle, but
+ it hardly ever occurs in practice.
+
+ The only exception is the case when one of operands is invariant.
+ For example pentium 3 generates comparisons like
+ (lt (subreg:HI (reg:SI)) 100). Here we assign HImode to 100, but we
+ definitely do not want this prevent the optimization. */
+ comp_mode = iv0->extend_mode;
+ if (GET_MODE_BITSIZE (comp_mode) < GET_MODE_BITSIZE (iv1->extend_mode))
+ comp_mode = iv1->extend_mode;
+
+ if (iv0->extend_mode != comp_mode)
+ {
+ if (iv0->mode != iv0->extend_mode
+ || iv0->step != const0_rtx)
+ return false;
+
+ iv0->base = simplify_gen_unary (signed_p ? SIGN_EXTEND : ZERO_EXTEND,
+ comp_mode, iv0->base, iv0->mode);
+ iv0->extend_mode = comp_mode;
+ }
+
+ if (iv1->extend_mode != comp_mode)
+ {
+ if (iv1->mode != iv1->extend_mode
+ || iv1->step != const0_rtx)
+ return false;
+
+ iv1->base = simplify_gen_unary (signed_p ? SIGN_EXTEND : ZERO_EXTEND,
+ comp_mode, iv1->base, iv1->mode);
+ iv1->extend_mode = comp_mode;
+ }
+
+ /* Check that both ivs belong to a range of a single mode. If one of the
+ operands is an invariant, we may need to shorten it into the common
+ mode. */
+ if (iv0->mode == iv0->extend_mode
+ && iv0->step == const0_rtx
+ && iv0->mode != iv1->mode)
+ shorten_into_mode (iv0, iv1->mode, cond, signed_p, desc);
+
+ if (iv1->mode == iv1->extend_mode
+ && iv1->step == const0_rtx
+ && iv0->mode != iv1->mode)
+ shorten_into_mode (iv1, iv0->mode, swap_condition (cond), signed_p, desc);
+
+ if (iv0->mode != iv1->mode)
+ return false;
+
+ desc->mode = iv0->mode;
+ desc->signed_p = signed_p;
+
+ return true;
+}
+
+/* Computes number of iterations of the CONDITION in INSN in LOOP and stores
+ the result into DESC. Very similar to determine_number_of_iterations
+ (basically its rtl version), complicated by things like subregs. */
+
+void
+iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
+ struct niter_desc *desc)
+{
+ rtx op0, op1, delta, step, bound, may_xform, def_insn, tmp, tmp0, tmp1;
+ struct rtx_iv iv0, iv1, tmp_iv;
+ rtx assumption, may_not_xform;
+ enum rtx_code cond;
+ enum machine_mode mode, comp_mode;
+ rtx mmin, mmax, mode_mmin, mode_mmax;
+ unsigned HOST_WIDEST_INT s, size, d, inv;
+ HOST_WIDEST_INT up, down, inc;
+ int was_sharp = false;
+
+ /* The meaning of these assumptions is this:
+ if !assumptions
+ then the rest of information does not have to be valid
+ if noloop_assumptions then the loop does not roll
+ if infinite then this exit is never used */
+
+ desc->assumptions = NULL_RTX;
+ desc->noloop_assumptions = NULL_RTX;
+ desc->infinite = NULL_RTX;
+ desc->simple_p = true;
+
+ desc->const_iter = false;
+ desc->niter_expr = NULL_RTX;
+ desc->niter_max = 0;
+
+ cond = GET_CODE (condition);
+ if (!COMPARISON_P (condition))
+ abort ();
+
+ mode = GET_MODE (XEXP (condition, 0));
+ if (mode == VOIDmode)
+ mode = GET_MODE (XEXP (condition, 1));
+ /* The constant comparisons should be folded. */
+ if (mode == VOIDmode)
+ abort ();
+
+ /* We only handle integers or pointers. */
+ if (GET_MODE_CLASS (mode) != MODE_INT
+ && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
+ goto fail;
+
+ op0 = XEXP (condition, 0);
+ def_insn = iv_get_reaching_def (insn, op0);
+ if (!iv_analyze (def_insn, op0, &iv0))
+ goto fail;
+ if (iv0.extend_mode == VOIDmode)
+ iv0.mode = iv0.extend_mode = mode;
+
+ op1 = XEXP (condition, 1);
+ def_insn = iv_get_reaching_def (insn, op1);
+ if (!iv_analyze (def_insn, op1, &iv1))
+ goto fail;
+ if (iv1.extend_mode == VOIDmode)
+ iv1.mode = iv1.extend_mode = mode;
+
+ if (GET_MODE_BITSIZE (iv0.extend_mode) > HOST_BITS_PER_WIDE_INT
+ || GET_MODE_BITSIZE (iv1.extend_mode) > HOST_BITS_PER_WIDE_INT)
+ goto fail;
+
+ /* Check condition and normalize it. */
+
+ switch (cond)
+ {
+ case GE:
+ case GT:
+ case GEU:
+ case GTU:
+ tmp_iv = iv0; iv0 = iv1; iv1 = tmp_iv;
+ cond = swap_condition (cond);
+ break;
+ case NE:
+ case LE:
+ case LEU:
+ case LT:
+ case LTU:
+ break;
+ default:
+ goto fail;
+ }
+
+ /* Handle extends. This is relatively nontrivial, so we only try in some
+ easy cases, when we can canonicalize the ivs (possibly by adding some
+ assumptions) to shape subreg (base + i * step). This function also fills
+ in desc->mode and desc->signed_p. */
+
+ if (!canonicalize_iv_subregs (&iv0, &iv1, cond, desc))
+ goto fail;
+
+ comp_mode = iv0.extend_mode;
+ mode = iv0.mode;
+ size = GET_MODE_BITSIZE (mode);
+ get_mode_bounds (mode, (cond == LE || cond == LT), comp_mode, &mmin, &mmax);
+ mode_mmin = lowpart_subreg (mode, mmin, comp_mode);
+ mode_mmax = lowpart_subreg (mode, mmax, comp_mode);
+
+ if (GET_CODE (iv0.step) != CONST_INT || GET_CODE (iv1.step) != CONST_INT)
+ goto fail;
+
+ /* We can take care of the case of two induction variables chasing each other
+ if the test is NE. I have never seen a loop using it, but still it is
+ cool. */
+ if (iv0.step != const0_rtx && iv1.step != const0_rtx)
+ {
+ if (cond != NE)
+ goto fail;
+
+ iv0.step = simplify_gen_binary (MINUS, comp_mode, iv0.step, iv1.step);
+ iv1.step = const0_rtx;
+ }
+
+ /* This is either infinite loop or the one that ends immediately, depending
+ on initial values. Unswitching should remove this kind of conditions. */
+ if (iv0.step == const0_rtx && iv1.step == const0_rtx)
+ goto fail;
+
+ /* Ignore loops of while (i-- < 10) type. */
+ if (cond != NE
+ && (INTVAL (iv0.step) < 0 || INTVAL (iv1.step) > 0))
+ goto fail;
+
+ /* Some more condition normalization. We must record some assumptions
+ due to overflows. */
+ switch (cond)
+ {
+ case LT:
+ case LTU:
+ /* We want to take care only of non-sharp relationals; this is easy,
+ as in cases the overflow would make the transformation unsafe
+ the loop does not roll. Seemingly it would make more sense to want
+ to take care of sharp relationals instead, as NE is more similar to
+ them, but the problem is that here the transformation would be more
+ difficult due to possibly infinite loops. */
+ if (iv0.step == const0_rtx)
+ {
+ tmp = lowpart_subreg (mode, iv0.base, comp_mode);
+ assumption = simplify_gen_relational (EQ, SImode, mode, tmp,
+ mode_mmax);
+ if (assumption == const_true_rtx)
+ goto zero_iter;
+ iv0.base = simplify_gen_binary (PLUS, comp_mode,
+ iv0.base, const1_rtx);
+ }
+ else
+ {
+ tmp = lowpart_subreg (mode, iv1.base, comp_mode);
+ assumption = simplify_gen_relational (EQ, SImode, mode, tmp,
+ mode_mmin);
+ if (assumption == const_true_rtx)
+ goto zero_iter;
+ iv1.base = simplify_gen_binary (PLUS, comp_mode,
+ iv1.base, constm1_rtx);
+ }
+
+ if (assumption != const0_rtx)
+ desc->noloop_assumptions =
+ alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions);
+ cond = (cond == LT) ? LE : LEU;
+
+ /* It will be useful to be able to tell the difference once more in
+ LE -> NE reduction. */
+ was_sharp = true;
+ break;
+ default: ;
+ }
+
+ /* Take care of trivially infinite loops. */
+ if (cond != NE)
+ {
+ if (iv0.step == const0_rtx)
+ {
+ tmp = lowpart_subreg (mode, iv0.base, comp_mode);
+ if (rtx_equal_p (tmp, mode_mmin))
+ {
+ desc->infinite =
+ alloc_EXPR_LIST (0, const_true_rtx, NULL_RTX);
+ return;
+ }
+ }
+ else
+ {
+ tmp = lowpart_subreg (mode, iv1.base, comp_mode);
+ if (rtx_equal_p (tmp, mode_mmax))
+ {
+ desc->infinite =
+ alloc_EXPR_LIST (0, const_true_rtx, NULL_RTX);
+ return;
+ }
+ }
+ }
+
+ /* If we can we want to take care of NE conditions instead of size
+ comparisons, as they are much more friendly (most importantly
+ this takes care of special handling of loops with step 1). We can
+ do it if we first check that upper bound is greater or equal to
+ lower bound, their difference is constant c modulo step and that
+ there is not an overflow. */
+ if (cond != NE)
+ {
+ if (iv0.step == const0_rtx)
+ step = simplify_gen_unary (NEG, comp_mode, iv1.step, comp_mode);
+ else
+ step = iv0.step;
+ delta = simplify_gen_binary (MINUS, comp_mode, iv1.base, iv0.base);
+ delta = lowpart_subreg (mode, delta, comp_mode);
+ delta = simplify_gen_binary (UMOD, mode, delta, step);
+ may_xform = const0_rtx;
+ may_not_xform = const_true_rtx;
+
+ if (GET_CODE (delta) == CONST_INT)
+ {
+ if (was_sharp && INTVAL (delta) == INTVAL (step) - 1)
+ {
+ /* A special case. We have transformed condition of type
+ for (i = 0; i < 4; i += 4)
+ into
+ for (i = 0; i <= 3; i += 4)
+ obviously if the test for overflow during that transformation
+ passed, we cannot overflow here. Most importantly any
+ loop with sharp end condition and step 1 falls into this
+ category, so handling this case specially is definitely
+ worth the troubles. */
+ may_xform = const_true_rtx;
+ }
+ else if (iv0.step == const0_rtx)
+ {
+ bound = simplify_gen_binary (PLUS, comp_mode, mmin, step);
+ bound = simplify_gen_binary (MINUS, comp_mode, bound, delta);
+ bound = lowpart_subreg (mode, bound, comp_mode);
+ tmp = lowpart_subreg (mode, iv0.base, comp_mode);
+ may_xform = simplify_gen_relational (cond, SImode, mode,
+ bound, tmp);
+ may_not_xform = simplify_gen_relational (reverse_condition (cond),
+ SImode, mode,
+ bound, tmp);
+ }
+ else
+ {
+ bound = simplify_gen_binary (MINUS, comp_mode, mmax, step);
+ bound = simplify_gen_binary (PLUS, comp_mode, bound, delta);
+ bound = lowpart_subreg (mode, bound, comp_mode);
+ tmp = lowpart_subreg (mode, iv1.base, comp_mode);
+ may_xform = simplify_gen_relational (cond, SImode, mode,
+ tmp, bound);
+ may_not_xform = simplify_gen_relational (reverse_condition (cond),
+ SImode, mode,
+ tmp, bound);
+ }
+ }
+
+ if (may_xform != const0_rtx)
+ {
+ /* We perform the transformation always provided that it is not
+ completely senseless. This is OK, as we would need this assumption
+ to determine the number of iterations anyway. */
+ if (may_xform != const_true_rtx)
+ {
+ /* If the step is a power of two and the final value we have
+ computed overflows, the cycle is infinite. Otherwise it
+ is nontrivial to compute the number of iterations. */
+ s = INTVAL (step);
+ if ((s & (s - 1)) == 0)
+ desc->infinite = alloc_EXPR_LIST (0, may_not_xform,
+ desc->infinite);
+ else
+ desc->assumptions = alloc_EXPR_LIST (0, may_xform,
+ desc->assumptions);
+ }
+
+ /* We are going to lose some information about upper bound on
+ number of iterations in this step, so record the information
+ here. */
+ inc = INTVAL (iv0.step) - INTVAL (iv1.step);
+ if (GET_CODE (iv1.base) == CONST_INT)
+ up = INTVAL (iv1.base);
+ else
+ up = INTVAL (mode_mmax) - inc;
+ down = INTVAL (GET_CODE (iv0.base) == CONST_INT
+ ? iv0.base
+ : mode_mmin);
+ desc->niter_max = (up - down) / inc + 1;
+
+ if (iv0.step == const0_rtx)
+ {
+ iv0.base = simplify_gen_binary (PLUS, comp_mode, iv0.base, delta);
+ iv0.base = simplify_gen_binary (MINUS, comp_mode, iv0.base, step);
+ }
+ else
+ {
+ iv1.base = simplify_gen_binary (MINUS, comp_mode, iv1.base, delta);
+ iv1.base = simplify_gen_binary (PLUS, comp_mode, iv1.base, step);
+ }
+
+ tmp0 = lowpart_subreg (mode, iv0.base, comp_mode);
+ tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
+ assumption = simplify_gen_relational (reverse_condition (cond),
+ SImode, mode, tmp0, tmp1);
+ if (assumption == const_true_rtx)
+ goto zero_iter;
+ else if (assumption != const0_rtx)
+ desc->noloop_assumptions =
+ alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions);
+ cond = NE;
+ }
+ }
+
+ /* Count the number of iterations. */
+ if (cond == NE)
+ {
+ /* Everything we do here is just arithmetics modulo size of mode. This
+ makes us able to do more involved computations of number of iterations
+ than in other cases. First transform the condition into shape
+ s * i <> c, with s positive. */
+ iv1.base = simplify_gen_binary (MINUS, comp_mode, iv1.base, iv0.base);
+ iv0.base = const0_rtx;
+ iv0.step = simplify_gen_binary (MINUS, comp_mode, iv0.step, iv1.step);
+ iv1.step = const0_rtx;
+ if (INTVAL (iv0.step) < 0)
+ {
+ iv0.step = simplify_gen_unary (NEG, comp_mode, iv0.step, mode);
+ iv1.base = simplify_gen_unary (NEG, comp_mode, iv1.base, mode);
+ }
+ iv0.step = lowpart_subreg (mode, iv0.step, comp_mode);
+
+ /* Let nsd (s, size of mode) = d. If d does not divide c, the loop
+ is infinite. Otherwise, the number of iterations is
+ (inverse(s/d) * (c/d)) mod (size of mode/d). */
+ s = INTVAL (iv0.step); d = 1;
+ while (s % 2 != 1)
+ {
+ s /= 2;
+ d *= 2;
+ size--;
+ }
+ bound = GEN_INT (((unsigned HOST_WIDEST_INT) 1 << (size - 1 ) << 1) - 1);
+
+ tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
+ tmp = simplify_gen_binary (UMOD, mode, tmp1, GEN_INT (d));
+ assumption = simplify_gen_relational (NE, SImode, mode, tmp, const0_rtx);
+ desc->infinite = alloc_EXPR_LIST (0, assumption, desc->infinite);
+
+ tmp = simplify_gen_binary (UDIV, mode, tmp1, GEN_INT (d));
+ inv = inverse (s, size);
+ inv = trunc_int_for_mode (inv, mode);
+ tmp = simplify_gen_binary (MULT, mode, tmp, GEN_INT (inv));
+ desc->niter_expr = simplify_gen_binary (AND, mode, tmp, bound);
+ }
+ else
+ {
+ if (iv1.step == const0_rtx)
+ /* Condition in shape a + s * i <= b
+ We must know that b + s does not overflow and a <= b + s and then we
+ can compute number of iterations as (b + s - a) / s. (It might
+ seem that we in fact could be more clever about testing the b + s
+ overflow condition using some information about b - a mod s,
+ but it was already taken into account during LE -> NE transform). */
+ {
+ step = iv0.step;
+ tmp0 = lowpart_subreg (mode, iv0.base, comp_mode);
+ tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
+
+ bound = simplify_gen_binary (MINUS, mode, mode_mmax,
+ lowpart_subreg (mode, step, comp_mode));
+ assumption = simplify_gen_relational (cond, SImode, mode,
+ tmp1, bound);
+ desc->assumptions =
+ alloc_EXPR_LIST (0, assumption, desc->assumptions);
+
+ tmp = simplify_gen_binary (PLUS, comp_mode, iv1.base, iv0.step);
+ tmp = lowpart_subreg (mode, tmp, comp_mode);
+ assumption = simplify_gen_relational (reverse_condition (cond),
+ SImode, mode, tmp0, tmp);
+
+ delta = simplify_gen_binary (PLUS, mode, tmp1, step);
+ delta = simplify_gen_binary (MINUS, mode, delta, tmp0);
+ }
+ else
+ {
+ /* Condition in shape a <= b - s * i
+ We must know that a - s does not overflow and a - s <= b and then
+ we can again compute number of iterations as (b - (a - s)) / s. */
+ step = simplify_gen_unary (NEG, mode, iv1.step, mode);
+ tmp0 = lowpart_subreg (mode, iv0.base, comp_mode);
+ tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
+
+ bound = simplify_gen_binary (MINUS, mode, mode_mmin,
+ lowpart_subreg (mode, step, comp_mode));
+ assumption = simplify_gen_relational (cond, SImode, mode,
+ bound, tmp0);
+ desc->assumptions =
+ alloc_EXPR_LIST (0, assumption, desc->assumptions);
+
+ tmp = simplify_gen_binary (PLUS, comp_mode, iv0.base, iv1.step);
+ tmp = lowpart_subreg (mode, tmp, comp_mode);
+ assumption = simplify_gen_relational (reverse_condition (cond),
+ SImode, mode,
+ tmp, tmp1);
+ delta = simplify_gen_binary (MINUS, mode, tmp0, step);
+ delta = simplify_gen_binary (MINUS, mode, tmp1, delta);
+ }
+ if (assumption == const_true_rtx)
+ goto zero_iter;
+ else if (assumption != const0_rtx)
+ desc->noloop_assumptions =
+ alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions);
+ delta = simplify_gen_binary (UDIV, mode, delta, step);
+ desc->niter_expr = delta;
+ }
+
+ simplify_using_initial_values (loop, AND, &desc->assumptions);
+ if (desc->assumptions
+ && XEXP (desc->assumptions, 0) == const0_rtx)
+ goto fail;
+ simplify_using_initial_values (loop, IOR, &desc->noloop_assumptions);
+ simplify_using_initial_values (loop, IOR, &desc->infinite);
+ simplify_using_initial_values (loop, NIL, &desc->niter_expr);
+
+ /* Rerun the simplification. Consider code (created by copying loop headers)
+
+ i = 0;
+
+ if (0 < n)
+ {
+ do
+ {
+ i++;
+ } while (i < n);
+ }
+
+ The first pass determines that i = 0, the second pass uses it to eliminate
+ noloop assumption. */
+
+ simplify_using_initial_values (loop, AND, &desc->assumptions);
+ if (desc->assumptions
+ && XEXP (desc->assumptions, 0) == const0_rtx)
+ goto fail;
+ simplify_using_initial_values (loop, IOR, &desc->noloop_assumptions);
+ simplify_using_initial_values (loop, IOR, &desc->infinite);
+ simplify_using_initial_values (loop, NIL, &desc->niter_expr);
+
+ if (desc->noloop_assumptions
+ && XEXP (desc->noloop_assumptions, 0) == const_true_rtx)
+ goto zero_iter;
+
+ if (GET_CODE (desc->niter_expr) == CONST_INT)
+ {
+ unsigned HOST_WIDEST_INT val = INTVAL (desc->niter_expr);
+
+ desc->const_iter = true;
+ desc->niter_max = desc->niter = val & GET_MODE_MASK (desc->mode);
+ }
+ else if (!desc->niter_max)
+ desc->niter_max = determine_max_iter (desc);
+
+ return;
+
+fail:
+ desc->simple_p = false;
+ return;
+
+zero_iter:
+ desc->const_iter = true;
+ desc->niter = 0;
+ desc->niter_max = 0;
+ desc->niter_expr = const0_rtx;
+ return;
+}
+
+/* Checks whether E is a simple exit from LOOP and stores its description
+ into DESC. */
+
+static void
+check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc)
+{
+ basic_block exit_bb;
+ rtx condition, at;
+ edge ei;
+
+ exit_bb = e->src;
+ desc->simple_p = false;
+
+ /* It must belong directly to the loop. */
+ if (exit_bb->loop_father != loop)
+ return;
+
+ /* It must be tested (at least) once during any iteration. */
+ if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit_bb))
+ return;
+
+ /* It must end in a simple conditional jump. */
+ if (!any_condjump_p (BB_END (exit_bb)))
+ return;
+
+ ei = exit_bb->succ;
+ if (ei == e)
+ ei = ei->succ_next;
+
+ desc->out_edge = e;
+ desc->in_edge = ei;
+
+ /* Test whether the condition is suitable. */
+ if (!(condition = get_condition (BB_END (ei->src), &at, false)))
+ return;
+
+ if (ei->flags & EDGE_FALLTHRU)
+ {
+ condition = reversed_condition (condition);
+ if (!condition)
+ return;
+ }
+
+ /* Check that we are able to determine number of iterations and fill
+ in information about it. */
+ iv_number_of_iterations (loop, at, condition, desc);
+}
+
+/* Finds a simple exit of LOOP and stores its description into DESC. */
+
+void
+find_simple_exit (struct loop *loop, struct niter_desc *desc)
+{
+ unsigned i;
+ basic_block *body;
+ edge e;
+ struct niter_desc act;
+ bool any = false;
+
+ desc->simple_p = false;
+ body = get_loop_body (loop);
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ for (e = body[i]->succ; e; e = e->succ_next)
+ {
+ if (flow_bb_inside_loop_p (loop, e->dest))
+ continue;
+
+ check_simple_exit (loop, e, &act);
+ if (!act.simple_p)
+ continue;
+
+ /* Prefer constant iterations; the less the better. */
+ if (!any)
+ any = true;
+ else if (!act.const_iter
+ || (desc->const_iter && act.niter >= desc->niter))
+ continue;
+ *desc = act;
+ }
+ }
+
+ if (dump_file)
+ {
+ if (desc->simple_p)
+ {
+ fprintf (dump_file, "Loop %d is simple:\n", loop->num);
+ fprintf (dump_file, " simple exit %d -> %d\n",
+ desc->out_edge->src->index,
+ desc->out_edge->dest->index);
+ if (desc->assumptions)
+ {
+ fprintf (dump_file, " assumptions: ");
+ print_rtl (dump_file, desc->assumptions);
+ fprintf (dump_file, "\n");
+ }
+ if (desc->noloop_assumptions)
+ {
+ fprintf (dump_file, " does not roll if: ");
+ print_rtl (dump_file, desc->noloop_assumptions);
+ fprintf (dump_file, "\n");
+ }
+ if (desc->infinite)
+ {
+ fprintf (dump_file, " infinite if: ");
+ print_rtl (dump_file, desc->infinite);
+ fprintf (dump_file, "\n");
+ }
+
+ fprintf (dump_file, " number of iterations: ");
+ print_rtl (dump_file, desc->niter_expr);
+ fprintf (dump_file, "\n");
+
+ fprintf (dump_file, " upper bound: ");
+ fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, desc->niter_max);
+ fprintf (dump_file, "\n");
+ }
+ else
+ fprintf (dump_file, "Loop %d is not simple.\n", loop->num);
+ }
+
+ free (body);
+}
+
+/* Creates a simple loop description of LOOP if it was not computed
+ already. */
+
+struct niter_desc *
+get_simple_loop_desc (struct loop *loop)
+{
+ struct niter_desc *desc = simple_loop_desc (loop);
+
+ if (desc)
+ return desc;
+
+ desc = xmalloc (sizeof (struct niter_desc));
+ iv_analysis_loop_init (loop);
+ find_simple_exit (loop, desc);
+ loop->aux = desc;
+
+ return desc;
+}
+
+/* Releases simple loop description for LOOP. */
+
+void
+free_simple_loop_desc (struct loop *loop)
+{
+ struct niter_desc *desc = simple_loop_desc (loop);
+
+ if (!desc)
+ return;
+
+ free (desc);
+ loop->aux = NULL;
+}
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
new file mode 100644
index 00000000000..d896757a578
--- /dev/null
+++ b/gcc/modulo-sched.c
@@ -0,0 +1,2136 @@
+/* Swing Modulo Scheduling implementation.
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.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 "toplev.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "regs.h"
+#include "function.h"
+#include "flags.h"
+#include "insn-config.h"
+#include "insn-attr.h"
+#include "except.h"
+#include "toplev.h"
+#include "recog.h"
+#include "sched-int.h"
+#include "target.h"
+#include "cfglayout.h"
+#include "cfgloop.h"
+#include "cfghooks.h"
+#include "expr.h"
+#include "params.h"
+#include "gcov-io.h"
+#include "df.h"
+#include "ddg.h"
+
+#ifdef INSN_SCHEDULING
+
+/* This file contains the implementation of the Swing Modulo Scheduler,
+ described in the following references:
+ [1] J. Llosa, A. Gonzalez, E. Ayguade, M. Valero., and J. Eckhardt.
+ Lifetime--sensitive modulo scheduling in a production environment.
+ IEEE Trans. on Comps., 50(3), March 2001
+ [2] J. Llosa, A. Gonzalez, E. Ayguade, and M. Valero.
+ Swing Modulo Scheduling: A Lifetime Sensitive Approach.
+ PACT '96 , pages 80-87, October 1996 (Boston - Massachusetts - USA).
+
+ The basic structure is:
+ 1. Build a data-dependence graph (DDG) for each loop.
+ 2. Use the DDG to order the insns of a loop (not in topological order
+ necessarily, but rather) trying to place each insn after all its
+ predecessors _or_ after all its successors.
+ 3. Compute MII: a lower bound on the number of cycles to schedule the loop.
+ 4. Use the ordering to perform list-scheduling of the loop:
+ 1. Set II = MII. We will try to schedule the loop within II cycles.
+ 2. Try to schedule the insns one by one according to the ordering.
+ For each insn compute an interval of cycles by considering already-
+ scheduled preds and succs (and associated latencies); try to place
+ the insn in the cycles of this window checking for potential
+ resource conflicts (using the DFA interface).
+ Note: this is different from the cycle-scheduling of schedule_insns;
+ here the insns are not scheduled monotonically top-down (nor bottom-
+ up).
+ 3. If failed in scheduling all insns - bump II++ and try again, unless
+ II reaches an upper bound MaxII, in which case report failure.
+ 5. If we succeeded in scheduling the loop within II cycles, we now
+ generate prolog and epilog, decrease the counter of the loop, and
+ perform modulo variable expansion for live ranges that span more than
+ II cycles (i.e. use register copies to prevent a def from overwriting
+ itself before reaching the use).
+*/
+
+
+/* This page defines partial-schedule structures and functions for
+ modulo scheduling. */
+
+typedef struct partial_schedule *partial_schedule_ptr;
+typedef struct ps_insn *ps_insn_ptr;
+
+/* The minimum (absolute) cycle that a node of ps was scheduled in. */
+#define PS_MIN_CYCLE(ps) (((partial_schedule_ptr)(ps))->min_cycle)
+
+/* The maximum (absolute) cycle that a node of ps was scheduled in. */
+#define PS_MAX_CYCLE(ps) (((partial_schedule_ptr)(ps))->max_cycle)
+
+/* Perform signed modulo, always returning a non-negative value. */
+#define SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y))
+
+/* The number of different iterations the nodes in ps span, assuming
+ the stage boundaries are placed efficiently. */
+#define PS_STAGE_COUNT(ps) ((PS_MAX_CYCLE (ps) - PS_MIN_CYCLE (ps) \
+ + 1 + (ps)->ii - 1) / (ps)->ii)
+
+#define CFG_HOOKS cfg_layout_rtl_cfg_hooks
+
+/* A single instruction in the partial schedule. */
+struct ps_insn
+{
+ /* The corresponding DDG_NODE. */
+ ddg_node_ptr node;
+
+ /* The (absolute) cycle in which the PS instruction is scheduled.
+ Same as SCHED_TIME (node). */
+ int cycle;
+
+ /* The next/prev PS_INSN in the same row. */
+ ps_insn_ptr next_in_row,
+ prev_in_row;
+
+ /* The number of nodes in the same row that come after this node. */
+ int row_rest_count;
+};
+
+/* Holds the partial schedule as an array of II rows. Each entry of the
+ array points to a linked list of PS_INSNs, which represents the
+ instructions that are scheduled for that row. */
+struct partial_schedule
+{
+ int ii; /* Number of rows in the partial schedule. */
+ int history; /* Threshold for conflict checking using DFA. */
+
+ /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii). */
+ ps_insn_ptr *rows;
+
+ /* The earliest absolute cycle of an insn in the partial schedule. */
+ int min_cycle;
+
+ /* The latest absolute cycle of an insn in the partial schedule. */
+ int max_cycle;
+
+ ddg_ptr g; /* The DDG of the insns in the partial schedule. */
+};
+
+
+partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history);
+void free_partial_schedule (partial_schedule_ptr);
+void reset_partial_schedule (partial_schedule_ptr, int new_ii);
+void print_partial_schedule (partial_schedule_ptr, FILE *);
+ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
+ ddg_node_ptr node, int cycle);
+void rotate_partial_schedule (partial_schedule_ptr, int);
+void set_row_column_for_ps (partial_schedule_ptr);
+
+
+/* This page defines constants and structures for the modulo scheduling
+ driver. */
+
+/* As in haifa-sched.c: */
+/* issue_rate is the number of insns that can be scheduled in the same
+ machine cycle. It can be defined in the config/mach/mach.h file,
+ otherwise we set it to 1. */
+
+static int issue_rate;
+
+/* For printing statistics. */
+static FILE *stats_file;
+
+static int sms_order_nodes (ddg_ptr, int, int * result);
+static void set_node_sched_params (ddg_ptr);
+static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int,
+ int *, FILE*);
+static void permute_partial_schedule (partial_schedule_ptr ps, rtx last);
+static void generate_prolog_epilog (partial_schedule_ptr, rtx, rtx, int);
+static void duplicate_insns_of_cycles (partial_schedule_ptr ps,
+ int from_stage, int to_stage,
+ int is_prolog);
+
+
+#define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap)
+#define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time)
+#define SCHED_FIRST_REG_MOVE(x) \
+ (((node_sched_params_ptr)(x)->aux.info)->first_reg_move)
+#define SCHED_NREG_MOVES(x) \
+ (((node_sched_params_ptr)(x)->aux.info)->nreg_moves)
+#define SCHED_ROW(x) (((node_sched_params_ptr)(x)->aux.info)->row)
+#define SCHED_STAGE(x) (((node_sched_params_ptr)(x)->aux.info)->stage)
+#define SCHED_COLUMN(x) (((node_sched_params_ptr)(x)->aux.info)->column)
+
+/* The scheduling parameters held for each node. */
+typedef struct node_sched_params
+{
+ int asap; /* A lower-bound on the absolute scheduling cycle. */
+ int time; /* The absolute scheduling cycle (time >= asap). */
+
+ /* The following field (first_reg_move) is a pointer to the first
+ register-move instruction added to handle the modulo-variable-expansion
+ of the register defined by this node. This register-move copies the
+ original register defined by the node. */
+ rtx first_reg_move;
+
+ /* The number of register-move instructions added, immediately preceding
+ first_reg_move. */
+ int nreg_moves;
+
+ int row; /* Holds time % ii. */
+ int stage; /* Holds time / ii. */
+
+ /* The column of a node inside the ps. If nodes u, v are on the same row,
+ u will precede v if column (u) < column (v). */
+ int column;
+} *node_sched_params_ptr;
+
+
+/* The following three functions are copied from the current scheduler
+ code in order to use sched_analyze() for computing the dependencies.
+ They are used when initializing the sched_info structure. */
+static const char *
+sms_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
+{
+ static char tmp[80];
+
+ sprintf (tmp, "i%4d", INSN_UID (insn));
+ return tmp;
+}
+
+static int
+contributes_to_priority (rtx next, rtx insn)
+{
+ return BLOCK_NUM (next) == BLOCK_NUM (insn);
+}
+
+static void
+compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
+ regset cond_exec ATTRIBUTE_UNUSED,
+ regset used ATTRIBUTE_UNUSED,
+ regset set ATTRIBUTE_UNUSED)
+{
+}
+
+static struct sched_info sms_sched_info =
+{
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sms_print_insn,
+ contributes_to_priority,
+ compute_jump_reg_dependencies,
+ NULL, NULL,
+ NULL, NULL,
+ 0, 0, 0
+};
+
+
+/* Return the register decremented and tested or zero if it is not a decrement
+ and branch jump insn (similar to doloop_condition_get). */
+static rtx
+doloop_register_get (rtx insn, rtx *comp)
+{
+ rtx pattern, cmp, inc, reg, condition;
+
+ if (GET_CODE (insn) != JUMP_INSN)
+ return NULL_RTX;
+ pattern = PATTERN (insn);
+
+ /* The canonical doloop pattern we expect is:
+
+ (parallel [(set (pc) (if_then_else (condition)
+ (label_ref (label))
+ (pc)))
+ (set (reg) (plus (reg) (const_int -1)))
+ (additional clobbers and uses)])
+
+ where condition is further restricted to be
+ (ne (reg) (const_int 1)). */
+
+ if (GET_CODE (pattern) != PARALLEL)
+ return NULL_RTX;
+
+ cmp = XVECEXP (pattern, 0, 0);
+ inc = XVECEXP (pattern, 0, 1);
+ /* Return the compare rtx. */
+ *comp = cmp;
+
+ /* Check for (set (reg) (something)). */
+ if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
+ return NULL_RTX;
+
+ /* Extract loop counter register. */
+ reg = SET_DEST (inc);
+
+ /* Check if something = (plus (reg) (const_int -1)). */
+ if (GET_CODE (SET_SRC (inc)) != PLUS
+ || XEXP (SET_SRC (inc), 0) != reg
+ || XEXP (SET_SRC (inc), 1) != constm1_rtx)
+ return NULL_RTX;
+
+ /* Check for (set (pc) (if_then_else (condition)
+ (label_ref (label))
+ (pc))). */
+ if (GET_CODE (cmp) != SET
+ || SET_DEST (cmp) != pc_rtx
+ || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
+ || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
+ || XEXP (SET_SRC (cmp), 2) != pc_rtx)
+ return NULL_RTX;
+
+ /* Extract loop termination condition. */
+ condition = XEXP (SET_SRC (cmp), 0);
+
+ /* Check if condition = (ne (reg) (const_int 1)), which is more
+ restrictive than the check in doloop_condition_get:
+ if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
+ || GET_CODE (XEXP (condition, 1)) != CONST_INT). */
+ if (GET_CODE (condition) != NE
+ || XEXP (condition, 1) != const1_rtx)
+ return NULL_RTX;
+
+ if (XEXP (condition, 0) == reg)
+ return reg;
+
+ return NULL_RTX;
+}
+
+/* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
+ that the number of iterations is a compile-time constant. If so,
+ return the rtx that sets COUNT_REG to a constant, and set COUNT to
+ this constant. Otherwise return 0. */
+static rtx
+const_iteration_count (rtx count_reg, basic_block pre_header,
+ HOST_WIDEST_INT * count)
+{
+ rtx insn;
+ rtx head, tail;
+ get_block_head_tail (pre_header->index, &head, &tail);
+
+ for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
+ if (INSN_P (insn) && single_set (insn) &&
+ rtx_equal_p (count_reg, SET_DEST (single_set (insn))))
+ {
+ rtx pat = single_set (insn);
+
+ if (GET_CODE (SET_SRC (pat)) == CONST_INT)
+ {
+ *count = INTVAL (SET_SRC (pat));
+ return insn;
+ }
+
+ return NULL_RTX;
+ }
+
+ return NULL_RTX;
+}
+
+/* A very simple resource-based lower bound on the initiation interval.
+ ??? Improve the accuracy of this bound by considering the
+ utilization of various units. */
+static int
+res_MII (ddg_ptr g)
+{
+ return (g->num_nodes / issue_rate);
+}
+
+
+/* Points to the array that contains the sched data for each node. */
+static node_sched_params_ptr node_sched_params;
+
+/* Allocate sched_params for each node and initialize it. Assumes that
+ the aux field of each node contain the asap bound (computed earlier),
+ and copies it into the sched_params field. */
+static void
+set_node_sched_params (ddg_ptr g)
+{
+ int i;
+
+ /* Allocate for each node in the DDG a place to hold the "sched_data". */
+ /* Initialize ASAP/ALAP/HIGHT to zero. */
+ node_sched_params = (node_sched_params_ptr)
+ xcalloc (g->num_nodes,
+ sizeof (struct node_sched_params));
+
+ /* Set the pointer of the general data of the node to point to the
+ appropriate sched_params structure. */
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ /* Watch out for aliasing problems? */
+ node_sched_params[i].asap = g->nodes[i].aux.count;
+ g->nodes[i].aux.info = &node_sched_params[i];
+ }
+}
+
+static void
+print_node_sched_params (FILE * dump_file, int num_nodes)
+{
+ int i;
+
+ for (i = 0; i < num_nodes; i++)
+ {
+ node_sched_params_ptr nsp = &node_sched_params[i];
+ rtx reg_move = nsp->first_reg_move;
+ int j;
+
+ fprintf (dump_file, "Node %d:\n", i);
+ fprintf (dump_file, " asap = %d:\n", nsp->asap);
+ fprintf (dump_file, " time = %d:\n", nsp->time);
+ fprintf (dump_file, " nreg_moves = %d:\n", nsp->nreg_moves);
+ for (j = 0; j < nsp->nreg_moves; j++)
+ {
+ fprintf (dump_file, " reg_move = ");
+ print_rtl_single (dump_file, reg_move);
+ reg_move = PREV_INSN (reg_move);
+ }
+ }
+}
+
+/* Calculate an upper bound for II. SMS should not schedule the loop if it
+ requires more cycles than this bound. Currently set to the sum of the
+ longest latency edge for each node. Reset based on experiments. */
+static int
+calculate_maxii (ddg_ptr g)
+{
+ int i;
+ int maxii = 0;
+
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_node_ptr u = &g->nodes[i];
+ ddg_edge_ptr e;
+ int max_edge_latency = 0;
+
+ for (e = u->out; e; e = e->next_out)
+ max_edge_latency = MAX (max_edge_latency, e->latency);
+
+ maxii += max_edge_latency;
+ }
+ return maxii;
+}
+
+
+/* Given the partial schedule, generate register moves when the length
+ of the register live range is more than ii; the number of moves is
+ determined according to the following equation:
+ SCHED_TIME (use) - SCHED_TIME (def) { 1 broken loop-carried
+ nreg_moves = ----------------------------------- - { dependence.
+ ii { 0 if not.
+ This handles the modulo-variable-expansions (mve's) needed for the ps. */
+static void
+generate_reg_moves (partial_schedule_ptr ps)
+{
+ ddg_ptr g = ps->g;
+ int ii = ps->ii;
+ int i;
+
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_node_ptr u = &g->nodes[i];
+ ddg_edge_ptr e;
+ int nreg_moves = 0, i_reg_move;
+ sbitmap *uses_of_defs;
+ rtx last_reg_move;
+ rtx prev_reg, old_reg;
+
+ /* Compute the number of reg_moves needed for u, by looking at life
+ ranges started at u (excluding self-loops). */
+ for (e = u->out; e; e = e->next_out)
+ if (e->type == TRUE_DEP && e->dest != e->src)
+ {
+ int nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
+
+ /* If dest precedes src in the schedule of the kernel, then dest
+ will read before src writes and we can save one reg_copy. */
+ if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
+ && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
+ nreg_moves4e--;
+
+ nreg_moves = MAX (nreg_moves, nreg_moves4e);
+ }
+
+ if (nreg_moves == 0)
+ continue;
+
+ /* Every use of the register defined by node may require a different
+ copy of this register, depending on the time the use is scheduled.
+ Set a bitmap vector, telling which nodes use each copy of this
+ register. */
+ uses_of_defs = sbitmap_vector_alloc (nreg_moves, g->num_nodes);
+ sbitmap_vector_zero (uses_of_defs, nreg_moves);
+ for (e = u->out; e; e = e->next_out)
+ if (e->type == TRUE_DEP && e->dest != e->src)
+ {
+ int dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
+
+ if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
+ && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
+ dest_copy--;
+
+ if (dest_copy)
+ SET_BIT (uses_of_defs[dest_copy - 1], e->dest->cuid);
+ }
+
+ /* Now generate the reg_moves, attaching relevant uses to them. */
+ SCHED_NREG_MOVES (u) = nreg_moves;
+ old_reg = prev_reg = copy_rtx (SET_DEST (single_set (u->insn)));
+ last_reg_move = u->insn;
+
+ for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
+ {
+ int i_use;
+ rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
+ rtx reg_move = gen_move_insn (new_reg, prev_reg);
+
+ add_insn_before (reg_move, last_reg_move);
+ last_reg_move = reg_move;
+
+ if (!SCHED_FIRST_REG_MOVE (u))
+ SCHED_FIRST_REG_MOVE (u) = reg_move;
+
+ EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use,
+ replace_rtx (g->nodes[i_use].insn, old_reg, new_reg));
+
+ prev_reg = new_reg;
+ }
+ }
+}
+
+/* Bump the SCHED_TIMEs of all nodes to start from zero. Set the values
+ of SCHED_ROW and SCHED_STAGE. */
+static void
+normalize_sched_times (partial_schedule_ptr ps)
+{
+ int i;
+ ddg_ptr g = ps->g;
+ int amount = PS_MIN_CYCLE (ps);
+ int ii = ps->ii;
+
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_node_ptr u = &g->nodes[i];
+ int normalized_time = SCHED_TIME (u) - amount;
+
+ if (normalized_time < 0)
+ abort ();
+
+ SCHED_TIME (u) = normalized_time;
+ SCHED_ROW (u) = normalized_time % ii;
+ SCHED_STAGE (u) = normalized_time / ii;
+ }
+}
+
+/* Set SCHED_COLUMN of each node according to its position in PS. */
+static void
+set_columns_for_ps (partial_schedule_ptr ps)
+{
+ int row;
+
+ for (row = 0; row < ps->ii; row++)
+ {
+ ps_insn_ptr cur_insn = ps->rows[row];
+ int column = 0;
+
+ for (; cur_insn; cur_insn = cur_insn->next_in_row)
+ SCHED_COLUMN (cur_insn->node) = column++;
+ }
+}
+
+/* Permute the insns according to their order in PS, from row 0 to
+ row ii-1, and position them right before LAST. This schedules
+ the insns of the loop kernel. */
+static void
+permute_partial_schedule (partial_schedule_ptr ps, rtx last)
+{
+ int ii = ps->ii;
+ int row;
+ ps_insn_ptr ps_ij;
+
+ for (row = 0; row < ii ; row++)
+ for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
+ if (PREV_INSN (last) != ps_ij->node->insn)
+ reorder_insns_nobb (ps_ij->node->first_note, ps_ij->node->insn,
+ PREV_INSN (last));
+}
+
+/* Used to generate the prologue & epilogue. Duplicate the subset of
+ nodes whose stages are between FROM_STAGE and TO_STAGE (inclusive
+ of both), together with a prefix/suffix of their reg_moves. */
+static void
+duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
+ int to_stage, int for_prolog)
+{
+ int row;
+ ps_insn_ptr ps_ij;
+
+ for (row = 0; row < ps->ii; row++)
+ for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
+ {
+ ddg_node_ptr u_node = ps_ij->node;
+ int j, i_reg_moves;
+ rtx reg_move = NULL_RTX;
+
+ if (for_prolog)
+ {
+ /* SCHED_STAGE (u_node) >= from_stage == 0. Generate increasing
+ number of reg_moves starting with the second occurrence of
+ u_node, which is generated if its SCHED_STAGE <= to_stage. */
+ i_reg_moves = to_stage - SCHED_STAGE (u_node);
+ i_reg_moves = MAX (i_reg_moves, 0);
+ i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
+
+ /* The reg_moves start from the *first* reg_move backwards. */
+ if (i_reg_moves)
+ {
+ reg_move = SCHED_FIRST_REG_MOVE (u_node);
+ for (j = 1; j < i_reg_moves; j++)
+ reg_move = PREV_INSN (reg_move);
+ }
+ }
+ else /* It's for the epilog. */
+ {
+ /* SCHED_STAGE (u_node) <= to_stage. Generate all reg_moves,
+ starting to decrease one stage after u_node no longer occurs;
+ that is, generate all reg_moves until
+ SCHED_STAGE (u_node) == from_stage - 1. */
+ i_reg_moves = SCHED_NREG_MOVES (u_node)
+ - (from_stage - SCHED_STAGE (u_node) - 1);
+ i_reg_moves = MAX (i_reg_moves, 0);
+ i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
+
+ /* The reg_moves start from the *last* reg_move forwards. */
+ if (i_reg_moves)
+ {
+ reg_move = SCHED_FIRST_REG_MOVE (u_node);
+ for (j = 1; j < SCHED_NREG_MOVES (u_node); j++)
+ reg_move = PREV_INSN (reg_move);
+ }
+ }
+
+ for (j = 0; j < i_reg_moves; j++, reg_move = NEXT_INSN (reg_move))
+ emit_insn (copy_rtx (PATTERN (reg_move)));
+
+ if (SCHED_STAGE (u_node) >= from_stage
+ && SCHED_STAGE (u_node) <= to_stage)
+ duplicate_insn_chain (u_node->first_note, u_node->insn);
+ }
+}
+
+
+/* Generate the instructions (including reg_moves) for prolog & epilog. */
+static void
+generate_prolog_epilog (partial_schedule_ptr ps, rtx orig_loop_beg,
+ rtx orig_loop_end, int unknown_count)
+{
+ int i;
+ int last_stage = PS_STAGE_COUNT (ps) - 1;
+ edge e;
+ rtx c_reg = NULL_RTX;
+ rtx cmp = NULL_RTX;
+ rtx precond_jump = NULL_RTX;
+ rtx precond_exit_label = NULL_RTX;
+ rtx precond_exit_label_insn = NULL_RTX;
+ rtx last_epilog_insn = NULL_RTX;
+ rtx loop_exit_label = NULL_RTX;
+ rtx loop_exit_label_insn = NULL_RTX;
+ rtx orig_loop_bct = NULL_RTX;
+
+ /* Loop header edge. */
+ e = ps->g->bb->pred;
+ if (e->src == ps->g->bb)
+ e = e->pred_next;
+
+ /* Generate the prolog, inserting its insns on the loop-entry edge. */
+ start_sequence ();
+
+ /* This is the place where we want to insert the precondition. */
+ if (unknown_count)
+ precond_jump = emit_note (NOTE_INSN_DELETED);
+
+ for (i = 0; i < last_stage; i++)
+ duplicate_insns_of_cycles (ps, 0, i, 1);
+
+ /* No need to call insert_insn_on_edge; we prepared the sequence. */
+ e->insns.r = get_insns ();
+ end_sequence ();
+
+ /* Generate the epilog, inserting its insns on the loop-exit edge. */
+ start_sequence ();
+
+ for (i = 0; i < last_stage; i++)
+ duplicate_insns_of_cycles (ps, i + 1, last_stage, 0);
+
+ last_epilog_insn = emit_note (NOTE_INSN_DELETED);
+
+ /* Emit the label where to put the original loop code. */
+ if (unknown_count)
+ {
+ rtx label, cond;
+
+ precond_exit_label = gen_label_rtx ();
+ precond_exit_label_insn = emit_label (precond_exit_label);
+
+ /* Put the original loop code. */
+ reorder_insns_nobb (orig_loop_beg, orig_loop_end, precond_exit_label_insn);
+
+ /* Change the label of the BCT to be the PRECOND_EXIT_LABEL. */
+ orig_loop_bct = get_last_insn ();
+ c_reg = doloop_register_get (orig_loop_bct, &cmp);
+ label = XEXP (SET_SRC (cmp), 1);
+ cond = XEXP (SET_SRC (cmp), 0);
+
+ if (! c_reg || GET_CODE (cond) != NE)
+ abort ();
+
+ XEXP (label, 0) = precond_exit_label;
+ JUMP_LABEL (orig_loop_bct) = precond_exit_label_insn;
+ LABEL_NUSES (precond_exit_label_insn)++;
+
+ /* Generate the loop exit label. */
+ loop_exit_label = gen_label_rtx ();
+ loop_exit_label_insn = emit_label (loop_exit_label);
+ }
+
+ e = ps->g->bb->succ;
+ if (e->dest == ps->g->bb)
+ e = e->succ_next;
+
+ e->insns.r = get_insns ();
+ end_sequence ();
+
+ commit_edge_insertions ();
+
+ if (unknown_count)
+ {
+ rtx precond_insns, epilog_jump, insert_after_insn;
+ basic_block loop_exit_bb = BLOCK_FOR_INSN (loop_exit_label_insn);
+ basic_block epilog_bb = BLOCK_FOR_INSN (last_epilog_insn);
+ basic_block precond_bb = BLOCK_FOR_INSN (precond_jump);
+ basic_block orig_loop_bb = BLOCK_FOR_INSN (precond_exit_label_insn);
+ edge epilog_exit_edge = epilog_bb->succ;
+
+ /* Do loop preconditioning to take care of cases were the loop count is
+ less than the stage count. Update the CFG properly. */
+ insert_after_insn = precond_jump;
+ start_sequence ();
+ c_reg = doloop_register_get (ps->g->closing_branch->insn, &cmp);
+ emit_cmp_and_jump_insns (c_reg, GEN_INT (PS_STAGE_COUNT (ps)), LT, NULL,
+ GET_MODE (c_reg), 1, precond_exit_label);
+ precond_insns = get_insns ();
+ precond_jump = get_last_insn ();
+ end_sequence ();
+ reorder_insns (precond_insns, precond_jump, insert_after_insn);
+
+ /* Generate a subtract instruction at the beginning of the prolog to
+ adjust the loop count by STAGE_COUNT. */
+ emit_insn_after (gen_sub2_insn (c_reg, GEN_INT (PS_STAGE_COUNT (ps) - 1)),
+ precond_jump);
+ update_bb_for_insn (precond_bb);
+ delete_insn (insert_after_insn);
+
+ /* Update label info for the precondition jump. */
+ JUMP_LABEL (precond_jump) = precond_exit_label_insn;
+ LABEL_NUSES (precond_exit_label_insn)++;
+
+ /* Update the CFG. */
+ split_block (precond_bb, precond_jump);
+ make_edge (precond_bb, orig_loop_bb, 0);
+
+ /* Add a jump at end of the epilog to the LOOP_EXIT_LABEL to jump over the
+ original loop copy and update the CFG. */
+ epilog_jump = emit_jump_insn_after (gen_jump (loop_exit_label),
+ last_epilog_insn);
+ delete_insn (last_epilog_insn);
+ JUMP_LABEL (epilog_jump) = loop_exit_label_insn;
+ LABEL_NUSES (loop_exit_label_insn)++;
+
+ redirect_edge_succ (epilog_exit_edge, loop_exit_bb);
+ epilog_exit_edge->flags &= ~EDGE_FALLTHRU;
+ emit_barrier_after (BB_END (epilog_bb));
+ }
+}
+
+/* Return the line note insn preceding INSN, for debugging. Taken from
+ emit-rtl.c. */
+static rtx
+find_line_note (rtx insn)
+{
+ for (; insn; insn = PREV_INSN (insn))
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) >= 0)
+ break;
+
+ return insn;
+}
+
+/* Main entry point, perform SMS scheduling on the loops of the function
+ that consist of single basic blocks. */
+void
+sms_schedule (FILE *dump_file)
+{
+ static int passes = 0;
+ rtx insn;
+ ddg_ptr *g_arr, g;
+ basic_block bb, pre_header = NULL;
+ int * node_order;
+ int maxii;
+ int i;
+ partial_schedule_ptr ps;
+ int max_bb_index = last_basic_block;
+ struct df *df;
+
+ /* SMS uses the DFA interface. */
+ if (! targetm.sched.use_dfa_pipeline_interface
+ || ! (*targetm.sched.use_dfa_pipeline_interface) ())
+ return;
+
+ stats_file = dump_file;
+
+
+ /* Initialize issue_rate. */
+ if (targetm.sched.issue_rate)
+ {
+ int temp = reload_completed;
+
+ reload_completed = 1;
+ issue_rate = (*targetm.sched.issue_rate) ();
+ reload_completed = temp;
+ }
+ else
+ issue_rate = 1;
+
+ /* Initialize the scheduler. */
+ current_sched_info = &sms_sched_info;
+ sched_init (NULL);
+
+ /* Init Data Flow analysis, to be used in interloop dep calculation. */
+ df = df_init ();
+ df_analyze (df, 0, DF_ALL);
+
+ /* Allocate memory to hold the DDG array. */
+ g_arr = xcalloc (max_bb_index, sizeof (ddg_ptr));
+
+ /* Build DDGs for all the relevant loops and hold them in G_ARR
+ indexed by the loop BB index. */
+ FOR_EACH_BB (bb)
+ {
+ rtx head, tail;
+ rtx count_reg, comp;
+ edge e, pre_header_edge;
+
+ if (bb->index < 0)
+ continue;
+
+ /* Check if bb has two successors, one being itself. */
+ e = bb->succ;
+ if (!e || !e->succ_next || e->succ_next->succ_next)
+ continue;
+
+ if (e->dest != bb && e->succ_next->dest != bb)
+ continue;
+
+ if ((e->flags & EDGE_COMPLEX)
+ || (e->succ_next->flags & EDGE_COMPLEX))
+ continue;
+
+ /* Check if bb has two predecessors, one being itself. */
+ /* In view of above tests, suffices to check e->pred_next->pred_next? */
+ e = bb->pred;
+ if (!e || !e->pred_next || e->pred_next->pred_next)
+ continue;
+
+ if (e->src != bb && e->pred_next->src != bb)
+ continue;
+
+ if ((e->flags & EDGE_COMPLEX)
+ || (e->pred_next->flags & EDGE_COMPLEX))
+ continue;
+
+ /* For debugging. */
+ if (passes++ > MAX_SMS_LOOP_NUMBER && MAX_SMS_LOOP_NUMBER != -1)
+ {
+ if (dump_file)
+ fprintf (dump_file, "SMS reached MAX_PASSES... \n");
+ break;
+ }
+
+ get_block_head_tail (bb->index, &head, &tail);
+ pre_header_edge = bb->pred;
+ if (bb->pred->src != bb)
+ pre_header_edge = bb->pred->pred_next;
+
+ /* Perfrom SMS only on loops that their average count is above threshold. */
+ if (bb->count < pre_header_edge->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD)
+ {
+ if (stats_file)
+ {
+ rtx line_note = find_line_note (tail);
+
+ if (line_note)
+ {
+ expanded_location xloc;
+ NOTE_EXPANDED_LOCATION (xloc, line_note);
+ fprintf (stats_file, "SMS bb %s %d (file, line)\n",
+ xloc.file, xloc.line);
+ }
+ fprintf (stats_file, "SMS single-bb-loop\n");
+ if (profile_info && flag_branch_probabilities)
+ {
+ fprintf (stats_file, "SMS loop-count ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) bb->count);
+ fprintf (stats_file, "\n");
+ fprintf (stats_file, "SMS preheader-count ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) pre_header_edge->count);
+ fprintf (stats_file, "\n");
+ fprintf (stats_file, "SMS profile-sum-max ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) profile_info->sum_max);
+ fprintf (stats_file, "\n");
+ }
+ }
+ continue;
+ }
+
+ /* Make sure this is a doloop. */
+ if ( !(count_reg = doloop_register_get (tail, &comp)))
+ continue;
+
+ e = bb->pred;
+ if (e->src == bb)
+ pre_header = e->pred_next->src;
+ else
+ pre_header = e->src;
+
+ /* Don't handle BBs with calls or barriers, or !single_set insns. */
+ for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == CALL_INSN
+ || GET_CODE (insn) == BARRIER
+ || (INSN_P (insn) && GET_CODE (insn) != JUMP_INSN
+ && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
+ break;
+
+ if (insn != NEXT_INSN (tail))
+ {
+ if (stats_file)
+ {
+ if (GET_CODE (insn) == CALL_INSN)
+ fprintf (stats_file, "SMS loop-with-call\n");
+ else if (GET_CODE (insn) == BARRIER)
+ fprintf (stats_file, "SMS loop-with-barrier\n");
+ else
+ fprintf (stats_file, "SMS loop-with-not-single-set\n");
+ print_rtl_single (stats_file, insn);
+ }
+
+ continue;
+ }
+
+ if (! (g = create_ddg (bb, df, 0)))
+ {
+ if (stats_file)
+ fprintf (stats_file, "SMS doloop\n");
+ continue;
+ }
+
+ g_arr[bb->index] = g;
+ }
+
+ /* Release Data Flow analysis data structures. */
+ df_finish (df);
+
+ /* Go over the built DDGs and perfrom SMS for each one of them. */
+ for (i = 0; i < max_bb_index; i++)
+ {
+ rtx head, tail;
+ rtx count_reg, count_init, comp;
+ edge pre_header_edge;
+ int mii, rec_mii;
+ int stage_count = 0;
+ HOST_WIDEST_INT loop_count = 0;
+
+ if (! (g = g_arr[i]))
+ continue;
+
+ if (dump_file)
+ print_ddg (dump_file, g);
+
+ get_block_head_tail (g->bb->index, &head, &tail);
+
+ pre_header_edge = g->bb->pred;
+ if (g->bb->pred->src != g->bb)
+ pre_header_edge = g->bb->pred->pred_next;
+
+ if (stats_file)
+ {
+ rtx line_note = find_line_note (tail);
+
+ if (line_note)
+ {
+ expanded_location xloc;
+ NOTE_EXPANDED_LOCATION (xloc, line_note);
+ fprintf (stats_file, "SMS bb %s %d (file, line)\n",
+ xloc.file, xloc.line);
+ }
+ fprintf (stats_file, "SMS single-bb-loop\n");
+ if (profile_info && flag_branch_probabilities)
+ {
+ fprintf (stats_file, "SMS loop-count ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) bb->count);
+ fprintf (stats_file, "\n");
+ fprintf (stats_file, "SMS preheader-count ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) pre_header_edge->count);
+ fprintf (stats_file, "\n");
+ fprintf (stats_file, "SMS profile-sum-max ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) profile_info->sum_max);
+ fprintf (stats_file, "\n");
+ }
+ fprintf (stats_file, "SMS doloop\n");
+ fprintf (stats_file, "SMS built-ddg %d\n", g->num_nodes);
+ fprintf (stats_file, "SMS num-loads %d\n", g->num_loads);
+ fprintf (stats_file, "SMS num-stores %d\n", g->num_stores);
+ }
+
+ /* Make sure this is a doloop. */
+ if ( !(count_reg = doloop_register_get (tail, &comp)))
+ abort ();
+
+ /* This should be NULL_RTX if the count is unknown at compile time. */
+ count_init = const_iteration_count (count_reg, pre_header, &loop_count);
+
+ if (stats_file && count_init)
+ {
+ fprintf (stats_file, "SMS const-doloop ");
+ fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
+ fprintf (stats_file, "\n");
+ }
+
+ node_order = (int *) xmalloc (sizeof (int) * g->num_nodes);
+
+ mii = 1; /* Need to pass some estimate of mii. */
+ rec_mii = sms_order_nodes (g, mii, node_order);
+ mii = MAX (res_MII (g), rec_mii);
+ maxii = (calculate_maxii (g) * SMS_MAX_II_FACTOR) / 100;
+
+ if (stats_file)
+ fprintf (stats_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
+ rec_mii, mii, maxii);
+
+ /* After sms_order_nodes and before sms_schedule_by_order, to copy over
+ ASAP. */
+ set_node_sched_params (g);
+
+ ps = sms_schedule_by_order (g, mii, maxii, node_order, dump_file);
+
+ if (ps)
+ stage_count = PS_STAGE_COUNT (ps);
+
+ if (stage_count == 0 || (count_init && (stage_count > loop_count)))
+ {
+ if (dump_file)
+ fprintf (dump_file, "SMS failed... \n");
+ if (stats_file)
+ fprintf (stats_file, "SMS sched-failed %d\n", stage_count);
+ }
+ else
+ {
+ rtx orig_loop_beg = NULL_RTX;
+ rtx orig_loop_end = NULL_RTX;
+
+ if (stats_file)
+ {
+ fprintf (stats_file,
+ "SMS succeeded %d %d (with ii, sc)\n", ps->ii,
+ stage_count);
+ print_partial_schedule (ps, dump_file);
+ fprintf (dump_file,
+ "SMS Branch (%d) will later be scheduled at cycle %d.\n",
+ g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1);
+ }
+
+ /* Save the original loop if we want to do loop preconditioning in
+ case the BCT count is not known. */
+ if (! count_init)
+ {
+ int i;
+
+ start_sequence ();
+ /* Copy the original loop code before modifying it - so we can use
+ it later. */
+ for (i = 0; i < ps->g->num_nodes; i++)
+ duplicate_insn_chain (ps->g->nodes[i].first_note,
+ ps->g->nodes[i].insn);
+
+ orig_loop_beg = get_insns ();
+ orig_loop_end = get_last_insn ();
+ end_sequence ();
+ }
+ /* Set the stage boundaries. If the DDG is built with closing_branch_deps,
+ the closing_branch was scheduled and should appear in the last (ii-1)
+ row. Otherwise, we are free to schedule the branch, and we let nodes
+ that were scheduled at the first PS_MIN_CYCLE cycle appear in the first
+ row; this should reduce stage_count to minimum. */
+ normalize_sched_times (ps);
+ rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
+ set_columns_for_ps (ps);
+
+ permute_partial_schedule (ps, g->closing_branch->first_note);
+ generate_reg_moves (ps);
+ if (dump_file)
+ print_node_sched_params (dump_file, g->num_nodes);
+
+ /* Set new iteration count of loop kernel. */
+ if (count_init)
+ SET_SRC (single_set (count_init)) = GEN_INT (loop_count
+ - stage_count + 1);
+
+ /* Generate prolog and epilog. */
+ generate_prolog_epilog (ps, orig_loop_beg, orig_loop_end,
+ count_init ? 0 : 1);
+ }
+ free_partial_schedule (ps);
+ free (node_sched_params);
+ free (node_order);
+ free_ddg (g);
+ }
+
+ /* Release scheduler data, needed until now because of DFA. */
+ sched_finish ();
+}
+
+/* The SMS scheduling algorithm itself
+ -----------------------------------
+ Input: 'O' an ordered list of insns of a loop.
+ Output: A scheduling of the loop - kernel, prolog, and epilogue.
+
+ 'Q' is the empty Set
+ 'PS' is the partial schedule; it holds the currently scheduled nodes with
+ their cycle/slot.
+ 'PSP' previously scheduled predecessors.
+ 'PSS' previously scheduled successors.
+ 't(u)' the cycle where u is scheduled.
+ 'l(u)' is the latency of u.
+ 'd(v,u)' is the dependence distance from v to u.
+ 'ASAP(u)' the earliest time at which u could be scheduled as computed in
+ the node ordering phase.
+ 'check_hardware_resources_conflicts(u, PS, c)'
+ run a trace around cycle/slot through DFA model
+ to check resource conflicts involving instruction u
+ at cycle c given the partial schedule PS.
+ 'add_to_partial_schedule_at_time(u, PS, c)'
+ Add the node/instruction u to the partial schedule
+ PS at time c.
+ 'calculate_register_pressure(PS)'
+ Given a schedule of instructions, calculate the register
+ pressure it implies. One implementation could be the
+ maximum number of overlapping live ranges.
+ 'maxRP' The maximum allowed register pressure, it is usually derived from the number
+ registers available in the hardware.
+
+ 1. II = MII.
+ 2. PS = empty list
+ 3. for each node u in O in pre-computed order
+ 4. if (PSP(u) != Q && PSS(u) == Q) then
+ 5. Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
+ 6. start = Early_start; end = Early_start + II - 1; step = 1
+ 11. else if (PSP(u) == Q && PSS(u) != Q) then
+ 12. Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
+ 13. start = Late_start; end = Late_start - II + 1; step = -1
+ 14. else if (PSP(u) != Q && PSS(u) != Q) then
+ 15. Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
+ 16. Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
+ 17. start = Early_start;
+ 18. end = min(Early_start + II - 1 , Late_start);
+ 19. step = 1
+ 20. else "if (PSP(u) == Q && PSS(u) == Q)"
+ 21. start = ASAP(u); end = start + II - 1; step = 1
+ 22. endif
+
+ 23. success = false
+ 24. for (c = start ; c != end ; c += step)
+ 25. if check_hardware_resources_conflicts(u, PS, c) then
+ 26. add_to_partial_schedule_at_time(u, PS, c)
+ 27. success = true
+ 28. break
+ 29. endif
+ 30. endfor
+ 31. if (success == false) then
+ 32. II = II + 1
+ 33. if (II > maxII) then
+ 34. finish - failed to schedule
+ 35. endif
+ 36. goto 2.
+ 37. endif
+ 38. endfor
+ 39. if (calculate_register_pressure(PS) > maxRP) then
+ 40. goto 32.
+ 41. endif
+ 42. compute epilogue & prologue
+ 43. finish - succeeded to schedule
+*/
+
+/* A limit on the number of cycles that resource conflicts can span. ??? Should
+ be provided by DFA, and be dependent on the type of insn scheduled. Currently
+ set to 0 to save compile time. */
+#define DFA_HISTORY SMS_DFA_HISTORY
+
+static partial_schedule_ptr
+sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *dump_file)
+{
+ int ii = mii;
+ int i, c, success;
+ int try_again_with_larger_ii = true;
+ int num_nodes = g->num_nodes;
+ ddg_edge_ptr e;
+ int start, end, step; /* Place together into one struct? */
+ sbitmap sched_nodes = sbitmap_alloc (num_nodes);
+ sbitmap psp = sbitmap_alloc (num_nodes);
+ sbitmap pss = sbitmap_alloc (num_nodes);
+ partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
+
+ while (try_again_with_larger_ii && ii < maxii)
+ {
+ if (dump_file)
+ fprintf(dump_file, "Starting with ii=%d\n", ii);
+ try_again_with_larger_ii = false;
+ sbitmap_zero (sched_nodes);
+
+ for (i = 0; i < num_nodes; i++)
+ {
+ int u = nodes_order[i];
+ ddg_node_ptr u_node = &g->nodes[u];
+ sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
+ sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
+ int psp_not_empty;
+ int pss_not_empty;
+ rtx insn = u_node->insn;
+
+ if (!INSN_P (insn))
+ continue;
+
+ if (GET_CODE (insn) == JUMP_INSN) /* Closing branch handled later. */
+ continue;
+
+ /* 1. compute sched window for u (start, end, step). */
+ sbitmap_zero (psp);
+ sbitmap_zero (pss);
+ psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
+ pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
+
+ if (psp_not_empty && !pss_not_empty)
+ {
+ int early_start = 0;
+
+ end = INT_MAX;
+ for (e = u_node->in; e != 0; e = e->next_in)
+ {
+ ddg_node_ptr v_node = e->src;
+ if (TEST_BIT (sched_nodes, v_node->cuid))
+ {
+ early_start = MAX (early_start,
+ SCHED_TIME (v_node)
+ + e->latency - (e->distance * ii));
+ if (e->data_type == MEM_DEP)
+ end = MIN (end, SCHED_TIME (v_node) + ii - 1);
+ }
+ }
+ start = early_start;
+ end = MIN (end, early_start + ii);
+ step = 1;
+ }
+
+ else if (!psp_not_empty && pss_not_empty)
+ {
+ int late_start = INT_MAX;
+
+ end = INT_MIN;
+ for (e = u_node->out; e != 0; e = e->next_out)
+ {
+ ddg_node_ptr v_node = e->dest;
+ if (TEST_BIT (sched_nodes, v_node->cuid))
+ {
+ late_start = MIN (late_start,
+ SCHED_TIME (v_node) - e->latency
+ + (e->distance * ii));
+ if (e->data_type == MEM_DEP)
+ end = MAX (end, SCHED_TIME (v_node) - ii + 1);
+ }
+ }
+ start = late_start;
+ end = MAX (end, late_start - ii);
+ step = -1;
+ }
+
+ else if (psp_not_empty && pss_not_empty)
+ {
+ int early_start = 0;
+ int late_start = INT_MAX;
+
+ start = INT_MIN;
+ end = INT_MAX;
+ for (e = u_node->in; e != 0; e = e->next_in)
+ {
+ ddg_node_ptr v_node = e->src;
+
+ if (TEST_BIT (sched_nodes, v_node->cuid))
+ {
+ early_start = MAX (early_start,
+ SCHED_TIME (v_node) + e->latency
+ - (e->distance * ii));
+ if (e->data_type == MEM_DEP)
+ end = MIN (end, SCHED_TIME (v_node) + ii - 1);
+ }
+ }
+ for (e = u_node->out; e != 0; e = e->next_out)
+ {
+ ddg_node_ptr v_node = e->dest;
+
+ if (TEST_BIT (sched_nodes, v_node->cuid))
+ {
+ late_start = MIN (late_start,
+ SCHED_TIME (v_node) - e->latency
+ + (e->distance * ii));
+ if (e->data_type == MEM_DEP)
+ start = MAX (start, SCHED_TIME (v_node) - ii + 1);
+ }
+ }
+ start = MAX (start, early_start);
+ end = MIN (end, MIN (early_start + ii, late_start + 1));
+ step = 1;
+ }
+ else /* psp is empty && pss is empty. */
+ {
+ start = SCHED_ASAP (u_node);
+ end = start + ii;
+ step = 1;
+ }
+
+ /* 2. Try scheduling u in window. */
+ if (dump_file)
+ fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n",
+ u, start, end, step);
+
+ success = 0;
+ if ((step > 0 && start < end) || (step < 0 && start > end))
+ for (c = start; c != end; c += step)
+ {
+ ps_insn_ptr psi = ps_add_node_check_conflicts (ps, u_node, c);
+
+ if (psi)
+ {
+ SCHED_TIME (u_node) = c;
+ SET_BIT (sched_nodes, u);
+ success = 1;
+ if (dump_file)
+ fprintf(dump_file, "Schedule in %d\n", c);
+ break;
+ }
+ }
+ if (!success)
+ {
+ /* ??? Try backtracking instead of immediately ii++? */
+ ii++;
+ try_again_with_larger_ii = true;
+ reset_partial_schedule (ps, ii);
+ break;
+ }
+ /* ??? If (success), check register pressure estimates. */
+ } /* Continue with next node. */
+ } /* While try_again_with_larger_ii. */
+
+ sbitmap_free (sched_nodes);
+ sbitmap_free (psp);
+ sbitmap_free (pss);
+
+ if (ii >= maxii)
+ {
+ free_partial_schedule (ps);
+ ps = NULL;
+ }
+ return ps;
+}
+
+
+/* This page implements the algorithm for ordering the nodes of a DDG
+ for modulo scheduling, activated through the
+ "int sms_order_nodes (ddg_ptr, int mii, int * result)" API. */
+
+#define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
+#define ASAP(x) (ORDER_PARAMS ((x))->asap)
+#define ALAP(x) (ORDER_PARAMS ((x))->alap)
+#define HEIGHT(x) (ORDER_PARAMS ((x))->height)
+#define MOB(x) (ALAP ((x)) - ASAP ((x)))
+#define DEPTH(x) (ASAP ((x)))
+
+typedef struct node_order_params * nopa;
+
+static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
+static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
+static nopa calculate_order_params (ddg_ptr, int mii);
+static int find_max_asap (ddg_ptr, sbitmap);
+static int find_max_hv_min_mob (ddg_ptr, sbitmap);
+static int find_max_dv_min_mob (ddg_ptr, sbitmap);
+
+enum sms_direction {BOTTOMUP, TOPDOWN};
+
+struct node_order_params
+{
+ int asap;
+ int alap;
+ int height;
+};
+
+/* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1. */
+static void
+check_nodes_order (int *node_order, int num_nodes)
+{
+ int i;
+ sbitmap tmp = sbitmap_alloc (num_nodes);
+
+ sbitmap_zero (tmp);
+
+ for (i = 0; i < num_nodes; i++)
+ {
+ int u = node_order[i];
+
+ if (u >= num_nodes || u < 0 || TEST_BIT (tmp, u))
+ abort ();
+
+ SET_BIT (tmp, u);
+ }
+
+ sbitmap_free (tmp);
+}
+
+/* Order the nodes of G for scheduling and pass the result in
+ NODE_ORDER. Also set aux.count of each node to ASAP.
+ Return the recMII for the given DDG. */
+static int
+sms_order_nodes (ddg_ptr g, int mii, int * node_order)
+{
+ int i;
+ int rec_mii = 0;
+ ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
+
+ nopa nops = calculate_order_params (g, mii);
+
+ order_nodes_of_sccs (sccs, node_order);
+
+ if (sccs->num_sccs > 0)
+ /* First SCC has the largest recurrence_length. */
+ rec_mii = sccs->sccs[0]->recurrence_length;
+
+ /* Save ASAP before destroying node_order_params. */
+ for (i = 0; i < g->num_nodes; i++)
+ {
+ ddg_node_ptr v = &g->nodes[i];
+ v->aux.count = ASAP (v);
+ }
+
+ free (nops);
+ free_ddg_all_sccs (sccs);
+ check_nodes_order (node_order, g->num_nodes);
+
+ return rec_mii;
+}
+
+static void
+order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
+{
+ int i, pos = 0;
+ ddg_ptr g = all_sccs->ddg;
+ int num_nodes = g->num_nodes;
+ sbitmap prev_sccs = sbitmap_alloc (num_nodes);
+ sbitmap on_path = sbitmap_alloc (num_nodes);
+ sbitmap tmp = sbitmap_alloc (num_nodes);
+ sbitmap ones = sbitmap_alloc (num_nodes);
+
+ sbitmap_zero (prev_sccs);
+ sbitmap_ones (ones);
+
+ /* Perfrom the node ordering starting from the SCC with the highest recMII.
+ For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc. */
+ for (i = 0; i < all_sccs->num_sccs; i++)
+ {
+ ddg_scc_ptr scc = all_sccs->sccs[i];
+
+ /* Add nodes on paths from previous SCCs to the current SCC. */
+ find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
+ sbitmap_a_or_b (tmp, scc->nodes, on_path);
+
+ /* Add nodes on paths from the current SCC to previous SCCs. */
+ find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
+ sbitmap_a_or_b (tmp, tmp, on_path);
+
+ /* Remove nodes of previous SCCs from current extended SCC. */
+ sbitmap_difference (tmp, tmp, prev_sccs);
+
+ pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
+ /* Above call to order_nodes_in_scc updated prev_sccs |= tmp. */
+ }
+
+ /* Handle the remaining nodes that do not belong to any scc. Each call
+ to order_nodes_in_scc handles a single connected component. */
+ while (pos < g->num_nodes)
+ {
+ sbitmap_difference (tmp, ones, prev_sccs);
+ pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
+ }
+ sbitmap_free (prev_sccs);
+ sbitmap_free (on_path);
+ sbitmap_free (tmp);
+ sbitmap_free (ones);
+}
+
+/* MII is needed if we consider backarcs (that do not close recursive cycles). */
+static struct node_order_params *
+calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED)
+{
+ int u;
+ int max_asap;
+ int num_nodes = g->num_nodes;
+ ddg_edge_ptr e;
+ /* Allocate a place to hold ordering params for each node in the DDG. */
+ nopa node_order_params_arr;
+
+ /* Initialize of ASAP/ALAP/HEIGHT to zero. */
+ node_order_params_arr = (nopa) xcalloc (num_nodes,
+ sizeof (struct node_order_params));
+
+ /* Set the aux pointer of each node to point to its order_params structure. */
+ for (u = 0; u < num_nodes; u++)
+ g->nodes[u].aux.info = &node_order_params_arr[u];
+
+ /* Disregarding a backarc from each recursive cycle to obtain a DAG,
+ calculate ASAP, ALAP, mobility, distance, and height for each node
+ in the dependence (direct acyclic) graph. */
+
+ /* We assume that the nodes in the array are in topological order. */
+
+ max_asap = 0;
+ for (u = 0; u < num_nodes; u++)
+ {
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ ASAP (u_node) = 0;
+ for (e = u_node->in; e; e = e->next_in)
+ if (e->distance == 0)
+ ASAP (u_node) = MAX (ASAP (u_node),
+ ASAP (e->src) + e->latency);
+ max_asap = MAX (max_asap, ASAP (u_node));
+ }
+
+ for (u = num_nodes - 1; u > -1; u--)
+ {
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ ALAP (u_node) = max_asap;
+ HEIGHT (u_node) = 0;
+ for (e = u_node->out; e; e = e->next_out)
+ if (e->distance == 0)
+ {
+ ALAP (u_node) = MIN (ALAP (u_node),
+ ALAP (e->dest) - e->latency);
+ HEIGHT (u_node) = MAX (HEIGHT (u_node),
+ HEIGHT (e->dest) + e->latency);
+ }
+ }
+
+ return node_order_params_arr;
+}
+
+static int
+find_max_asap (ddg_ptr g, sbitmap nodes)
+{
+ int u;
+ int max_asap = -1;
+ int result = -1;
+
+ EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+ {
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ if (max_asap < ASAP (u_node))
+ {
+ max_asap = ASAP (u_node);
+ result = u;
+ }
+ });
+ return result;
+}
+
+static int
+find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
+{
+ int u;
+ int max_hv = -1;
+ int min_mob = INT_MAX;
+ int result = -1;
+
+ EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+ {
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ if (max_hv < HEIGHT (u_node))
+ {
+ max_hv = HEIGHT (u_node);
+ min_mob = MOB (u_node);
+ result = u;
+ }
+ else if ((max_hv == HEIGHT (u_node))
+ && (min_mob > MOB (u_node)))
+ {
+ min_mob = MOB (u_node);
+ result = u;
+ }
+ });
+ return result;
+}
+
+static int
+find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
+{
+ int u;
+ int max_dv = -1;
+ int min_mob = INT_MAX;
+ int result = -1;
+
+ EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+ {
+ ddg_node_ptr u_node = &g->nodes[u];
+
+ if (max_dv < DEPTH (u_node))
+ {
+ max_dv = DEPTH (u_node);
+ min_mob = MOB (u_node);
+ result = u;
+ }
+ else if ((max_dv == DEPTH (u_node))
+ && (min_mob > MOB (u_node)))
+ {
+ min_mob = MOB (u_node);
+ result = u;
+ }
+ });
+ return result;
+}
+
+/* Places the nodes of SCC into the NODE_ORDER array starting
+ at position POS, according to the SMS ordering algorithm.
+ NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
+ the NODE_ORDER array, starting from position zero. */
+static int
+order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
+ int * node_order, int pos)
+{
+ enum sms_direction dir;
+ int num_nodes = g->num_nodes;
+ sbitmap workset = sbitmap_alloc (num_nodes);
+ sbitmap tmp = sbitmap_alloc (num_nodes);
+ sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
+ sbitmap predecessors = sbitmap_alloc (num_nodes);
+ sbitmap successors = sbitmap_alloc (num_nodes);
+
+ sbitmap_zero (predecessors);
+ find_predecessors (predecessors, g, nodes_ordered);
+
+ sbitmap_zero (successors);
+ find_successors (successors, g, nodes_ordered);
+
+ sbitmap_zero (tmp);
+ if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
+ {
+ sbitmap_copy (workset, tmp);
+ dir = BOTTOMUP;
+ }
+ else if (sbitmap_a_and_b_cg (tmp, successors, scc))
+ {
+ sbitmap_copy (workset, tmp);
+ dir = TOPDOWN;
+ }
+ else
+ {
+ int u;
+
+ sbitmap_zero (workset);
+ if ((u = find_max_asap (g, scc)) >= 0)
+ SET_BIT (workset, u);
+ dir = BOTTOMUP;
+ }
+
+ sbitmap_zero (zero_bitmap);
+ while (!sbitmap_equal (workset, zero_bitmap))
+ {
+ int v;
+ ddg_node_ptr v_node;
+ sbitmap v_node_preds;
+ sbitmap v_node_succs;
+
+ if (dir == TOPDOWN)
+ {
+ while (!sbitmap_equal (workset, zero_bitmap))
+ {
+ v = find_max_hv_min_mob (g, workset);
+ v_node = &g->nodes[v];
+ node_order[pos++] = v;
+ v_node_succs = NODE_SUCCESSORS (v_node);
+ sbitmap_a_and_b (tmp, v_node_succs, scc);
+
+ /* Don't consider the already ordered successors again. */
+ sbitmap_difference (tmp, tmp, nodes_ordered);
+ sbitmap_a_or_b (workset, workset, tmp);
+ RESET_BIT (workset, v);
+ SET_BIT (nodes_ordered, v);
+ }
+ dir = BOTTOMUP;
+ sbitmap_zero (predecessors);
+ find_predecessors (predecessors, g, nodes_ordered);
+ sbitmap_a_and_b (workset, predecessors, scc);
+ }
+ else
+ {
+ while (!sbitmap_equal (workset, zero_bitmap))
+ {
+ v = find_max_dv_min_mob (g, workset);
+ v_node = &g->nodes[v];
+ node_order[pos++] = v;
+ v_node_preds = NODE_PREDECESSORS (v_node);
+ sbitmap_a_and_b (tmp, v_node_preds, scc);
+
+ /* Don't consider the already ordered predecessors again. */
+ sbitmap_difference (tmp, tmp, nodes_ordered);
+ sbitmap_a_or_b (workset, workset, tmp);
+ RESET_BIT (workset, v);
+ SET_BIT (nodes_ordered, v);
+ }
+ dir = TOPDOWN;
+ sbitmap_zero (successors);
+ find_successors (successors, g, nodes_ordered);
+ sbitmap_a_and_b (workset, successors, scc);
+ }
+ }
+ sbitmap_free (tmp);
+ sbitmap_free (workset);
+ sbitmap_free (zero_bitmap);
+ sbitmap_free (predecessors);
+ sbitmap_free (successors);
+ return pos;
+}
+
+
+/* This page contains functions for manipulating partial-schedules during
+ modulo scheduling. */
+
+/* Create a partial schedule and allocate a memory to hold II rows. */
+partial_schedule_ptr
+create_partial_schedule (int ii, ddg_ptr g, int history)
+{
+ partial_schedule_ptr ps = (partial_schedule_ptr)
+ xmalloc (sizeof (struct partial_schedule));
+ ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
+ ps->ii = ii;
+ ps->history = history;
+ ps->min_cycle = INT_MAX;
+ ps->max_cycle = INT_MIN;
+ ps->g = g;
+
+ return ps;
+}
+
+/* Free the PS_INSNs in rows array of the given partial schedule.
+ ??? Consider caching the PS_INSN's. */
+static void
+free_ps_insns (partial_schedule_ptr ps)
+{
+ int i;
+
+ for (i = 0; i < ps->ii; i++)
+ {
+ while (ps->rows[i])
+ {
+ ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
+
+ free (ps->rows[i]);
+ ps->rows[i] = ps_insn;
+ }
+ ps->rows[i] = NULL;
+ }
+}
+
+/* Free all the memory allocated to the partial schedule. */
+void
+free_partial_schedule (partial_schedule_ptr ps)
+{
+ if (!ps)
+ return;
+ free_ps_insns (ps);
+ free (ps->rows);
+ free (ps);
+}
+
+/* Clear the rows array with its PS_INSNs, and create a new one with
+ NEW_II rows. */
+void
+reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
+{
+ if (!ps)
+ return;
+ free_ps_insns (ps);
+ if (new_ii == ps->ii)
+ return;
+ ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
+ * sizeof (ps_insn_ptr));
+ memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
+ ps->ii = new_ii;
+ ps->min_cycle = INT_MAX;
+ ps->max_cycle = INT_MIN;
+}
+
+/* Prints the partial schedule as an ii rows array, for each rows
+ print the ids of the insns in it. */
+void
+print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
+{
+ int i;
+
+ for (i = 0; i < ps->ii; i++)
+ {
+ ps_insn_ptr ps_i = ps->rows[i];
+
+ fprintf (dump, "\n[CYCLE %d ]: ", i);
+ while (ps_i)
+ {
+ fprintf (dump, "%d, ",
+ INSN_UID (ps_i->node->insn));
+ ps_i = ps_i->next_in_row;
+ }
+ }
+}
+
+/* Creates an object of PS_INSN and initializes it to the given parameters. */
+static ps_insn_ptr
+create_ps_insn (ddg_node_ptr node, int rest_count, int cycle)
+{
+ ps_insn_ptr ps_i = xmalloc (sizeof (struct ps_insn));
+
+ ps_i->node = node;
+ ps_i->next_in_row = NULL;
+ ps_i->prev_in_row = NULL;
+ ps_i->row_rest_count = rest_count;
+ ps_i->cycle = cycle;
+
+ return ps_i;
+}
+
+
+/* Removes the given PS_INSN from the partial schedule. Returns false if the
+ node is not found in the partial schedule, else returns true. */
+static int
+remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
+{
+ int row;
+
+ if (!ps || !ps_i)
+ return false;
+
+ row = SMODULO (ps_i->cycle, ps->ii);
+ if (! ps_i->prev_in_row)
+ {
+ if (ps_i != ps->rows[row])
+ return false;
+
+ ps->rows[row] = ps_i->next_in_row;
+ if (ps->rows[row])
+ ps->rows[row]->prev_in_row = NULL;
+ }
+ else
+ {
+ ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
+ if (ps_i->next_in_row)
+ ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
+ }
+ free (ps_i);
+ return true;
+}
+
+/* Advances the PS_INSN one column in its current row; returns false
+ in failure and true in success. */
+static int
+ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i)
+{
+ ps_insn_ptr prev, next;
+ int row;
+
+ if (!ps || !ps_i)
+ return false;
+
+ row = SMODULO (ps_i->cycle, ps->ii);
+
+ if (! ps_i->next_in_row)
+ return false;
+
+ /* Check if next_in_row is dependent on ps_i, both having same sched
+ times (typically ANTI_DEP). If so, ps_i cannot skip over it. */
+ if (ps_i->cycle == ps_i->next_in_row->cycle)
+ {
+ ddg_edge_ptr e;
+ ddg_node_ptr next_node = ps_i->next_in_row->node;
+
+ for (e = ps_i->node->out; e; e = e->next_out)
+ if (e->dest == next_node)
+ return false;
+ }
+
+ /* Advace PS_I over its next_in_row in the doubly linked list. */
+ prev = ps_i->prev_in_row;
+ next = ps_i->next_in_row;
+
+ if (ps_i == ps->rows[row])
+ ps->rows[row] = next;
+
+ ps_i->next_in_row = next->next_in_row;
+
+ if (next->next_in_row)
+ next->next_in_row->prev_in_row = ps_i;
+
+ next->next_in_row = ps_i;
+ ps_i->prev_in_row = next;
+
+ next->prev_in_row = prev;
+ if (prev)
+ prev->next_in_row = next;
+
+ return true;
+}
+
+/* Inserts a DDG_NODE to the given partial schedule at the given cycle.
+ Returns 0 if this is not possible and a PS_INSN otherwise. */
+static ps_insn_ptr
+add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle)
+{
+ ps_insn_ptr ps_i, next_ps_i, advance_after;
+ int rest_count = 1;
+ int row = SMODULO (cycle, ps->ii);
+ ddg_edge_ptr e;
+
+ if (ps->rows[row]
+ && ps->rows[row]->row_rest_count >= issue_rate)
+ return NULL;
+
+ if (ps->rows[row])
+ rest_count += ps->rows[row]->row_rest_count;
+
+ ps_i = create_ps_insn (node, rest_count, cycle);
+ ps_i->next_in_row = ps->rows[row];
+ ps_i->prev_in_row = NULL;
+ if (ps_i->next_in_row)
+ ps_i->next_in_row->prev_in_row = ps_i;
+ ps->rows[row] = ps_i;
+
+ /* Check if n is dependent on an insn already in row, having same cycle
+ (typically ANTI_DEP). If so, n must skip over it. */
+ advance_after = NULL;
+ for (next_ps_i = ps_i->next_in_row;
+ next_ps_i;
+ next_ps_i = next_ps_i->next_in_row)
+ if (next_ps_i->cycle == cycle)
+ for (e = node->in; e; e = e->next_in)
+ if (e->src == next_ps_i->node)
+ advance_after = next_ps_i;
+
+ if (advance_after)
+ while (ps_i->prev_in_row != advance_after)
+ if (!ps_insn_advance_column (ps, ps_i))
+ {
+ remove_node_from_ps (ps, ps_i);
+ return NULL;
+ }
+
+ return ps_i;
+}
+
+/* Advance time one cycle. Assumes DFA is being used. */
+static void
+advance_one_cycle (void)
+{
+ if (targetm.sched.use_dfa_pipeline_interface
+ && (*targetm.sched.use_dfa_pipeline_interface) ())
+ {
+ if (targetm.sched.dfa_pre_cycle_insn)
+ state_transition (curr_state,
+ (*targetm.sched.dfa_pre_cycle_insn) ());
+
+ state_transition (curr_state, NULL);
+
+ if (targetm.sched.dfa_post_cycle_insn)
+ state_transition (curr_state,
+ (*targetm.sched.dfa_post_cycle_insn) ());
+ }
+}
+
+/* Checks if PS has resource conflicts according to DFA, starting from
+ FROM cycle to TO cycle; returns true if there are conflicts and false
+ if there are no conflicts. Assumes DFA is being used. */
+static int
+ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
+{
+ int cycle;
+
+ if (! targetm.sched.use_dfa_pipeline_interface
+ || ! (*targetm.sched.use_dfa_pipeline_interface) ())
+ return true;
+
+ state_reset (curr_state);
+
+ for (cycle = from; cycle <= to; cycle++)
+ {
+ ps_insn_ptr crr_insn;
+ /* Holds the remaining issue slots in the current row. */
+ int can_issue_more = issue_rate;
+
+ /* Walk through the DFA for the current row. */
+ for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
+ crr_insn;
+ crr_insn = crr_insn->next_in_row)
+ {
+ rtx insn = crr_insn->node->insn;
+
+ if (!INSN_P (insn))
+ continue;
+
+ /* Check if there is room for the current insn. */
+ if (!can_issue_more || state_dead_lock_p (curr_state))
+ return true;
+
+ /* Update the DFA state and return with failure if the DFA found
+ recource conflicts. */
+ if (state_transition (curr_state, insn) >= 0)
+ return true;
+
+ if (targetm.sched.variable_issue)
+ can_issue_more =
+ (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
+ insn, can_issue_more);
+ /* A naked CLOBBER or USE generates no instruction, so don't
+ let them consume issue slots. */
+ else if (GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER)
+ can_issue_more--;
+ }
+
+ /* Advance the DFA to the next cycle. */
+ advance_one_cycle ();
+ }
+ return false;
+}
+
+/* Checks if the given node causes resource conflicts when added to PS at
+ cycle C. If not the node is added to PS and returned; otherwise zero
+ is returned. */
+ps_insn_ptr
+ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n, int c)
+{
+ int has_conflicts = 0;
+ ps_insn_ptr ps_i;
+
+ /* First add the node to the PS, if this succeeds check for conflicts,
+ trying different issue slots in the same row. */
+ if (! (ps_i = add_node_to_ps (ps, n, c)))
+ return NULL; /* Failed to insert the node at the given cycle. */
+
+ has_conflicts = ps_has_conflicts (ps, c, c)
+ || (ps->history > 0
+ && ps_has_conflicts (ps,
+ c - ps->history,
+ c + ps->history));
+
+ /* Try different issue slots to find one that the given node can be
+ scheduled in without conflicts. */
+ while (has_conflicts)
+ {
+ if (! ps_insn_advance_column (ps, ps_i))
+ break;
+ has_conflicts = ps_has_conflicts (ps, c, c)
+ || (ps->history > 0
+ && ps_has_conflicts (ps,
+ c - ps->history,
+ c + ps->history));
+ }
+
+ if (has_conflicts)
+ {
+ remove_node_from_ps (ps, ps_i);
+ return NULL;
+ }
+
+ ps->min_cycle = MIN (ps->min_cycle, c);
+ ps->max_cycle = MAX (ps->max_cycle, c);
+ return ps_i;
+}
+
+/* Rotate the rows of PS such that insns scheduled at time
+ START_CYCLE will appear in row 0. Updates max/min_cycles. */
+void
+rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
+{
+ int i, row, backward_rotates;
+ int last_row = ps->ii - 1;
+
+ if (start_cycle == 0)
+ return;
+
+ backward_rotates = SMODULO (start_cycle, ps->ii);
+
+ /* Revisit later and optimize this into a single loop. */
+ for (i = 0; i < backward_rotates; i++)
+ {
+ ps_insn_ptr first_row = ps->rows[0];
+
+ for (row = 0; row < last_row; row++)
+ ps->rows[row] = ps->rows[row+1];
+
+ ps->rows[last_row] = first_row;
+ }
+
+ ps->max_cycle -= start_cycle;
+ ps->min_cycle -= start_cycle;
+}
+
+#endif /* INSN_SCHEDULING*/
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
new file mode 100644
index 00000000000..a21f29d4b12
--- /dev/null
+++ b/gcc/opt-functions.awk
@@ -0,0 +1,76 @@
+# Copyright (C) 2003,2004 Free Software Foundation, Inc.
+# Contributed by Kelley Cook, June 2004.
+# Original code from Neil Booth, May 2003.
+#
+# 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Some common subroutines for use by opt[ch]-gen.awk.
+
+function switch_flags (flags)
+{
+ flags = " " flags " "
+ result = "0"
+ for (j = 0; j < n_langs; j++) {
+ regex = " " langs[j] " "
+ gsub ( "\\+", "\\+", regex )
+ if (flags ~ regex)
+ result = result " | " macros[j]
+ }
+ if (flags ~ " Common ") result = result " | CL_COMMON"
+ if (flags ~ " Joined ") result = result " | CL_JOINED"
+ if (flags ~ " JoinedOrMissing ") \
+ result = result " | CL_JOINED | CL_MISSING_OK"
+ if (flags ~ " Separate ") result = result " | CL_SEPARATE"
+ if (flags ~ " RejectNegative ") result = result " | CL_REJECT_NEGATIVE"
+ if (flags ~ " UInteger ") result = result " | CL_UINTEGER"
+ if (flags ~ " Undocumented ") result = result " | CL_UNDOCUMENTED"
+ if (flags ~ " Report ") result = result " | CL_REPORT"
+ sub( "^0 \\| ", "", result )
+ return result
+}
+
+function var_args(flags)
+{
+ if (flags !~ "Var\\(")
+ return ""
+ sub(".*Var\\(", "", flags)
+ sub("\\).*", "", flags)
+
+ return flags
+}
+function var_name(flags)
+{
+ s = var_args(flags)
+ if (s == "")
+ return "";
+ sub( ",.*", "", s)
+ return s
+}
+function var_set(flags)
+{
+ s = var_args(flags)
+ if (s !~ ",")
+ return "0, 0"
+ sub( "[^,]*,", "", s)
+ return "1, " s
+}
+function var_ref(flags)
+{
+ name = var_name(flags)
+ if (name == "")
+ return "0"
+ else
+ return "&" name
+}
diff --git a/gcc/opt-gather.awk b/gcc/opt-gather.awk
new file mode 100644
index 00000000000..2feb6d84372
--- /dev/null
+++ b/gcc/opt-gather.awk
@@ -0,0 +1,54 @@
+# Copyright (C) 2003,2004 Free Software Foundation, Inc.
+# Contributed by Kelley Cook, June 2004.
+# Original code from Neil Booth, May 2003.
+#
+# 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This Awk script takes a list of *.opt files and combines them into
+# a three-field sorted list suitable for input into opt[ch]-gen.awk.
+#
+# Usage: awk -f opt-gather.awk file1.opt [...] > outputfile
+
+function sort(ARRAY, ELEMENTS)
+{
+ for (i = 2; i <= ELEMENTS; ++i) {
+ for (j = i; ARRAY[j-1] > ARRAY[j]; --j) {
+ temp = ARRAY[j]
+ ARRAY[j] = ARRAY[j-1]
+ ARRAY[j-1] = temp
+ }
+ }
+ return
+}
+
+BEGIN { numrec = 0 }
+
+# Ignore comments and blank lines
+/^[ \t]*(;|$)/ { flag = 0; next }
+/^[^ \t]/ { if (flag == 0) {
+ record[++numrec] = $0
+ flag = 1 }
+ else {
+ record[numrec] = record[numrec] SUBSEP $0
+ }
+}
+
+# Sort it and output it
+END {
+ sort(record,numrec)
+
+ for (i = 1; i <= numrec; i++) {
+ print record[i] }
+}
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
new file mode 100644
index 00000000000..3ed1cf881be
--- /dev/null
+++ b/gcc/optc-gen.awk
@@ -0,0 +1,144 @@
+# Copyright (C) 2003,2004 Free Software Foundation, Inc.
+# Contributed by Kelley Cook, June 2004.
+# Original code from Neil Booth, May 2003.
+#
+# 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This Awk script reads in the option records generated from
+# opt-gather.awk, combines the flags of duplicat options and generates a
+# C file.
+#
+# This program uses functions from opt-functions.awk
+#
+# Usage: awk -f opt-functions.awk -f optc-gen.awk \
+# [-v header_name=header.h] < inputfile > options.c
+
+BEGIN {
+ n_opts = 0
+ n_langs = 0
+ quote = "\042"
+ comma = ","
+ FS=SUBSEP
+ # Default the name of header created from opth-gen.awk to options.h
+ if (header_name == "") header_name="options.h"
+}
+
+# Collect the text and flags of each option into an array
+ {
+ if ($1 == "Language") {
+ langs[n_langs] = $2
+ n_langs++;
+ }
+ else {
+ opts[n_opts] = $1
+ flags[n_opts] = $2
+ help[n_opts] = $3
+ n_opts++;
+ }
+ }
+
+# Dump that array of options into a C file.
+END {
+print "/* This file is auto-generated by opts.sh. */"
+print ""
+print "#include <intl.h>"
+print "#include " quote header_name quote
+print "#include " quote "opts.h" quote
+print ""
+
+for (i = 0; i < n_opts; i++) {
+ name = var_name(flags[i]);
+ if (name == "")
+ continue;
+
+ if (flags[i] ~ "VarExists")
+ continue;
+
+ if (flags[i] ~ "Init\\(")
+ {
+ init = flags[i];
+ sub(".*Init\\(","",init);
+ sub("\\).*","",init);
+ init = " = " init;
+ }
+ else
+ init = "";
+
+ printf ("/* Set by -%s.\n %s */\nint %s%s;\n\n",
+ opts[i], help[i], name,init)
+ }
+
+
+print "const char * const lang_names[] =\n{"
+for (i = 0; i < n_langs; i++) {
+ macros[i] = "CL_" langs[i]
+ gsub( "[^A-Za-z0-9_]", "X", macros[i] )
+ s = substr(" ", length (macros[i]))
+ print " " quote langs[i] quote ","
+ }
+
+print " 0\n};\n"
+print "const unsigned int cl_options_count = N_OPTS;\n"
+
+print "const struct cl_option cl_options[] =\n{"
+
+for (i = 0; i < n_opts; i++)
+ back_chain[i] = "N_OPTS";
+
+ for (i = 0; i < n_opts; i++) {
+ # Combine the flags of identical switches. Switches
+ # appear many times if they are handled by many front
+ # ends, for example.
+ while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
+ flags[i + 1] = flags[i] " " flags[i + 1];
+ i++;
+ }
+
+ len = length (opts[i]);
+ enum = "OPT_" opts[i]
+ if (opts[i] == "finline-limit=")
+ enum = enum "eq"
+ gsub ("[^A-Za-z0-9]", "_", enum)
+
+ # If this switch takes joined arguments, back-chain all
+ # subsequent switches to it for which it is a prefix. If
+ # a later switch S is a longer prefix of a switch T, T
+ # will be back-chained to S in a later iteration of this
+ # for() loop, which is what we want.
+ if (flags[i] ~ "Joined") {
+ for (j = i + 1; j < n_opts; j++) {
+ if (substr (opts[j], 1, len) != opts[i])
+ break;
+ back_chain[j] = enum;
+ }
+ }
+
+ s = substr(" ", length (opts[i]))
+ if (i + 1 == n_opts)
+ comma = ""
+
+ if (help[i] == "")
+ hlp = "0"
+ else
+ hlp = "N_(" quote help[i] quote ")";
+
+ printf(" { %c-%s%c,\n %s,\n %s, %u, %s, %s, %s }%s\n",
+ quote, opts[i], quote, hlp, back_chain[i], len,
+ switch_flags(flags[i]),
+ var_ref(flags[i]), var_set(flags[i]), comma)
+}
+
+print "};"
+}
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
new file mode 100644
index 00000000000..6cea944bc49
--- /dev/null
+++ b/gcc/opth-gen.awk
@@ -0,0 +1,128 @@
+# Copyright (C) 2003,2004 Free Software Foundation, Inc.
+# Contributed by Kelley Cook, June 2004.
+# Original code from Neil Booth, May 2003.
+#
+# 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This Awk script reads in the option records generated from
+# opt-gather.awk, combines the flags of duplicate options and generates a
+# C header file.
+#
+# This program uses functions from opt-functions.awk
+# Usage: awk -f opt-functions.awk -f opth-gen.awk < inputfile > options.h
+
+BEGIN {
+ n_opts = 0
+ n_langs = 0
+ quote = "\042"
+ comma = ","
+ FS=SUBSEP
+}
+
+# Collect the text and flags of each option into an array
+ {
+ if ($1 == "Language") {
+ langs[n_langs] = $2
+ n_langs++;
+ }
+ else {
+ opts[n_opts] = $1
+ flags[n_opts] = $2
+ help[n_opts] = $3
+ n_opts++;
+ }
+ }
+
+# Dump out an enumeration into a .h file.
+# Combine the flags of duplicate options.
+END {
+print "/* This file is auto-generated by opts.sh. */"
+print ""
+print "#ifndef OPTIONS_H"
+print "#define OPTIONS_H"
+print ""
+
+for (i = 0; i < n_opts; i++) {
+ name = var_name(flags[i]);
+ if (name == "")
+ continue;
+
+ print "/* Set by -" opts[i] "."
+ print " " help[i] " */"
+ print "extern int " name ";"
+ print ""
+
+ }
+
+
+for (i = 0; i < n_langs; i++) {
+ macros[i] = "CL_" langs[i]
+ gsub( "[^A-Za-z0-9_]", "X", macros[i] )
+ s = substr(" ", length (macros[i]))
+ print "#define " macros[i] s " (1 << " i ")"
+ }
+
+print ""
+print "enum opt_code"
+print "{"
+
+for (i = 0; i < n_opts; i++)
+ back_chain[i] = "N_OPTS";
+
+ for (i = 0; i < n_opts; i++) {
+ # Combine the flags of identical switches. Switches
+ # appear many times if they are handled by many front
+ # ends, for example.
+ while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
+ flags[i + 1] = flags[i] " " flags[i + 1];
+ i++;
+ }
+
+ len = length (opts[i]);
+ enum = "OPT_" opts[i]
+ if (opts[i] == "finline-limit=")
+ enum = enum "eq"
+ gsub ("[^A-Za-z0-9]", "_", enum)
+
+ # If this switch takes joined arguments, back-chain all
+ # subsequent switches to it for which it is a prefix. If
+ # a later switch S is a longer prefix of a switch T, T
+ # will be back-chained to S in a later iteration of this
+ # for() loop, which is what we want.
+ if (flags[i] ~ "Joined") {
+ for (j = i + 1; j < n_opts; j++) {
+ if (substr (opts[j], 1, len) != opts[i])
+ break;
+ back_chain[j] = enum;
+ }
+ }
+
+ s = substr(" ", length (opts[i]))
+ if (i + 1 == n_opts)
+ comma = ""
+
+ if (help[i] == "")
+ hlp = "0"
+ else
+ hlp = "N_(\"" help[i] "\")";
+
+ print " " enum "," s "/* -" opts[i] " */"
+}
+
+print " N_OPTS"
+print "};"
+print ""
+print "#endif /* OPTIONS_H */"
+}
diff --git a/gcc/passes.c b/gcc/passes.c
new file mode 100644
index 00000000000..822e4db8f8d
--- /dev/null
+++ b/gcc/passes.c
@@ -0,0 +1,2021 @@
+/* Top level of GCC compilers (cc1, cc1plus, etc.)
+ Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 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. */
+
+/* This is the top level of cc1/c++.
+ It parses command args, opens files, invokes the various passes
+ in the proper order, and counts the time used by each.
+ Error messages and low-level interface to malloc also handled here. */
+
+#include "config.h"
+#undef FLOAT /* This is for hpux. They should change hpux. */
+#undef FFS /* Some systems define this in param.h. */
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include <signal.h>
+
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+#ifdef HAVE_SYS_TIMES_H
+# include <sys/times.h>
+#endif
+
+#include "line-map.h"
+#include "input.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "insn-attr.h"
+#include "insn-config.h"
+#include "insn-flags.h"
+#include "hard-reg-set.h"
+#include "recog.h"
+#include "output.h"
+#include "except.h"
+#include "function.h"
+#include "toplev.h"
+#include "expr.h"
+#include "basic-block.h"
+#include "intl.h"
+#include "ggc.h"
+#include "graph.h"
+#include "loop.h"
+#include "regs.h"
+#include "timevar.h"
+#include "diagnostic.h"
+#include "params.h"
+#include "reload.h"
+#include "dwarf2asm.h"
+#include "integrate.h"
+#include "real.h"
+#include "debug.h"
+#include "target.h"
+#include "langhooks.h"
+#include "cfglayout.h"
+#include "cfgloop.h"
+#include "hosthooks.h"
+#include "cgraph.h"
+#include "opts.h"
+#include "coverage.h"
+#include "value-prof.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+
+#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
+#include "dwarf2out.h"
+#endif
+
+#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
+#include "dbxout.h"
+#endif
+
+#ifdef SDB_DEBUGGING_INFO
+#include "sdbout.h"
+#endif
+
+#ifdef XCOFF_DEBUGGING_INFO
+#include "xcoffout.h" /* Needed for external data
+ declarations for e.g. AIX 4.x. */
+#endif
+
+#ifndef HAVE_conditional_execution
+#define HAVE_conditional_execution 0
+#endif
+
+/* Format to use to print dumpfile index value */
+#ifndef DUMPFILE_FORMAT
+#define DUMPFILE_FORMAT ".%02d."
+#endif
+
+/* Describes a dump file. */
+
+struct dump_file_info
+{
+ /* The unique extension to apply, e.g. ".jump". */
+ const char *const extension;
+
+ /* The -d<c> character that enables this dump file. */
+ char const debug_switch;
+
+ /* True if there is a corresponding graph dump file. */
+ char const graph_dump_p;
+
+ /* True if the user selected this dump. */
+ char enabled;
+
+ /* True if the files have been initialized (ie truncated). */
+ char initialized;
+};
+
+/* Enumerate the extant dump files. */
+
+enum dump_file_index
+{
+ DFI_cgraph,
+ DFI_rtl,
+ DFI_sibling,
+ DFI_eh,
+ DFI_jump,
+ DFI_null,
+ DFI_cse,
+ DFI_gcse,
+ DFI_loop,
+ DFI_bypass,
+ DFI_cfg,
+ DFI_bp,
+ DFI_vpt,
+ DFI_ce1,
+ DFI_tracer,
+ DFI_loop2,
+ DFI_web,
+ DFI_cse2,
+ DFI_life,
+ DFI_combine,
+ DFI_ce2,
+ DFI_regmove,
+ DFI_sms,
+ DFI_sched,
+ DFI_lreg,
+ DFI_greg,
+ DFI_postreload,
+ DFI_gcse2,
+ DFI_flow2,
+ DFI_peephole2,
+ DFI_ce3,
+ DFI_rnreg,
+ DFI_bbro,
+ DFI_branch_target_load,
+ DFI_sched2,
+ DFI_stack,
+ DFI_vartrack,
+ DFI_mach,
+ DFI_dbr,
+ DFI_MAX
+};
+
+/* Describes all the dump files. Should be kept in order of the
+ pass and in sync with dump_file_index above.
+
+ Remaining -d letters:
+
+ " e q "
+ " F K O Q WXY "
+*/
+
+static struct dump_file_info dump_file_tbl[DFI_MAX] =
+{
+ { "cgraph", 'U', 0, 0, 0 },
+ { "rtl", 'r', 0, 0, 0 },
+ { "sibling", 'i', 0, 0, 0 },
+ { "eh", 'h', 0, 0, 0 },
+ { "jump", 'j', 0, 0, 0 },
+ { "null", 'u', 0, 0, 0 },
+ { "cse", 's', 0, 0, 0 },
+ { "gcse", 'G', 1, 0, 0 },
+ { "loop", 'L', 1, 0, 0 },
+ { "bypass", 'G', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "cfg", 'f', 1, 0, 0 },
+ { "bp", 'b', 1, 0, 0 },
+ { "vpt", 'V', 1, 0, 0 },
+ { "ce1", 'C', 1, 0, 0 },
+ { "tracer", 'T', 1, 0, 0 },
+ { "loop2", 'L', 1, 0, 0 },
+ { "web", 'Z', 0, 0, 0 },
+ { "cse2", 't', 1, 0, 0 },
+ { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "combine", 'c', 1, 0, 0 },
+ { "ce2", 'C', 1, 0, 0 },
+ { "regmove", 'N', 1, 0, 0 },
+ { "sms", 'm', 0, 0, 0 },
+ { "sched", 'S', 1, 0, 0 },
+ { "lreg", 'l', 1, 0, 0 },
+ { "greg", 'g', 1, 0, 0 },
+ { "postreload", 'o', 1, 0, 0 },
+ { "gcse2", 'J', 0, 0, 0 },
+ { "flow2", 'w', 1, 0, 0 },
+ { "peephole2", 'z', 1, 0, 0 },
+ { "ce3", 'E', 1, 0, 0 },
+ { "rnreg", 'n', 1, 0, 0 },
+ { "bbro", 'B', 1, 0, 0 },
+ { "btl", 'd', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "sched2", 'R', 1, 0, 0 },
+ { "stack", 'k', 1, 0, 0 },
+ { "vartrack", 'V', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "mach", 'M', 1, 0, 0 },
+ { "dbr", 'd', 0, 0, 0 },
+};
+
+/* Routine to open a dump file. Return true if the dump file is enabled. */
+
+static int
+open_dump_file (enum dump_file_index index, tree decl)
+{
+ char *dump_name;
+ const char *open_arg;
+ char seq[16];
+
+ if (! dump_file_tbl[index].enabled)
+ return 0;
+
+ timevar_push (TV_DUMP);
+ if (dump_file != NULL)
+ fclose (dump_file);
+
+ sprintf (seq, DUMPFILE_FORMAT, index);
+
+ if (! dump_file_tbl[index].initialized)
+ {
+ /* If we've not initialized the files, do so now. */
+ if (graph_dump_format != no_graph
+ && dump_file_tbl[index].graph_dump_p)
+ {
+ dump_name = concat (seq, dump_file_tbl[index].extension, NULL);
+ clean_graph_dump_file (dump_base_name, dump_name);
+ free (dump_name);
+ }
+ dump_file_tbl[index].initialized = 1;
+ open_arg = "w";
+ }
+ else
+ open_arg = "a";
+
+ dump_name = concat (dump_base_name, seq,
+ dump_file_tbl[index].extension, NULL);
+
+ dump_file = fopen (dump_name, open_arg);
+ if (dump_file == NULL)
+ fatal_error ("can't open %s: %m", dump_name);
+
+ free (dump_name);
+
+ if (decl)
+ fprintf (dump_file, "\n;; Function %s%s\n\n",
+ lang_hooks.decl_printable_name (decl, 2),
+ cfun->function_frequency == FUNCTION_FREQUENCY_HOT
+ ? " (hot)"
+ : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
+ ? " (unlikely executed)"
+ : "");
+
+ timevar_pop (TV_DUMP);
+ return 1;
+}
+
+/* Routine to close a dump file. */
+
+static void
+close_dump_file (enum dump_file_index index,
+ void (*func) (FILE *, rtx),
+ rtx insns)
+{
+ if (! dump_file)
+ return;
+
+ timevar_push (TV_DUMP);
+ if (insns
+ && graph_dump_format != no_graph
+ && dump_file_tbl[index].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
+
+ sprintf (seq, DUMPFILE_FORMAT, index);
+ suffix = concat (seq, dump_file_tbl[index].extension, NULL);
+ print_rtl_graph_with_bb (dump_base_name, suffix, insns);
+ free (suffix);
+ }
+
+ if (func && insns)
+ func (dump_file, insns);
+
+ fflush (dump_file);
+ fclose (dump_file);
+
+ dump_file = NULL;
+ timevar_pop (TV_DUMP);
+}
+
+/* This is called from various places for FUNCTION_DECL, VAR_DECL,
+ and TYPE_DECL nodes.
+
+ This does nothing for local (non-static) variables, unless the
+ variable is a register variable with an ASMSPEC. In that case, or
+ if the variable is not an automatic, it sets up the RTL and
+ outputs any assembler code (label definition, storage allocation
+ and initialization).
+
+ DECL is the declaration. If ASMSPEC is nonzero, it specifies
+ the assembler symbol name to be used. TOP_LEVEL is nonzero
+ if this declaration is not within a function. */
+
+void
+rest_of_decl_compilation (tree decl,
+ const char *asmspec,
+ int top_level,
+ int at_end)
+{
+ /* We deferred calling assemble_alias so that we could collect
+ other attributes such as visibility. Emit the alias now. */
+ {
+ tree alias;
+ alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
+ if (alias)
+ {
+ alias = TREE_VALUE (TREE_VALUE (alias));
+ alias = get_identifier (TREE_STRING_POINTER (alias));
+ assemble_alias (decl, alias);
+ }
+ }
+
+ /* Forward declarations for nested functions are not "external",
+ but we need to treat them as if they were. */
+ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
+ || TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ timevar_push (TV_VARCONST);
+
+ if (asmspec)
+ make_decl_rtl (decl, asmspec);
+
+ /* Don't output anything when a tentative file-scope definition
+ is seen. But at end of compilation, do output code for them.
+
+ We do output all variables when unit-at-a-time is active and rely on
+ callgraph code to defer them except for forward declarations
+ (see gcc.c-torture/compile/920624-1.c) */
+ if ((at_end
+ || !DECL_DEFER_OUTPUT (decl)
+ || (flag_unit_at_a_time && DECL_INITIAL (decl)))
+ && !DECL_EXTERNAL (decl))
+ {
+ if (flag_unit_at_a_time && !cgraph_global_info_ready
+ && TREE_CODE (decl) != FUNCTION_DECL && top_level)
+ cgraph_varpool_finalize_decl (decl);
+ else
+ assemble_variable (decl, top_level, at_end, 0);
+ }
+
+#ifdef ASM_FINISH_DECLARE_OBJECT
+ if (decl == last_assemble_variable_decl)
+ {
+ ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
+ top_level, at_end);
+ }
+#endif
+
+ timevar_pop (TV_VARCONST);
+ }
+ else if (DECL_REGISTER (decl) && asmspec != 0)
+ {
+ if (decode_reg_name (asmspec) >= 0)
+ {
+ SET_DECL_RTL (decl, NULL_RTX);
+ make_decl_rtl (decl, asmspec);
+ }
+ else
+ {
+ error ("%Hinvalid register name `%s' for register variable",
+ &DECL_SOURCE_LOCATION (decl), asmspec);
+ DECL_REGISTER (decl) = 0;
+ if (!top_level)
+ expand_decl (decl);
+ }
+ }
+ else if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ timevar_push (TV_SYMOUT);
+ debug_hooks->type_decl (decl, !top_level);
+ timevar_pop (TV_SYMOUT);
+ }
+}
+
+/* Called after finishing a record, union or enumeral type. */
+
+void
+rest_of_type_compilation (tree type, int toplev)
+{
+ /* Avoid confusing the debug information machinery when there are
+ errors. */
+ if (errorcount != 0 || sorrycount != 0)
+ return;
+
+ timevar_push (TV_SYMOUT);
+ debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev);
+ timevar_pop (TV_SYMOUT);
+}
+
+/* Turn the RTL into assembly. */
+static void
+rest_of_handle_final (void)
+{
+ timevar_push (TV_FINAL);
+ {
+ rtx x;
+ const char *fnname;
+
+ /* Get the function's name, as described by its RTL. This may be
+ different from the DECL_NAME name used in the source file. */
+
+ x = DECL_RTL (current_function_decl);
+ if (!MEM_P (x))
+ abort ();
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != SYMBOL_REF)
+ abort ();
+ fnname = XSTR (x, 0);
+
+ assemble_start_function (current_function_decl, fnname);
+ final_start_function (get_insns (), asm_out_file, optimize);
+ final (get_insns (), asm_out_file, optimize, 0);
+ final_end_function ();
+
+#ifdef IA64_UNWIND_INFO
+ /* ??? The IA-64 ".handlerdata" directive must be issued before
+ the ".endp" directive that closes the procedure descriptor. */
+ output_function_exception_table ();
+#endif
+
+ assemble_end_function (current_function_decl, fnname);
+
+#ifndef IA64_UNWIND_INFO
+ /* Otherwise, it feels unclean to switch sections in the middle. */
+ output_function_exception_table ();
+#endif
+
+ if (! quiet_flag)
+ fflush (asm_out_file);
+
+ /* Release all memory allocated by flow. */
+ free_basic_block_vars ();
+
+ /* Release all memory held by regsets now. */
+ regset_release_memory ();
+ }
+ timevar_pop (TV_FINAL);
+
+ ggc_collect ();
+}
+
+#ifdef DELAY_SLOTS
+/* Run delay slot optimization. */
+static void
+rest_of_handle_delay_slots (void)
+{
+ timevar_push (TV_DBR_SCHED);
+ open_dump_file (DFI_dbr, current_function_decl);
+
+ dbr_schedule (get_insns (), dump_file);
+
+ close_dump_file (DFI_dbr, print_rtl, get_insns ());
+ timevar_pop (TV_DBR_SCHED);
+
+ ggc_collect ();
+}
+#endif
+
+#ifdef STACK_REGS
+/* Convert register usage from flat register file usage to a stack
+ register file. */
+static void
+rest_of_handle_stack_regs (void)
+{
+#if defined (HAVE_ATTR_length)
+ /* If flow2 creates new instructions which need splitting
+ and scheduling after reload is not done, they might not be
+ split until final which doesn't allow splitting
+ if HAVE_ATTR_length. */
+#ifdef INSN_SCHEDULING
+ if (optimize && !flag_schedule_insns_after_reload)
+#else
+ if (optimize)
+#endif
+ {
+ timevar_push (TV_SHORTEN_BRANCH);
+ split_all_insns (1);
+ timevar_pop (TV_SHORTEN_BRANCH);
+ }
+#endif
+
+ timevar_push (TV_REG_STACK);
+ open_dump_file (DFI_stack, current_function_decl);
+
+ if (reg_to_stack (dump_file) && optimize)
+ {
+ if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
+ && (flag_reorder_blocks || flag_reorder_blocks_and_partition))
+ {
+ reorder_basic_blocks ();
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
+ }
+ }
+
+ close_dump_file (DFI_stack, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_REG_STACK);
+
+ ggc_collect ();
+}
+#endif
+
+/* Track the variables, ie. compute where the variable is stored at each position in function. */
+static void
+rest_of_handle_variable_tracking (void)
+{
+ timevar_push (TV_VAR_TRACKING);
+ open_dump_file (DFI_vartrack, current_function_decl);
+
+ variable_tracking_main ();
+
+ close_dump_file (DFI_vartrack, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_VAR_TRACKING);
+}
+
+/* Machine independent reorg pass. */
+static void
+rest_of_handle_machine_reorg (void)
+{
+ timevar_push (TV_MACH_DEP);
+ open_dump_file (DFI_mach, current_function_decl);
+
+ targetm.machine_dependent_reorg ();
+
+ close_dump_file (DFI_mach, print_rtl, get_insns ());
+ timevar_pop (TV_MACH_DEP);
+
+ ggc_collect ();
+}
+
+
+/* Run new register allocator. Return TRUE if we must exit
+ rest_of_compilation upon return. */
+static bool
+rest_of_handle_new_regalloc (void)
+{
+ int failure;
+
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ reg_alloc ();
+
+ timevar_pop (TV_LOCAL_ALLOC);
+ if (dump_file_tbl[DFI_lreg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ close_dump_file (DFI_lreg, NULL, NULL);
+ timevar_pop (TV_DUMP);
+ }
+
+ /* XXX clean up the whole mess to bring live info in shape again. */
+ timevar_push (TV_GLOBAL_ALLOC);
+ open_dump_file (DFI_greg, current_function_decl);
+
+ build_insn_chain (get_insns ());
+ failure = reload (get_insns (), 0);
+
+ timevar_pop (TV_GLOBAL_ALLOC);
+
+ if (dump_file_tbl[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_global_regs (dump_file);
+
+ close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_DUMP);
+ }
+
+ if (failure)
+ return true;
+
+ reload_completed = 1;
+
+ return false;
+}
+
+/* Run old register allocator. Return TRUE if we must exit
+ rest_of_compilation upon return. */
+static bool
+rest_of_handle_old_regalloc (void)
+{
+ int failure;
+ int rebuild_notes;
+
+ /* Allocate the reg_renumber array. */
+ allocate_reg_info (max_regno, FALSE, TRUE);
+
+ /* And the reg_equiv_memory_loc array. */
+ VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno);
+ reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0);
+
+ allocate_initial_values (reg_equiv_memory_loc);
+
+ regclass (get_insns (), max_reg_num (), dump_file);
+ rebuild_notes = local_alloc ();
+
+ timevar_pop (TV_LOCAL_ALLOC);
+
+ /* Local allocation may have turned an indirect jump into a direct
+ jump. If so, we must rebuild the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_notes)
+ {
+ timevar_push (TV_JUMP);
+
+ rebuild_jump_labels (get_insns ());
+ purge_all_dead_edges (0);
+
+ timevar_pop (TV_JUMP);
+ }
+
+ if (dump_file_tbl[DFI_lreg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_flow_info (dump_file);
+ dump_local_alloc (dump_file);
+
+ close_dump_file (DFI_lreg, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_DUMP);
+ }
+
+ ggc_collect ();
+
+ timevar_push (TV_GLOBAL_ALLOC);
+ open_dump_file (DFI_greg, current_function_decl);
+
+ /* If optimizing, allocate remaining pseudo-regs. Do the reload
+ pass fixing up any insns that are invalid. */
+
+ if (optimize)
+ failure = global_alloc (dump_file);
+ else
+ {
+ build_insn_chain (get_insns ());
+ failure = reload (get_insns (), 0);
+ }
+
+ timevar_pop (TV_GLOBAL_ALLOC);
+
+ if (dump_file_tbl[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_global_regs (dump_file);
+
+ close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_DUMP);
+ }
+
+ return failure;
+}
+
+/* Run the regrename and cprop passes. */
+static void
+rest_of_handle_regrename (void)
+{
+ timevar_push (TV_RENAME_REGISTERS);
+ open_dump_file (DFI_rnreg, current_function_decl);
+
+ if (flag_rename_registers)
+ regrename_optimize ();
+ if (flag_cprop_registers)
+ copyprop_hardreg_forward ();
+
+ close_dump_file (DFI_rnreg, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_RENAME_REGISTERS);
+}
+
+/* Reorder basic blocks. */
+static void
+rest_of_handle_reorder_blocks (void)
+{
+ bool changed;
+ open_dump_file (DFI_bbro, current_function_decl);
+
+ /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+ splitting possibly introduced more crossjumping opportunities. */
+ changed = cleanup_cfg (CLEANUP_EXPENSIVE
+ | (!HAVE_conditional_execution
+ ? CLEANUP_UPDATE_LIFE : 0));
+
+ if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
+ tracer ();
+ if (flag_reorder_blocks || flag_reorder_blocks_and_partition)
+ reorder_basic_blocks ();
+ if (flag_reorder_blocks || flag_reorder_blocks_and_partition
+ || (flag_sched2_use_traces && flag_schedule_insns_after_reload))
+ changed |= cleanup_cfg (CLEANUP_EXPENSIVE
+ | (!HAVE_conditional_execution
+ ? CLEANUP_UPDATE_LIFE : 0));
+
+ /* On conditional execution targets we can not update the life cheaply, so
+ we deffer the updating to after both cleanups. This may lose some cases
+ but should not be terribly bad. */
+ if (changed && HAVE_conditional_execution)
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_DEATH_NOTES);
+ close_dump_file (DFI_bbro, print_rtl_with_bb, get_insns ());
+}
+
+#ifdef INSN_SCHEDULING
+/* Run instruction scheduler. */
+static void
+rest_of_handle_sched (void)
+{
+ timevar_push (TV_SMS);
+ if (optimize > 0 && flag_modulo_sched)
+ {
+
+ /* Perform SMS module scheduling. */
+ open_dump_file (DFI_sms, current_function_decl);
+
+ /* We want to be able to create new pseudos. */
+ no_new_pseudos = 0;
+ sms_schedule (dump_file);
+ close_dump_file (DFI_sms, print_rtl, get_insns ());
+
+
+ /* Update the life information, because we add pseudos. */
+ max_regno = max_reg_num ();
+ allocate_reg_info (max_regno, FALSE, FALSE);
+ update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
+ (PROP_DEATH_NOTES
+ | PROP_KILL_DEAD_CODE
+ | PROP_SCAN_DEAD_CODE));
+ no_new_pseudos = 1;
+ }
+ timevar_pop (TV_SMS);
+ timevar_push (TV_SCHED);
+
+ /* Print function header into sched dump now
+ because doing the sched analysis makes some of the dump. */
+ if (optimize > 0 && flag_schedule_insns)
+ {
+ open_dump_file (DFI_sched, current_function_decl);
+
+ /* Do control and data sched analysis,
+ and write some of the results to dump file. */
+
+ schedule_insns (dump_file);
+
+ close_dump_file (DFI_sched, print_rtl_with_bb, get_insns ());
+ }
+ timevar_pop (TV_SCHED);
+
+ ggc_collect ();
+}
+
+/* Run second scheduling pass after reload. */
+static void
+rest_of_handle_sched2 (void)
+{
+ timevar_push (TV_SCHED2);
+ open_dump_file (DFI_sched2, current_function_decl);
+
+ /* Do control and data sched analysis again,
+ and write some more of the results to dump file. */
+
+ split_all_insns (1);
+
+ if (flag_sched2_use_superblocks || flag_sched2_use_traces)
+ {
+ schedule_ebbs (dump_file);
+ /* No liveness updating code yet, but it should be easy to do.
+ reg-stack recomputes the liveness when needed for now. */
+ count_or_remove_death_notes (NULL, 1);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ }
+ else
+ schedule_insns (dump_file);
+
+ close_dump_file (DFI_sched2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_SCHED2);
+
+ ggc_collect ();
+}
+#endif
+
+static void
+rest_of_handle_gcse2 (void)
+{
+ open_dump_file (DFI_gcse2, current_function_decl);
+
+ gcse_after_reload_main (get_insns (), dump_file);
+ rebuild_jump_labels (get_insns ());
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ close_dump_file (DFI_gcse2, print_rtl_with_bb, get_insns ());
+
+ ggc_collect ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+}
+
+/* Register allocation pre-pass, to reduce number of moves necessary
+ for two-address machines. */
+static void
+rest_of_handle_regmove (void)
+{
+ timevar_push (TV_REGMOVE);
+ open_dump_file (DFI_regmove, current_function_decl);
+
+ regmove_optimize (get_insns (), max_reg_num (), dump_file);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+ close_dump_file (DFI_regmove, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_REGMOVE);
+
+ ggc_collect ();
+}
+
+/* Run tracer. */
+static void
+rest_of_handle_tracer (void)
+{
+ open_dump_file (DFI_tracer, current_function_decl);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ tracer ();
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (get_insns (), max_reg_num (), 0);
+ close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
+}
+
+/* If-conversion and CFG cleanup. */
+static void
+rest_of_handle_if_conversion (void)
+{
+ open_dump_file (DFI_ce1, current_function_decl);
+ if (flag_if_conversion)
+ {
+ timevar_push (TV_IFCVT);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (get_insns (), max_reg_num (), 0);
+ if_convert (0);
+ timevar_pop (TV_IFCVT);
+ }
+ timevar_push (TV_JUMP);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (get_insns (), max_reg_num (), 0);
+ timevar_pop (TV_JUMP);
+ close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
+}
+
+/* Rerun if-conversion, as combine may have simplified things enough
+ to now meet sequence length restrictions. */
+static void
+rest_of_handle_if_after_combine (void)
+{
+ timevar_push (TV_IFCVT);
+ open_dump_file (DFI_ce2, current_function_decl);
+
+ no_new_pseudos = 0;
+ if_convert (1);
+ no_new_pseudos = 1;
+
+ close_dump_file (DFI_ce2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_IFCVT);
+}
+
+static void
+rest_of_handle_web (void)
+{
+ open_dump_file (DFI_web, current_function_decl);
+ timevar_push (TV_WEB);
+ web_main ();
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ timevar_pop (TV_WEB);
+ close_dump_file (DFI_web, print_rtl_with_bb, get_insns ());
+ reg_scan (get_insns (), max_reg_num (), 0);
+}
+
+/* Do branch profiling and static profile estimation passes. */
+static void
+rest_of_handle_branch_prob (void)
+{
+ struct loops loops;
+ timevar_push (TV_BRANCH_PROB);
+ open_dump_file (DFI_bp, current_function_decl);
+
+ if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+ branch_prob ();
+
+ /* Discover and record the loop depth at the head of each basic
+ block. The loop infrastructure does the real job for us. */
+ flow_loops_find (&loops, LOOP_TREE);
+
+ if (dump_file)
+ flow_loops_dump (&loops, dump_file, NULL, 0);
+
+ /* Estimate using heuristics if no profiling info is available. */
+ if (flag_guess_branch_prob)
+ estimate_probability (&loops);
+
+ flow_loops_free (&loops);
+ free_dominance_info (CDI_DOMINATORS);
+ close_dump_file (DFI_bp, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_BRANCH_PROB);
+}
+
+/* Do optimizations based on expression value profiles. */
+static void
+rest_of_handle_value_profile_transformations (void)
+{
+ open_dump_file (DFI_vpt, current_function_decl);
+ timevar_push (TV_VPT);
+
+ if (value_profile_transformations ())
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ timevar_pop (TV_VPT);
+ close_dump_file (DFI_vpt, print_rtl_with_bb, get_insns ());
+}
+
+/* Do control and data flow analysis; write some of the results to the
+ dump file. */
+static void
+rest_of_handle_cfg (void)
+{
+ open_dump_file (DFI_cfg, current_function_decl);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+
+ /* It may make more sense to mark constant functions after dead code is
+ eliminated by life_analysis, but we need to do it early, as -fprofile-arcs
+ may insert code making function non-constant, but we still must consider
+ it as constant, otherwise -fbranch-probabilities will not read data back.
+
+ life_analysis rarely eliminates modification of external memory.
+ */
+ if (optimize)
+ {
+ /* Alias analysis depends on this information and mark_constant_function
+ depends on alias analysis. */
+ reg_scan (get_insns (), max_reg_num (), 1);
+ mark_constant_function ();
+ }
+
+ close_dump_file (DFI_cfg, print_rtl_with_bb, get_insns ());
+}
+
+/* Perform jump bypassing and control flow optimizations. */
+static void
+rest_of_handle_jump_bypass (void)
+{
+ timevar_push (TV_BYPASS);
+ open_dump_file (DFI_bypass, current_function_decl);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (get_insns (), max_reg_num (), 1);
+
+ if (bypass_jumps (dump_file))
+ {
+ rebuild_jump_labels (get_insns ());
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ }
+
+ close_dump_file (DFI_bypass, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_BYPASS);
+
+ ggc_collect ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+}
+
+/* Try combining insns through substitution. */
+static void
+rest_of_handle_combine (void)
+{
+ int rebuild_jump_labels_after_combine = 0;
+
+ timevar_push (TV_COMBINE);
+ open_dump_file (DFI_combine, current_function_decl);
+
+ rebuild_jump_labels_after_combine
+ = combine_instructions (get_insns (), max_reg_num ());
+
+ /* Combining get_insns () may have turned an indirect jump into a
+ direct jump. Rebuild the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_jump_labels_after_combine)
+ {
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (get_insns ());
+ timevar_pop (TV_JUMP);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+ }
+
+ close_dump_file (DFI_combine, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_COMBINE);
+
+ ggc_collect ();
+}
+
+/* Perform life analysis. */
+static void
+rest_of_handle_life (void)
+{
+ open_dump_file (DFI_life, current_function_decl);
+ regclass_init ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+ life_analysis (dump_file, PROP_FINAL);
+ if (optimize)
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
+ | CLEANUP_LOG_LINKS
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+ timevar_pop (TV_FLOW);
+
+ if (extra_warnings)
+ {
+ setjmp_vars_warning (DECL_INITIAL (current_function_decl));
+ setjmp_args_warning ();
+ }
+
+ if (optimize)
+ {
+ if (!flag_new_regalloc && initialize_uninitialized_subregs ())
+ {
+ /* Insns were inserted, and possibly pseudos created, so
+ things might look a bit different. */
+ allocate_reg_life_data ();
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
+ }
+ }
+
+ no_new_pseudos = 1;
+
+ close_dump_file (DFI_life, print_rtl_with_bb, get_insns ());
+
+ ggc_collect ();
+}
+
+/* Perform common subexpression elimination. Nonzero value from
+ `cse_main' means that jumps were simplified and some code may now
+ be unreachable, so do jump optimization again. */
+static void
+rest_of_handle_cse (void)
+{
+ int tem;
+ open_dump_file (DFI_cse, current_function_decl);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ timevar_push (TV_CSE);
+
+ reg_scan (get_insns (), max_reg_num (), 1);
+
+ tem = cse_main (get_insns (), max_reg_num (), 0, dump_file);
+ if (tem)
+ rebuild_jump_labels (get_insns ());
+ if (purge_all_dead_edges (0))
+ delete_unreachable_blocks ();
+
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+
+ /* If we are not running more CSE passes, then we are no longer
+ expecting CSE to be run. But always rerun it in a cheap mode. */
+ cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
+
+ if (tem || optimize > 1)
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+
+ timevar_pop (TV_CSE);
+ close_dump_file (DFI_cse, print_rtl_with_bb, get_insns ());
+}
+
+/* Run second CSE pass after loop optimizations. */
+static void
+rest_of_handle_cse2 (void)
+{
+ int tem;
+ timevar_push (TV_CSE2);
+ open_dump_file (DFI_cse2, current_function_decl);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ /* CFG is no longer maintained up-to-date. */
+ tem = cse_main (get_insns (), max_reg_num (), 1, dump_file);
+
+ /* Run a pass to eliminate duplicated assignments to condition code
+ registers. We have to run this after bypass_jumps, because it
+ makes it harder for that pass to determine whether a jump can be
+ bypassed safely. */
+ cse_condition_code_reg ();
+
+ purge_all_dead_edges (0);
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+
+ if (tem)
+ {
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (get_insns ());
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ timevar_pop (TV_JUMP);
+ }
+ reg_scan (get_insns (), max_reg_num (), 0);
+ close_dump_file (DFI_cse2, print_rtl_with_bb, get_insns ());
+ ggc_collect ();
+ timevar_pop (TV_CSE2);
+}
+
+/* Perform global cse. */
+static void
+rest_of_handle_gcse (void)
+{
+ int save_csb, save_cfj;
+ int tem2 = 0, tem;
+ timevar_push (TV_GCSE);
+ open_dump_file (DFI_gcse, current_function_decl);
+
+ tem = gcse_main (get_insns (), dump_file);
+ rebuild_jump_labels (get_insns ());
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+
+ save_csb = flag_cse_skip_blocks;
+ save_cfj = flag_cse_follow_jumps;
+ flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
+
+ /* If -fexpensive-optimizations, re-run CSE to clean up things done
+ by gcse. */
+ if (flag_expensive_optimizations)
+ {
+ timevar_push (TV_CSE);
+ reg_scan (get_insns (), max_reg_num (), 1);
+ tem2 = cse_main (get_insns (), max_reg_num (), 0, dump_file);
+ purge_all_dead_edges (0);
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ timevar_pop (TV_CSE);
+ cse_not_expected = !flag_rerun_cse_after_loop;
+ }
+
+ /* If gcse or cse altered any jumps, rerun jump optimizations to clean
+ things up. Then possibly re-run CSE again. */
+ while (tem || tem2)
+ {
+ tem = tem2 = 0;
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (get_insns ());
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ timevar_pop (TV_JUMP);
+
+ if (flag_expensive_optimizations)
+ {
+ timevar_push (TV_CSE);
+ reg_scan (get_insns (), max_reg_num (), 1);
+ tem2 = cse_main (get_insns (), max_reg_num (), 0, dump_file);
+ purge_all_dead_edges (0);
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ timevar_pop (TV_CSE);
+ }
+ }
+
+ close_dump_file (DFI_gcse, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_GCSE);
+
+ ggc_collect ();
+ flag_cse_skip_blocks = save_csb;
+ flag_cse_follow_jumps = save_cfj;
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+}
+
+/* Move constant computations out of loops. */
+static void
+rest_of_handle_loop_optimize (void)
+{
+ int do_unroll, do_prefetch;
+
+ timevar_push (TV_LOOP);
+ delete_dead_jumptables ();
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ open_dump_file (DFI_loop, current_function_decl);
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+
+ if (flag_unroll_loops)
+ do_unroll = LOOP_AUTO_UNROLL; /* Having two unrollers is useless. */
+ else
+ do_unroll = flag_old_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
+ do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
+
+ if (flag_rerun_loop_opt)
+ {
+ cleanup_barriers ();
+
+ /* We only want to perform unrolling once. */
+ loop_optimize (get_insns (), dump_file, do_unroll);
+ do_unroll = 0;
+
+ /* The first call to loop_optimize makes some instructions
+ trivially dead. We delete those instructions now in the
+ hope that doing so will make the heuristics in loop work
+ better and possibly speed up compilation. */
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+
+ /* The regscan pass is currently necessary as the alias
+ analysis code depends on this information. */
+ reg_scan (get_insns (), max_reg_num (), 1);
+ }
+ cleanup_barriers ();
+ loop_optimize (get_insns (), dump_file, do_unroll | do_prefetch);
+
+ /* Loop can create trivially dead instructions. */
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ close_dump_file (DFI_loop, print_rtl, get_insns ());
+ timevar_pop (TV_LOOP);
+ find_basic_blocks (get_insns (), max_reg_num (), dump_file);
+
+ ggc_collect ();
+}
+
+/* Perform loop optimizations. It might be better to do them a bit
+ sooner, but we want the profile feedback to work more
+ efficiently. */
+static void
+rest_of_handle_loop2 (void)
+{
+ struct loops *loops;
+ basic_block bb;
+
+ if (!flag_move_loop_invariants
+ && !flag_unswitch_loops
+ && !flag_peel_loops
+ && !flag_unroll_loops
+ && !flag_branch_on_count_reg)
+ return;
+
+ timevar_push (TV_LOOP);
+ open_dump_file (DFI_loop2, current_function_decl);
+ if (dump_file)
+ dump_flow_info (dump_file);
+
+ /* Initialize structures for layout changes. */
+ cfg_layout_initialize ();
+
+ loops = loop_optimizer_init (dump_file);
+
+ if (loops)
+ {
+ /* The optimizations: */
+ if (flag_move_loop_invariants)
+ move_loop_invariants (loops);
+
+ if (flag_unswitch_loops)
+ unswitch_loops (loops);
+
+ if (flag_peel_loops || flag_unroll_loops)
+ unroll_and_peel_loops (loops,
+ (flag_peel_loops ? UAP_PEEL : 0) |
+ (flag_unroll_loops ? UAP_UNROLL : 0) |
+ (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
+
+#ifdef HAVE_doloop_end
+ if (flag_branch_on_count_reg && HAVE_doloop_end)
+ doloop_optimize_loops (loops);
+#endif /* HAVE_doloop_end */
+
+ loop_optimizer_finalize (loops, dump_file);
+ }
+
+ /* Finalize layout changes. */
+ FOR_EACH_BB (bb)
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ bb->rbi->next = bb->next_bb;
+ cfg_layout_finalize ();
+
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ reg_scan (get_insns (), max_reg_num (), 0);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_LOOP);
+ ggc_collect ();
+}
+
+/* This is called from finish_function (within langhooks.parse_file)
+ after each top-level definition is parsed.
+ It is supposed to compile that function or variable
+ and output the assembler code for it.
+ After we return, the tree storage is freed. */
+
+void
+rest_of_compilation (void)
+{
+ /* There's no need to defer outputting this function any more; we
+ know we want to output it. */
+ DECL_DEFER_OUTPUT (current_function_decl) = 0;
+
+ /* There's no need to defer outputting this function any more; we
+ know we want to output it. */
+ DECL_DEFER_OUTPUT (current_function_decl) = 0;
+
+ /* Register rtl specific functions for cfg. */
+ rtl_register_cfg_hooks ();
+
+ /* Now that we're out of the frontend, we shouldn't have any more
+ CONCATs anywhere. */
+ generating_concat_p = 0;
+
+ /* When processing delayed functions, prepare_function_start() won't
+ have been run to re-initialize it. */
+ cse_not_expected = ! optimize;
+
+ finalize_block_changes ();
+
+ /* Dump the rtl code if we are dumping rtl. */
+ if (open_dump_file (DFI_rtl, current_function_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. */
+ {
+ tree parent;
+ for (parent = DECL_CONTEXT (current_function_decl);
+ parent != NULL_TREE;
+ parent = get_containing_scope (parent))
+ if (TREE_CODE (parent) == FUNCTION_DECL)
+ TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1;
+ }
+
+ /* We are now committed to emitting code for this function. Do any
+ preparation, such as emitting abstract debug info for the inline
+ before it gets mangled by optimization. */
+ if (cgraph_function_possibly_inlined_p (current_function_decl))
+ (*debug_hooks->outlining_inline_function) (current_function_decl);
+
+ /* Remove any notes we don't need. That will make iterating
+ over the instruction sequence faster, and allow the garbage
+ collector to reclaim the memory used by the notes. */
+ remove_unnecessary_notes ();
+
+ ggc_collect ();
+
+ /* Initialize some variables used by the optimizers. */
+ init_function_for_compilation ();
+
+ TREE_ASM_WRITTEN (current_function_decl) = 1;
+
+ /* Now that integrate will no longer see our rtl, we need not
+ distinguish between the return value of this function and the
+ return value of called functions. Also, we can remove all SETs
+ of subregs of hard registers; they are only here because of
+ integrate. Also, we can now initialize pseudos intended to
+ carry magic hard reg data throughout the function. */
+ rtx_equal_function_value_matters = 0;
+ purge_hard_subreg_sets (get_insns ());
+
+ /* Early return if there were errors. We can run afoul of our
+ consistency checks, and there's not really much point in fixing them. */
+ if (rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount)
+ goto exit_rest_of_compilation;
+
+ timevar_push (TV_JUMP);
+ open_dump_file (DFI_sibling, current_function_decl);
+
+ /* ??? We may get called either via tree_rest_of_compilation when the CFG
+ is already built or directly (for instance from coverage code).
+ The direct callers shall be updated. */
+ if (!basic_block_info)
+ {
+ init_flow ();
+ rebuild_jump_labels (get_insns ());
+ find_exception_handler_labels ();
+ find_basic_blocks (get_insns (), max_reg_num (), dump_file);
+ }
+ delete_unreachable_blocks ();
+#ifdef ENABLE_CHECKING
+ verify_flow_info();
+#endif
+
+ /* Turn NOTE_INSN_PREDICTIONs into branch predictions. */
+ if (flag_guess_branch_prob)
+ {
+ timevar_push (TV_BRANCH_PROB);
+ note_prediction_to_br_prob ();
+ timevar_pop (TV_BRANCH_PROB);
+ }
+
+ 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))
+ {
+ timevar_push (TV_JUMP);
+ open_dump_file (DFI_eh, current_function_decl);
+
+ finish_eh_generation ();
+
+ close_dump_file (DFI_eh, print_rtl, get_insns ());
+ timevar_pop (TV_JUMP);
+ }
+
+ /* Delay emitting hard_reg_initial_value sets until after EH landing pad
+ generation, which might create new sets. */
+ emit_initial_value_sets ();
+
+#ifdef FINALIZE_PIC
+ /* If we are doing position-independent code generation, now
+ is the time to output special prologues and epilogues.
+ We do not want to do this earlier, because it just clutters
+ up inline functions with meaningless insns. */
+ if (flag_pic)
+ FINALIZE_PIC;
+#endif
+
+ /* Copy any shared structure that should not be shared. */
+ unshare_all_rtl ();
+
+#ifdef SETJMP_VIA_SAVE_AREA
+ /* This must be performed before virtual register instantiation.
+ Please be aware that everything in the compiler that can look
+ at the RTL up to this point must understand that REG_SAVE_AREA
+ is just like a use of the REG contained inside. */
+ if (current_function_calls_alloca)
+ optimize_save_area_alloca (get_insns ());
+#endif
+
+ /* Instantiate all virtual registers. */
+ instantiate_virtual_regs ();
+
+ open_dump_file (DFI_jump, current_function_decl);
+
+ /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
+ are initialized and to compute whether control can drop off the end
+ of the function. */
+
+ timevar_push (TV_JUMP);
+ /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
+ before jump optimization switches branch directions. */
+ if (flag_guess_branch_prob)
+ expected_value_to_br_prob ();
+
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ reg_scan (get_insns(), max_reg_num (), 0);
+ if (dump_file)
+ dump_flow_info (dump_file);
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+
+ create_loop_notes ();
+
+ purge_line_number_notes (get_insns ());
+
+ close_dump_file (DFI_jump, print_rtl, get_insns ());
+
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+
+ /* 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
+ maximum instruction UID, so if we can reduce the maximum UID
+ we'll save big on memory. */
+ renumber_insns (dump_file);
+ timevar_pop (TV_JUMP);
+
+ close_dump_file (DFI_jump, print_rtl_with_bb, get_insns ());
+
+ ggc_collect ();
+
+ if (optimize > 0)
+ rest_of_handle_cse ();
+
+ ggc_collect ();
+
+ if (optimize > 0)
+ {
+ if (flag_gcse)
+ rest_of_handle_gcse ();
+
+ if (flag_loop_optimize)
+ rest_of_handle_loop_optimize ();
+
+ if (flag_gcse)
+ rest_of_handle_jump_bypass ();
+ }
+
+ timevar_push (TV_FLOW);
+
+ rest_of_handle_cfg ();
+
+ 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 ();
+
+ if (flag_branch_probabilities
+ && flag_profile_values
+ && flag_value_profile_transformations)
+ rest_of_handle_value_profile_transformations ();
+
+ /* Remove the death notes created for vpt. */
+ if (flag_profile_values)
+ count_or_remove_death_notes (NULL, 1);
+ }
+
+ if (optimize > 0)
+ rest_of_handle_if_conversion ();
+
+ if (flag_tracer)
+ rest_of_handle_tracer ();
+
+ if (optimize > 0
+ && flag_loop_optimize2)
+ rest_of_handle_loop2 ();
+
+ if (flag_web)
+ rest_of_handle_web ();
+
+ if (flag_rerun_cse_after_loop)
+ rest_of_handle_cse2 ();
+
+ cse_not_expected = 1;
+
+ rest_of_handle_life ();
+
+ if (optimize > 0)
+ rest_of_handle_combine ();
+
+ if (flag_if_conversion)
+ rest_of_handle_if_after_combine ();
+
+ /* The optimization to partition hot/cold basic blocks into separate
+ sections of the .o file does not work well with exception handling.
+ Don't call it if there are exceptions. */
+
+ if (flag_reorder_blocks_and_partition && !flag_exceptions)
+ {
+ no_new_pseudos = 0;
+ partition_hot_cold_basic_blocks ();
+ allocate_reg_life_data ();
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
+ no_new_pseudos = 1;
+ }
+
+ if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
+ rest_of_handle_regmove ();
+
+ /* Do unconditional splitting before register allocation to allow machine
+ description to add extra information not needed previously. */
+ split_all_insns (1);
+
+#ifdef OPTIMIZE_MODE_SWITCHING
+ timevar_push (TV_MODE_SWITCH);
+
+ no_new_pseudos = 0;
+ optimize_mode_switching (NULL);
+ no_new_pseudos = 1;
+
+ timevar_pop (TV_MODE_SWITCH);
+#endif
+
+ /* Any of the several passes since flow1 will have munged register
+ lifetime data a bit. We need it to be up to date for scheduling
+ (see handling of reg_known_equiv in init_alias_analysis). */
+ recompute_reg_usage (get_insns (), !optimize_size);
+
+#ifdef INSN_SCHEDULING
+ rest_of_handle_sched ();
+#endif
+
+ /* Determine if the current function is a leaf before running reload
+ since this can impact optimizations done by the prologue and
+ epilogue thus changing register elimination offsets. */
+ current_function_is_leaf = leaf_function_p ();
+
+ timevar_push (TV_LOCAL_ALLOC);
+ open_dump_file (DFI_lreg, current_function_decl);
+
+ if (flag_new_regalloc)
+ {
+ if (rest_of_handle_new_regalloc ())
+ goto exit_rest_of_compilation;
+ }
+ else
+ {
+ if (rest_of_handle_old_regalloc ())
+ goto exit_rest_of_compilation;
+ }
+
+ ggc_collect ();
+
+ open_dump_file (DFI_postreload, current_function_decl);
+
+ /* Do a very simple CSE pass over just the hard registers. */
+ if (optimize > 0)
+ {
+ timevar_push (TV_RELOAD_CSE_REGS);
+ reload_cse_regs (get_insns ());
+ /* reload_cse_regs can eliminate potentially-trapping MEMs.
+ Remove any EH edges associated with them. */
+ if (flag_non_call_exceptions)
+ purge_all_dead_edges (0);
+ timevar_pop (TV_RELOAD_CSE_REGS);
+ }
+
+ close_dump_file (DFI_postreload, print_rtl_with_bb, get_insns ());
+
+ if (optimize > 0 && flag_gcse_after_reload)
+ rest_of_handle_gcse2 ();
+
+ /* Re-create the death notes which were deleted during reload. */
+ timevar_push (TV_FLOW2);
+ open_dump_file (DFI_flow2, current_function_decl);
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+
+ /* If optimizing, then go ahead and split get_insns () now. */
+#ifndef STACK_REGS
+ if (optimize > 0)
+#endif
+ split_all_insns (0);
+
+ if (flag_branch_target_load_optimize)
+ {
+ open_dump_file (DFI_branch_target_load, current_function_decl);
+
+ branch_target_load_optimize (/*after_prologue_epilogue_gen=*/false);
+
+ close_dump_file (DFI_branch_target_load, print_rtl_with_bb, get_insns ());
+
+ ggc_collect ();
+ }
+
+ if (! targetm.late_rtl_prologue_epilogue)
+ {
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ /* On some machines, the prologue and epilogue code, or parts thereof,
+ can be represented as RTL. Doing so lets us schedule insns between
+ it and the rest of the code and also allows delayed branch
+ scheduling to operate in the epilogue. */
+ thread_prologue_and_epilogue_insns (get_insns ());
+ epilogue_completed = 1;
+ }
+
+ if (optimize)
+ {
+ life_analysis (dump_file, PROP_POSTRELOAD);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
+
+ /* This is kind of a heuristic. We need to run combine_stack_adjustments
+ even for machines with possibly nonzero RETURN_POPS_ARGS
+ and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having
+ push instructions will have popping returns. */
+#ifndef PUSH_ROUNDING
+ if (!ACCUMULATE_OUTGOING_ARGS)
+#endif
+ combine_stack_adjustments ();
+
+ ggc_collect ();
+ }
+
+ flow2_completed = 1;
+
+ close_dump_file (DFI_flow2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_FLOW2);
+
+#ifdef HAVE_peephole2
+ if (optimize > 0 && flag_peephole2)
+ {
+ timevar_push (TV_PEEPHOLE2);
+ open_dump_file (DFI_peephole2, current_function_decl);
+
+ peephole2_optimize (dump_file);
+
+ close_dump_file (DFI_peephole2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_PEEPHOLE2);
+ }
+#endif
+
+ open_dump_file (DFI_ce3, current_function_decl);
+ if (optimize)
+ /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+ splitting possibly introduced more crossjumping opportunities. */
+ cleanup_cfg (CLEANUP_EXPENSIVE
+ | CLEANUP_UPDATE_LIFE
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
+ if (flag_if_conversion2)
+ {
+ timevar_push (TV_IFCVT2);
+
+ if_convert (1);
+
+ timevar_pop (TV_IFCVT2);
+ }
+ close_dump_file (DFI_ce3, print_rtl_with_bb, get_insns ());
+
+ if (optimize > 0)
+ {
+ if (flag_rename_registers || flag_cprop_registers)
+ rest_of_handle_regrename ();
+
+ rest_of_handle_reorder_blocks ();
+ }
+
+ if (flag_branch_target_load_optimize2)
+ {
+ /* Leave this a warning for now so that it is possible to experiment
+ with running this pass twice. In 3.6, we should either make this
+ an error, or use separate dump files. */
+ if (flag_branch_target_load_optimize)
+ warning ("branch target register load optimization is not intended "
+ "to be run twice");
+
+ open_dump_file (DFI_branch_target_load, current_function_decl);
+
+ branch_target_load_optimize (/*after_prologue_epilogue_gen=*/true);
+
+ close_dump_file (DFI_branch_target_load, print_rtl_with_bb, get_insns ());
+
+ ggc_collect ();
+ }
+
+#ifdef LEAF_REGISTERS
+ current_function_uses_only_leaf_regs
+ = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
+#endif
+
+ if (targetm.late_rtl_prologue_epilogue)
+ {
+ /* On some machines, the prologue and epilogue code, or parts thereof,
+ can be represented as RTL. Doing so lets us schedule insns between
+ it and the rest of the code and also allows delayed branch
+ scheduling to operate in the epilogue. */
+ thread_prologue_and_epilogue_insns (get_insns ());
+ epilogue_completed = 1;
+ if (optimize)
+ life_analysis (dump_file, PROP_POSTRELOAD);
+ }
+
+#ifdef INSN_SCHEDULING
+ if (optimize > 0 && flag_schedule_insns_after_reload)
+ rest_of_handle_sched2 ();
+#endif
+
+#ifdef STACK_REGS
+ rest_of_handle_stack_regs ();
+#endif
+
+ compute_alignments ();
+
+ if (flag_var_tracking)
+ rest_of_handle_variable_tracking ();
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+
+ if (targetm.machine_dependent_reorg != 0)
+ rest_of_handle_machine_reorg ();
+
+ purge_line_number_notes (get_insns ());
+ cleanup_barriers ();
+
+#ifdef DELAY_SLOTS
+ if (optimize > 0 && flag_delayed_branch)
+ rest_of_handle_delay_slots ();
+#endif
+
+#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
+ timevar_push (TV_SHORTEN_BRANCH);
+ split_all_insns_noflow ();
+ timevar_pop (TV_SHORTEN_BRANCH);
+#endif
+
+ convert_to_eh_region_ranges ();
+
+ /* Shorten branches. */
+ timevar_push (TV_SHORTEN_BRANCH);
+ shorten_branches (get_insns ());
+ timevar_pop (TV_SHORTEN_BRANCH);
+
+ 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;
+
+ rest_of_handle_final ();
+
+ /* Write DBX symbols if requested. */
+
+ /* Note that for those inline functions where we don't initially
+ know for certain that we will be generating an out-of-line copy,
+ the first invocation of this routine (rest_of_compilation) will
+ skip over this code by doing a `goto exit_rest_of_compilation;'.
+ Later on, wrapup_global_declarations will (indirectly) call
+ rest_of_compilation again for those inline functions that need
+ to have out-of-line copies generated. During that call, we
+ *will* be routed past here. */
+
+ timevar_push (TV_SYMOUT);
+ (*debug_hooks->function_decl) (current_function_decl);
+ timevar_pop (TV_SYMOUT);
+
+ exit_rest_of_compilation:
+
+ coverage_end_function ();
+
+ /* In case the function was not output,
+ don't leave any temporary anonymous types
+ queued up for sdb output. */
+#ifdef SDB_DEBUGGING_INFO
+ if (write_symbols == SDB_DEBUG)
+ sdbout_types (NULL_TREE);
+#endif
+
+ reload_completed = 0;
+ epilogue_completed = 0;
+ flow2_completed = 0;
+ no_new_pseudos = 0;
+
+ timevar_push (TV_FINAL);
+
+ /* Clear out the insn_length contents now that they are no
+ longer valid. */
+ init_insn_lengths ();
+
+ /* Show no temporary slots allocated. */
+ init_temp_slots ();
+
+ free_basic_block_vars ();
+ free_bb_for_insn ();
+
+ timevar_pop (TV_FINAL);
+
+ if (targetm.binds_local_p (current_function_decl))
+ {
+ int pref = cfun->preferred_stack_boundary;
+ if (cfun->recursive_call_emit
+ && cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
+ pref = cfun->stack_alignment_needed;
+ cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
+ = pref;
+ }
+
+ /* Make sure volatile mem refs aren't considered valid operands for
+ arithmetic insns. We must call this here if this is a nested inline
+ function, since the above code leaves us in the init_recog state
+ (from final.c), and the function context push/pop code does not
+ save/restore volatile_ok.
+
+ ??? Maybe it isn't necessary for expand_start_function to call this
+ anymore if we do it here? */
+
+ init_recog_no_volatile ();
+
+ /* We're done with this function. Free up memory if we can. */
+ free_after_parsing (cfun);
+}
+
+void
+init_optimization_passes (void)
+{
+ open_dump_file (DFI_cgraph, NULL);
+ cgraph_dump_file = dump_file;
+ dump_file = NULL;
+}
+
+void
+finish_optimization_passes (void)
+{
+ if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+ {
+ timevar_push (TV_DUMP);
+ open_dump_file (DFI_bp, NULL);
+
+ end_branch_prob ();
+
+ close_dump_file (DFI_bp, NULL, NULL_RTX);
+ timevar_pop (TV_DUMP);
+ }
+
+ if (optimize > 0 && open_dump_file (DFI_combine, NULL))
+ {
+ timevar_push (TV_DUMP);
+ dump_combine_total_stats (dump_file);
+ close_dump_file (DFI_combine, NULL, NULL_RTX);
+ timevar_pop (TV_DUMP);
+ }
+
+ dump_file = cgraph_dump_file;
+ cgraph_dump_file = NULL;
+ close_dump_file (DFI_cgraph, NULL, NULL_RTX);
+
+ /* Do whatever is necessary to finish printing the graphs. */
+ if (graph_dump_format != no_graph)
+ {
+ int i;
+
+ for (i = 0; i < (int) DFI_MAX; ++i)
+ if (dump_file_tbl[i].initialized && dump_file_tbl[i].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
+
+ sprintf (seq, DUMPFILE_FORMAT, i);
+ suffix = concat (seq, dump_file_tbl[i].extension, NULL);
+ finish_graph_dump_file (dump_base_name, suffix);
+ free (suffix);
+ }
+ }
+
+}
+
+bool
+enable_rtl_dump_file (int letter)
+{
+ bool matched = false;
+ int i;
+
+ if (letter == 'a')
+ {
+ for (i = 0; i < (int) DFI_MAX; ++i)
+ dump_file_tbl[i].enabled = 1;
+ matched = true;
+ }
+ else
+ {
+ for (i = 0; i < (int) DFI_MAX; ++i)
+ if (letter == dump_file_tbl[i].debug_switch)
+ {
+ dump_file_tbl[i].enabled = 1;
+ matched = true;
+ }
+ }
+
+ return matched;
+}
+
+struct tree_opt_pass pass_rest_of_compilation =
+{
+ "rest of compilation", /* name */
+ NULL, /* gate */
+ rest_of_compilation, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_REST_OF_COMPILATION, /* tv_id */
+ PROP_rtl, /* properties_required */
+ 0, /* properties_provided */
+ PROP_rtl, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_ggc_collect /* todo_flags_finish */
+};
+
+
diff --git a/gcc/po/ca.po b/gcc/po/ca.po
new file mode 100644
index 00000000000..760bc22319a
--- /dev/null
+++ b/gcc/po/ca.po
@@ -0,0 +1,23026 @@
+# translation of gcc-3.2-ca.po to Catalan
+# Catalan translation of gcc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This file is distributed under the same license as the gcc package.
+# Gilles MATEU <mateu.gilles@wanadoo.fr>, 2002.
+# Gilles MATEU <mateu.gilles@wanadoo.fr>, 2003.
+# Gilles MATEU <mateu.gilles@wanadoo.fr>, 2004.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gcc 3.3.2\n"
+"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
+"POT-Creation-Date: 2004-04-18 18:00-0700\n"
+"PO-Revision-Date: 2004-01-30 00:03+0000\n"
+"Last-Translator: Mateu Gilles <mateu.gilles@wanadoo.fr>\n"
+"Language-Team: Catalan <ca@dodds.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: attribs.c:178
+#, c-format
+msgid "`%s' attribute directive ignored"
+msgstr "s'ignora la directiva d'atribut \"%s\""
+
+#: attribs.c:186
+#, c-format
+msgid "wrong number of arguments specified for `%s' attribute"
+msgstr "es va especificar el nombre equivocat d'arguments per a l'atribut \"%s\""
+
+#: attribs.c:203
+#, c-format
+msgid "`%s' attribute does not apply to types"
+msgstr "l'atribut \"%s\" no s'aplica a tipus"
+
+#: attribs.c:249
+#, c-format
+msgid "`%s' attribute only applies to function types"
+msgstr "l'atribut \"%s\" nomes s'aplica a tipus funcions"
+
+#: attribs.c:416 c-common.c:4306 c-common.c:4325 c-common.c:4343
+#: c-common.c:4370 c-common.c:4389 c-common.c:4412 c-common.c:4435
+#: c-common.c:4461 c-common.c:4495 c-common.c:4539 c-common.c:4567
+#: c-common.c:4595 c-common.c:4614 c-common.c:4869 c-common.c:4891
+#: c-common.c:4926 c-common.c:4993 c-common.c:5039 c-common.c:5097
+#: c-common.c:5128 c-common.c:5474 c-common.c:5497 c-common.c:5536
+#: config/arm/arm.c:2281 config/arm/arm.c:2308 config/avr/avr.c:4539
+#: config/h8300/h8300.c:4284 config/h8300/h8300.c:4307 config/i386/i386.c:1608
+#: config/i386/i386.c:15380 config/i386/winnt.c:86 config/ia64/ia64.c:1057
+#: config/ip2k/ip2k.c:3151
+#, c-format
+msgid "`%s' attribute ignored"
+msgstr "s'ignora l'atribut \"%s\""
+
+#: builtins.c:318
+msgid "offset outside bounds of constant string"
+msgstr "el desplaçament fora dels límits de la constant de cadena"
+
+#: builtins.c:786
+msgid "second arg to `__builtin_prefetch' must be a constant"
+msgstr "el segon argument de \"__builtin_prefetch\" deu ser una constant"
+
+#: builtins.c:793
+msgid "invalid second arg to __builtin_prefetch; using zero"
+msgstr "segon argument de __builtin_prefetch invalid; s'utilitzara zero"
+
+#: builtins.c:800
+msgid "third arg to `__builtin_prefetch' must be a constant"
+msgstr "el tercer argument de \"__builtin_prefetch\" deu ser una constant"
+
+#: builtins.c:807
+msgid "invalid third arg to __builtin_prefetch; using zero"
+msgstr "tercer argument de __builtin_prefetch invalid; s'utilitzara zero"
+
+#: builtins.c:3828
+msgid "argument of `__builtin_args_info' must be constant"
+msgstr "l'argument de \"__builtin_args_info\" deu ser constant"
+
+#: builtins.c:3834
+msgid "argument of `__builtin_args_info' out of range"
+msgstr "l'argument de \"__builtin_args_info\" està fora de rang"
+
+#: builtins.c:3840
+msgid "missing argument in `__builtin_args_info'"
+msgstr "falta un argument en \"__builtin_args_info\""
+
+#: builtins.c:3856
+msgid "`va_start' used in function with fixed args"
+msgstr "es va usar \"va_start\" en una funció amb arguments fixos"
+
+#: builtins.c:3875
+msgid "second parameter of `va_start' not last named argument"
+msgstr "el segon paràmetre de \"va_start\" no és l'últim argument nomenat"
+
+#. Evidently an out of date version of <stdarg.h>; can't validate
+#. va_start's second argument, but can still work as intended.
+#: builtins.c:3880
+msgid "`__builtin_next_arg' called without an argument"
+msgstr "es va cridar a \"__builtin_next_arg\" sense un argument"
+
+#: builtins.c:3969
+msgid "too many arguments to function `va_start'"
+msgstr "massa arguments per a la funció \"va_start\""
+
+#: builtins.c:4091
+msgid "first argument to `va_arg' not of type `va_list'"
+msgstr "el primer argument per a \"va_arg\" no és del tipus \"va_list\""
+
+#. Unfortunately, this is merely undefined, rather than a constraint
+#. violation, so we cannot make this an error. If this call is never
+#. executed, the program is still strictly conforming.
+#: builtins.c:4123
+#, c-format
+msgid "`%s' is promoted to `%s' when passed through `...'"
+msgstr "\"%s\" es promou a \"%s\" quan passa a través de \"...\""
+
+#: builtins.c:4128
+#, c-format
+msgid "(so you should pass `%s' not `%s' to `va_arg')"
+msgstr "(així que deu passar \"%s\" i no \"%s\" a \"va_arg\")"
+
+#. We can, however, treat "undefined" any way we please.
+#. Call abort to encourage the user to fix the program.
+#: builtins.c:4134 c-typeck.c:1719
+msgid "if this code is reached, the program will abort"
+msgstr ""
+
+#: builtins.c:4241
+msgid "invalid arg to `__builtin_frame_address'"
+msgstr "argument invàlid per a \"__builtin_frame_address\""
+
+#: builtins.c:4243
+msgid "invalid arg to `__builtin_return_address'"
+msgstr "argument invàlid per a \"__builtin_return_address\""
+
+#: builtins.c:4257
+msgid "unsupported arg to `__builtin_frame_address'"
+msgstr "argument sense suport per a \"__builtin_frame_address\""
+
+#: builtins.c:4259
+msgid "unsupported arg to `__builtin_return_address'"
+msgstr "argument sense suport per a \"__builtin_return_address\""
+
+#: builtins.c:4419
+msgid "second arg to `__builtin_expect' must be a constant"
+msgstr "el segon argument de \"__builtin_expect\" deu ser una constant"
+
+#: builtins.c:5360
+msgid "__builtin_longjmp second argument must be 1"
+msgstr "el segon argument de _builtin_longjump deu ser 1"
+
+#: builtins.c:5458
+#, c-format
+msgid "built-in function `%s' not currently supported"
+msgstr "no se suporta actualment la funció interna \"%s\""
+
+#: builtins.c:5598
+msgid "target format does not support infinity"
+msgstr "el format objectiu no té suport per a infinit"
+
+#: c-common.c:917
+msgid "%Hsuggest explicit braces to avoid ambiguous `else'"
+msgstr ""
+
+#: c-common.c:1141
+#, fuzzy
+msgid "%J'%D' is not defined outside of function scope"
+msgstr "no es defineix \"%s\" fora de l'àmbit de la funció"
+
+#: c-common.c:1161
+#, c-format
+msgid "string length `%d' is greater than the length `%d' ISO C%d compilers are required to support"
+msgstr "la longitud de la cadena \"%d\" és major que la longitud `%d\" que es requereix que els compiladors ISO C %d donin suport"
+
+#: c-common.c:1201
+msgid "overflow in constant expression"
+msgstr "desbordament en la constant implícita"
+
+#: c-common.c:1221
+msgid "integer overflow in expression"
+msgstr "desbordament enter en l'expressió"
+
+#: c-common.c:1230
+msgid "floating point overflow in expression"
+msgstr "desbordament de coma flotant en l'expressió"
+
+#: c-common.c:1236
+msgid "vector overflow in expression"
+msgstr "desbordament de vector flotant en l'expressió"
+
+#. This detects cases like converting -129 or 256 to unsigned char.
+#: c-common.c:1258
+msgid "large integer implicitly truncated to unsigned type"
+msgstr "enter gran truncat implícitament al tipus unsigned"
+
+#: c-common.c:1260
+msgid "negative integer implicitly converted to unsigned type"
+msgstr "enter negatiu truncat implícitament al tipus unsigned"
+
+#: c-common.c:1306
+msgid "overflow in implicit constant conversion"
+msgstr "desbordament en la conversió implícita de constant"
+
+#: c-common.c:1442
+#, c-format
+msgid "operation on `%s' may be undefined"
+msgstr "l'operació sobre \"%s\" pot estar indefinida"
+
+#: c-common.c:1726
+msgid "expression statement has incomplete type"
+msgstr "la declaració de l'expressió té tipus de dada incompleta"
+
+#: c-common.c:1758
+msgid "case label does not reduce to an integer constant"
+msgstr "l'etiqueta de \"casi\" no es redueix a una constant entera"
+
+#: c-common.c:2088
+msgid "invalid truth-value expression"
+msgstr "expressió de valor veritable invàlida"
+
+#: c-common.c:2139
+#, c-format
+msgid "invalid operands to binary %s"
+msgstr "operadors invàlids per al binari %s"
+
+#: c-common.c:2373
+msgid "comparison is always false due to limited range of data type"
+msgstr "la comparança sempre és falsa a causa del rang limitat del tipus de dades"
+
+#: c-common.c:2375
+msgid "comparison is always true due to limited range of data type"
+msgstr "la comparança sempre és veritable a causa del rang limitat del tipus de dades"
+
+#: c-common.c:2445
+msgid "comparison of unsigned expression >= 0 is always true"
+msgstr "la comparança d'una expressió unsigned >= 0 sempre és veritable"
+
+#: c-common.c:2454
+msgid "comparison of unsigned expression < 0 is always false"
+msgstr "la comparança d'una expressió unsigned < 0 sempre és falsa"
+
+#: c-common.c:2499
+msgid "pointer of type `void *' used in arithmetic"
+msgstr "es va usar un punter de tipus \"void *\" en l'aritmètica"
+
+#: c-common.c:2505
+msgid "pointer to a function used in arithmetic"
+msgstr "es va usar un punter a una funció en l'aritmètica"
+
+#: c-common.c:2511
+msgid "pointer to member function used in arithmetic"
+msgstr "es va usar un punter a una funció membre en l'aritmètica"
+
+#: c-common.c:2600 f/com.c:14734
+msgid "struct type value used where scalar is required"
+msgstr "s'usa un valor de tipus struct quan es requereix un escalar"
+
+#: c-common.c:2604 f/com.c:14738
+msgid "union type value used where scalar is required"
+msgstr "s'usa un valor de tipus union quan es requereix un escalar"
+
+#: c-common.c:2608 f/com.c:14742
+msgid "array type value used where scalar is required"
+msgstr "s'usa un valor de tipus matriu quan es requereix un escalar"
+
+#. Common Ada/Pascal programmer's mistake. We always warn
+#. about this since it is so bad.
+#: c-common.c:2645
+#, fuzzy
+msgid "the address of `%D', will always evaluate as `true'"
+msgstr "l'adreça de \"%D\", sempre serà \"true\""
+
+#: c-common.c:2739 f/com.c:14874
+msgid "suggest parentheses around assignment used as truth value"
+msgstr "se suggereixen parèntesi al voltant de l'assignació usada com valor veritable"
+
+#: c-common.c:2785 c-common.c:2825
+msgid "invalid use of `restrict'"
+msgstr "ús invàlid de \"restrict\""
+
+#: c-common.c:2935
+msgid "invalid application of `sizeof' to a function type"
+msgstr "aplicació invalida de \"sizeof\" a una expressió de tipus de funció"
+
+#: c-common.c:2945
+#, c-format
+msgid "invalid application of `%s' to a void type"
+msgstr "applicació invàlida de \"%s\" a un tipus void"
+
+#: c-common.c:2951
+#, c-format
+msgid "invalid application of `%s' to an incomplete type"
+msgstr "aplicació invàlida de \"%s\" a un tipus de dada incompleta"
+
+#: c-common.c:2991
+msgid "`__alignof' applied to a bit-field"
+msgstr "\"__alignof\" aplicat a un camp de bits"
+
+#: c-common.c:3483
+#, c-format
+msgid "cannot disable built-in function `%s'"
+msgstr "no es pot desactivar la funcio interna \"%s\""
+
+#: c-common.c:3644 c-typeck.c:1949
+#, c-format
+msgid "too few arguments to function `%s'"
+msgstr "massa pocs arguments per a la funció \"%s\""
+
+#: c-common.c:3650 c-typeck.c:1810
+#, c-format
+msgid "too many arguments to function `%s'"
+msgstr "massa arguments per a la funció \"%s\""
+
+#: c-common.c:3669
+#, c-format
+msgid "non-floating-point argument to function `%s'"
+msgstr "arguments que no són de coma flotant per a la funció \"%s\""
+
+#: c-common.c:3896
+msgid "pointers are not permitted as case values"
+msgstr "els apuntadores no són permesos com valors casi"
+
+#: c-common.c:3900
+#, fuzzy
+msgid "range expressions in switch statements are non-standard"
+msgstr "ISO C prohibeix un rang d'expressions en les declaracions switch"
+
+#: c-common.c:3929
+msgid "empty range specified"
+msgstr "es va especificar un rang buit"
+
+#: c-common.c:3980
+msgid "duplicate (or overlapping) case value"
+msgstr "valor de casi duplicat (o translapat)"
+
+#: c-common.c:3981
+#, fuzzy
+msgid "%Jthis is the first entry overlapping that value"
+msgstr "aquesta és la primera entrada que translapa aquest valor"
+
+#: c-common.c:3985
+msgid "duplicate case value"
+msgstr "valor de casi duplicat"
+
+#: c-common.c:3986
+#, fuzzy
+msgid "%Jpreviously used here"
+msgstr "es va usar prèviament aquí"
+
+#: c-common.c:3990
+msgid "multiple default labels in one switch"
+msgstr "múltiples etiquetes per omissió en un sol switch"
+
+#: c-common.c:3991
+#, fuzzy
+msgid "%Jthis is the first default label"
+msgstr "aquesta és la primera etiqueta per omissió"
+
+#: c-common.c:4016
+#, fuzzy
+msgid "taking the address of a label is non-standard"
+msgstr "SO C prohibeix prendre l'adreça d'una etiqueta"
+
+#: c-common.c:4062
+msgid "%Hignoring return value of `%D', declared with attribute warn_unused_result"
+msgstr ""
+
+#: c-common.c:4067
+msgid "%Hignoring return value of function declared with attribute warn_unused_result"
+msgstr ""
+
+#: c-common.c:4648
+#, c-format
+msgid "unknown machine mode `%s'"
+msgstr "es desconeix la manera de màquina \"%s\""
+
+#: c-common.c:4651
+#, c-format
+msgid "no data type for mode `%s'"
+msgstr "no hi ha tipus de dades per a la manera \"%s\""
+
+#: c-common.c:4655
+#, fuzzy, c-format
+msgid "invalid pointer mode `%s'"
+msgstr "codi d'operant \"%c\" invàlid"
+
+#: c-common.c:4662 c-common.c:5225
+#, c-format
+msgid "unable to emulate '%s'"
+msgstr "no es pot emular \"%s\""
+
+#: c-common.c:4706
+#, fuzzy
+msgid "%Jsection attribute cannot be specified for local variables"
+msgstr "l'atribut de secció no pot ser especificat per a les variables locals"
+
+#: c-common.c:4717
+#, fuzzy
+msgid "%Jsection of '%D' conflicts with previous declaration"
+msgstr "la secció de \"%s\" causa conflictes amb la declaració prèvia"
+
+#: c-common.c:4726
+#, fuzzy
+msgid "%Jsection attribute not allowed for '%D'"
+msgstr "no es permet un atribut de secció per a \"%s\""
+
+#: c-common.c:4732
+#, fuzzy
+msgid "%Jsection attributes are not supported for this target"
+msgstr "atributs de secció no suportats per aquest objectiu"
+
+#: c-common.c:4770
+msgid "requested alignment is not a constant"
+msgstr "l'alineació sol-licitada no és una constant"
+
+#: c-common.c:4775
+msgid "requested alignment is not a power of 2"
+msgstr "l'alineació sol-licitada no és una potència de 2"
+
+#: c-common.c:4780
+msgid "requested alignment is too large"
+msgstr "l'alineació sol-licitada és massa gran"
+
+#: c-common.c:4806
+#, fuzzy
+msgid "%Jalignment may not be specified for '%D'"
+msgstr "l'alineació no pot ser especificada per a \"%s\""
+
+#: c-common.c:4844
+#, fuzzy
+msgid "%J'%D' defined both normally and as an alias"
+msgstr "\"%s\" definit normalment i com un alies"
+
+#: c-common.c:4854
+msgid "alias arg not a string"
+msgstr "l'argument d'alies no és una cadena"
+
+#: c-common.c:4897
+msgid "visibility arg not a string"
+msgstr "l'argument de·visibilitat no és una cadena"
+
+#: c-common.c:4910
+msgid "visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\""
+msgstr "l'argument de visibilitat deu ser \"default\", \"hidden\", \"protected\" o \"internal\""
+
+#: c-common.c:4936
+msgid "tls_model arg not a string"
+msgstr "l'argument tls_model no és una cadena"
+
+#: c-common.c:4945
+msgid "tls_model arg must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\""
+msgstr "l'argument de tls_model deu ser \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\""
+
+#: c-common.c:4967 c-common.c:5013
+#, fuzzy
+msgid "%J'%E' attribute applies only to functions"
+msgstr "l'atribut \"%s\" s'aplica solament a funcions"
+
+#: c-common.c:4972 c-common.c:5018
+#, fuzzy
+msgid "%Jcan't set '%E' attribute after definition"
+msgstr "no es pot establir l'atribut \"%s\" després de la definició"
+
+#: c-common.c:5094
+#, c-format
+msgid "`%s' attribute ignored for `%s'"
+msgstr "atribut \"%s\" ignorat per a \"%s\""
+
+#: c-common.c:5157
+#, c-format
+msgid "invalid vector type for attribute `%s'"
+msgstr "tipus de vector invalid per a l'atribut \"%s\""
+
+#: c-common.c:5181 c-common.c:5213
+msgid "no vector mode with the size and type specified could be found"
+msgstr "no es pot trobar un mode vector amb la grandària i el tipus especificat "
+
+#: c-common.c:5315
+msgid "nonnull attribute without arguments on a non-prototype"
+msgstr "un atribut nonnull sense arguments en un que no és prototip"
+
+#: c-common.c:5330
+#, c-format
+msgid "nonnull argument has invalid operand number (arg %lu)"
+msgstr "un argument nonnull té un nombre d'operadors invàlid (arg %lu)"
+
+#: c-common.c:5349
+#, c-format
+msgid "nonnull argument with out-of-range operand number (arg %lu, operand %lu)"
+msgstr "un argument nonnull amb un nombre d'operants fora de rang (arg %lu, operand %lu)"
+
+#: c-common.c:5357
+#, c-format
+msgid "nonnull argument references non-pointer operand (arg %lu, operand %lu)"
+msgstr "un argument nonnull fa referència a un operant que no és punter (arg %lu, operand %lu)"
+
+#: c-common.c:5437
+#, c-format
+msgid "null argument where non-null required (arg %lu)"
+msgstr "argument null on es requereix un que no sigui null (arg %lu)"
+
+#: c-common.c:5508
+msgid "cleanup arg not an identifier"
+msgstr "l'objecte·cridat·no·és·un identificador"
+
+#: c-common.c:5515
+msgid "cleanup arg not a function"
+msgstr "l'objecte cridat no és una funció"
+
+#: c-common.c:5876
+#, c-format
+msgid "%s at end of input"
+msgstr "%s al final de l'entrada"
+
+#: c-common.c:5882
+#, c-format
+msgid "%s before %s'%c'"
+msgstr "%s abans de %s\"%c\""
+
+#: c-common.c:5884
+#, c-format
+msgid "%s before %s'\\x%x'"
+msgstr "%s abans de %s\"\\x%x\""
+
+#: c-common.c:5888
+#, c-format
+msgid "%s before string constant"
+msgstr "%s abans d'una constant de cadena"
+
+#: c-common.c:5890
+#, c-format
+msgid "%s before numeric constant"
+msgstr "%s abans d'una constant numèrica"
+
+#: c-common.c:5892
+#, c-format
+msgid "%s before \"%s\""
+msgstr "%s abans de \"%s\""
+
+#: c-common.c:5894
+#, c-format
+msgid "%s before '%s' token"
+msgstr "%s abans l'element \"%s\""
+
+#. Use `%s' to print the string in case there are any escape
+#. characters in the message.
+#: c-common.c:5896 c-typeck.c:2586 c-typeck.c:3978 c-typeck.c:3993
+#: c-typeck.c:4008 final.c:2776 final.c:2778 gcc.c:4581 rtl-error.c:109
+#: toplev.c:1357 config/cris/cris.c:552 cp/parser.c:1848 cp/typeck.c:4118
+#: java/expr.c:356 java/verify.c:1456 java/verify.c:1457 java/verify.c:1472
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: c-convert.c:82 c-typeck.c:1197 c-typeck.c:3418 cp/typeck.c:1337
+#: cp/typeck.c:5660 treelang/tree-convert.c:79
+msgid "void value not ignored as it ought to be"
+msgstr "valor void no ignorat com deuria ser"
+
+#: c-convert.c:114 java/typeck.c:148 treelang/tree-convert.c:105
+msgid "conversion to non-scalar type requested"
+msgstr "es va sol·licitar conversió a tipus no escalar"
+
+#: c-decl.c:371
+#, fuzzy
+msgid "%Jarray '%D' assumed to have one element"
+msgstr "s'assumeix que la matriu \"%s\" té un element"
+
+#: c-decl.c:580
+#, fuzzy
+msgid "%Jlabel `%D' used but not defined"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: c-decl.c:586
+#, fuzzy
+msgid "%Jlabel `%D' defined but not used"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: c-decl.c:588
+#, fuzzy
+msgid "%Jlabel `%D' declared but not defined"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: c-decl.c:613
+#, fuzzy
+msgid "%Junused variable `%D'"
+msgstr "variable \"%s\" sense ús"
+
+#: c-decl.c:821
+msgid "a parameter list with an ellipsis can't match an empty parameter name list declaration"
+msgstr "Una llista de paràmetres amb una el·lipse no pot coincidir amb una declaració de nom de llista de paràmetres buida."
+
+#: c-decl.c:828
+msgid "an argument type that has a default promotion can't match an empty parameter name list declaration"
+msgstr "Un tipus d'argument que té una promoció per omissió no pot coincidir amb una declaració de nom de llista de paràmetres buida."
+
+#: c-decl.c:864
+msgid "%Jprototype for '%D' declares more arguments than previous old-style definition"
+msgstr ""
+
+#: c-decl.c:870
+msgid "%Jprototype for '%D' declares fewer arguments than previous old-style definition"
+msgstr ""
+
+#: c-decl.c:879
+msgid "%Jprototype for '%D' declares arg %d with incompatible type"
+msgstr ""
+
+#. If we get here, no errors were found, but do issue a warning
+#. for this poor-style construct.
+#: c-decl.c:891
+#, fuzzy
+msgid "%Jprototype for '%D' follows non-prototype definition"
+msgstr "a continuació la definició del no prototip aquí"
+
+#: c-decl.c:906
+#, fuzzy
+msgid "%Jprevious definition of '%D' was here"
+msgstr "definició prèvia aquí"
+
+#: c-decl.c:908
+#, fuzzy
+msgid "%Jprevious implicit declaration of '%D' was here"
+msgstr "declaració implícita prèvia de \"%s\""
+
+#: c-decl.c:910
+#, fuzzy
+msgid "%Jprevious declaration of '%D' was here"
+msgstr "declaració prèvia de \"%#D\" aquí"
+
+#: c-decl.c:945
+#, fuzzy
+msgid "%J'%D' redeclared as different kind of symbol"
+msgstr "\"%#D\" redeclarat com un tipus diferent de símbol"
+
+#: c-decl.c:950
+#, fuzzy
+msgid "%Jbuilt-in function '%D' declared as non-function"
+msgstr "la funció interna \"%s\" no és declarada com funció"
+
+#: c-decl.c:953 c-decl.c:1045
+#, fuzzy
+msgid "%Jshadowing built-in function '%D'"
+msgstr "enfosquin la funció interna \"%s\""
+
+#. If types don't match for a built-in, throw away the
+#. built-in. No point in calling locate_old_decl here, it
+#. won't print anything.
+#: c-decl.c:974
+#, fuzzy
+msgid "%Jconflicting types for built-in function '%D'"
+msgstr "tipus en conflicte per a la funció interna \"%s\""
+
+#: c-decl.c:998 c-decl.c:1006
+#, fuzzy
+msgid "%Jconflicting types for '%D'"
+msgstr "tipus en conflicte per a \"%#D\""
+
+#. allow OLDDECL to continue in use
+#: c-decl.c:1021
+#, fuzzy
+msgid "%Jredefinition of typedef '%D'"
+msgstr "redefinició de \"%s\""
+
+#: c-decl.c:1058 c-decl.c:1122
+#, fuzzy
+msgid "%Jredefinition of '%D'"
+msgstr "redefinició de \"%s\""
+
+#: c-decl.c:1089 c-decl.c:1139
+#, fuzzy
+msgid "%Jstatic declaration of '%D' follows non-static declaration"
+msgstr "la declaració static per a \"%s\" a continuació d'una no static"
+
+#: c-decl.c:1097 c-decl.c:1136
+#, fuzzy
+msgid "%Jnon-static declaration of '%D' follows static declaration"
+msgstr "la declaració no static per a \"%s\" a continuació d'una static"
+
+#: c-decl.c:1109
+#, fuzzy
+msgid "%Jthread-local declaration of '%D' follows non-thread-local declaration"
+msgstr "declaració thread-local per a \"%s\" a continuació d'una no thread-local"
+
+#: c-decl.c:1112
+#, fuzzy
+msgid "%Jnon-thread-local declaration of '%D' follows thread-local declaration"
+msgstr "declaració no thread-local per a \"%s\" a continuació d'una thread-local"
+
+#: c-decl.c:1152
+#, fuzzy
+msgid "%Jextern declaration of '%D' follows declaration with no linkage"
+msgstr "la declaració externa de \"%s\" no coincideix amb la global"
+
+#: c-decl.c:1155
+#, fuzzy
+msgid "%Jdeclaration of '%D' with no linkage follows extern declaration"
+msgstr "la declaració de \"%F\" llança excepcions diferents"
+
+#: c-decl.c:1158
+#, fuzzy
+msgid "%Jredeclaration of '%D' with no linkage"
+msgstr "declaració prèvia de \"%#D\" amb l'enllaç %L"
+
+#: c-decl.c:1172
+msgid "%Jredeclaration of '%D' with different visibility (old visibility preserved)"
+msgstr ""
+
+#: c-decl.c:1183
+#, fuzzy
+msgid "%Jinline declaration of '%D' follows declaration with attribute noinline"
+msgstr "declaració prèvia de la funció \"%s\" amb l'atribut noinline"
+
+#: c-decl.c:1190
+#, fuzzy
+msgid "%Jdeclaration of '%D' with attribute noinline follows inline declaration "
+msgstr "declaració de la variable static \"%s\" en la declaració inicial del cicle \"for\""
+
+#: c-decl.c:1202
+#, fuzzy
+msgid "%J'%D' declared inline after being called"
+msgstr "\"%s\" declarat inline abans de ser cridat"
+
+#: c-decl.c:1208
+#, fuzzy
+msgid "%J'%D' declared inline after its definition"
+msgstr "\"%s\" declarat inline després de la seva definició"
+
+#: c-decl.c:1221
+#, fuzzy
+msgid "%Jredefinition of parameter '%D'"
+msgstr "redefinició de \"struct %s\""
+
+#: c-decl.c:1230
+#, fuzzy
+msgid "%Jvolatile declaration of '%D' follows non-volatile declaration"
+msgstr "declaració thread-local per a \"%s\" a continuació d'una no thread-local"
+
+#: c-decl.c:1233
+#, fuzzy
+msgid "%Jnon-volatile declaration of '%D' follows volatile declaration"
+msgstr "declaració no thread-local per a \"%s\" a continuació d'una thread-local"
+
+#: c-decl.c:1240
+#, fuzzy
+msgid "%Jconst declaration of '%D' follows non-const declaration"
+msgstr "la declaració const per a \"%s\" a continuació d'una no const"
+
+#: c-decl.c:1243
+#, fuzzy
+msgid "%Jnon-const declaration of '%D' follows const declaration"
+msgstr "la declaració no static per a \"%s\" a continuació d'una static"
+
+#: c-decl.c:1262
+#, fuzzy
+msgid "%Jredundant redeclaration of '%D'"
+msgstr "declaració redundant de \"%D\" en el mateix àmbit"
+
+#: c-decl.c:1581
+#, fuzzy
+msgid "%Jdeclaration of '%D' shadows a parameter"
+msgstr "la declaració de \"%#D\" enfosqueix un paràmetre"
+
+#: c-decl.c:1583
+#, fuzzy
+msgid "%Jdeclaration of '%D' shadows a global declaration"
+msgstr "la declaració de \"%#D\" enfosqueix un paràmetre"
+
+#: c-decl.c:1585
+#, fuzzy
+msgid "%Jdeclaration of '%D' shadows a previous local"
+msgstr "la declaració de \"%#D\" enfosqueix un paràmetre"
+
+#: c-decl.c:1587 cp/name-lookup.c:958 cp/name-lookup.c:981
+#: cp/name-lookup.c:989
+#, fuzzy
+msgid "%Jshadowed declaration is here"
+msgstr "declaració prèvia de \"%#D\" aquí"
+
+#: c-decl.c:1697
+#, c-format
+msgid "nested extern declaration of `%s'"
+msgstr "declaració extern niada de \"%s\""
+
+#: c-decl.c:1838 objc/objc-act.c:2534 objc/objc-act.c:6793
+#, fuzzy
+msgid "%Jprevious declaration of '%D'"
+msgstr "declaració prèvia de \"%D\""
+
+#: c-decl.c:1879 c-decl.c:1881
+#, c-format
+msgid "implicit declaration of function `%s'"
+msgstr "declaració implícita de la funció \"%s\""
+
+#: c-decl.c:1897
+#, c-format
+msgid "`%s' undeclared here (not in a function)"
+msgstr "\"%s\" no ha estat declarat aquí (no en una funció)"
+
+#: c-decl.c:1903
+#, c-format
+msgid "`%s' undeclared (first use in this function)"
+msgstr "\"%s\" no ha estat declarat aquí (primer us en aquesta funció)"
+
+#: c-decl.c:1908
+msgid "(Each undeclared identifier is reported only once"
+msgstr "(Cada identificador no declarat solament es reporta una vegada"
+
+#: c-decl.c:1909
+msgid "for each function it appears in.)"
+msgstr "per a cada funció en la qual apareix.)"
+
+#: c-decl.c:1962
+#, c-format
+msgid "label %s referenced outside of any function"
+msgstr "l'etiqueta %s és referenciada fora de qualsevol funció"
+
+#: c-decl.c:2009
+#, c-format
+msgid "duplicate label declaration `%s'"
+msgstr "declaració de l'etiqueta \"%s\" duplicada"
+
+#: c-decl.c:2010
+#, fuzzy
+msgid "%Jthis is a previous declaration"
+msgstr "aquesta és una declaració prèvia"
+
+#: c-decl.c:2045
+#, fuzzy
+msgid "%Hduplicate label `%D'"
+msgstr "etiqueta duplicada \"%D\""
+
+#: c-decl.c:2047
+#, fuzzy
+msgid "%J`%D' previously defined here"
+msgstr "es va definir \"%#D\" prèviament aquí"
+
+#: c-decl.c:2049
+#, fuzzy
+msgid "%J`%D' previously declared here"
+msgstr "es va declarar \"%#D\" prèviament aquí"
+
+#: c-decl.c:2069
+msgid "%Htraditional C lacks a separate namespace for labels, identifier `%s' conflicts"
+msgstr ""
+
+#: c-decl.c:2140
+#, fuzzy
+msgid "%H`%s' defined as wrong kind of tag"
+msgstr "\"%s\" redeclarat com un tipus diferent de símbol"
+
+#: c-decl.c:2378
+msgid "unnamed struct/union that defines no instances"
+msgstr "struct/union sense nom que no defineix cap instància"
+
+#: c-decl.c:2397
+msgid "useless keyword or type name in empty declaration"
+msgstr "paraules claus inútils o noms de tipus en una declaració buida"
+
+#: c-decl.c:2404
+msgid "two types specified in one empty declaration"
+msgstr "es van especificar dos tipus en una declaració buida"
+
+#: c-decl.c:2409 c-parse.y:735 c-parse.y:737 objc/objc-parse.y:776
+#: objc/objc-parse.y:778 objc/objc-parse.y:3016
+msgid "empty declaration"
+msgstr "declaració buida"
+
+#: c-decl.c:2435
+msgid "ISO C90 does not support `static' or type qualifiers in parameter array declarators"
+msgstr "ISO C90 no dóna suport a \"static\" o qualificadors de tipus dins matrius de declaradors de parametres"
+
+#: c-decl.c:2437
+msgid "ISO C90 does not support `[*]' array declarators"
+msgstr "ISO C90 no dóna suport a declaradors de parametres \"[*]\""
+
+#: c-decl.c:2440
+msgid "GCC does not yet properly implement `[*]' array declarators"
+msgstr "GCC no implementa encara correctament declaradors de parametres \"[*]\""
+
+#: c-decl.c:2456
+msgid "static or type qualifiers in abstract declarator"
+msgstr "static o calificador de tipus en un declarador abstracte"
+
+#: c-decl.c:2526
+#, fuzzy
+msgid "%J'%D' is usually a function"
+msgstr "\"%s\" generalment és una funció"
+
+#: c-decl.c:2535
+#, c-format
+msgid "typedef `%s' is initialized (use __typeof__ instead)"
+msgstr "typedef \"%s\" té valor inicial (usi __typeof__ en lloc)"
+
+#: c-decl.c:2541
+#, c-format
+msgid "function `%s' is initialized like a variable"
+msgstr "la funció \"%s\" té valor inicial com una variable"
+
+#. DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.
+#: c-decl.c:2548
+#, c-format
+msgid "parameter `%s' is initialized"
+msgstr "el paràmetre \"%s\" té valor inicial"
+
+#: c-decl.c:2568 c-typeck.c:4228
+msgid "variable-sized object may not be initialized"
+msgstr "un objecte de grandària variable no pot tenir valor inicial"
+
+#: c-decl.c:2574
+#, c-format
+msgid "variable `%s' has initializer but incomplete type"
+msgstr "la variable \"%s\" té assignació de valor inicial, però tipus de dada incompleta"
+
+#: c-decl.c:2580
+#, c-format
+msgid "elements of array `%s' have incomplete type"
+msgstr "alguns elements de la matriu \"%s\" tenen tipus de dada incompleta"
+
+#: c-decl.c:2649 c-decl.c:5451 cp/decl.c:3761 cp/decl.c:10133
+#, fuzzy
+msgid "%Jinline function '%D' given attribute noinline"
+msgstr "ha donat un atribut noinline a la funció inline \"%s\""
+
+#: c-decl.c:2725
+#, fuzzy
+msgid "%Jinitializer fails to determine size of '%D'"
+msgstr "el inicializador no pot determinar la grandària de \"%D\""
+
+#: c-decl.c:2730
+#, fuzzy
+msgid "%Jarray size missing in '%D'"
+msgstr "falta la grandària de la matriu en \"%D\""
+
+#: c-decl.c:2746
+#, fuzzy
+msgid "%Jzero or negative size array '%D'"
+msgstr "matriu \"%s\" de grandària zero o negatiu"
+
+#: c-decl.c:2774
+#, fuzzy
+msgid "%Jstorage size of '%D' isn't known"
+msgstr "no es coneix la grandària d'emmagatzematge de \"%D\""
+
+#: c-decl.c:2784
+#, fuzzy
+msgid "%Jstorage size of '%D' isn't constant"
+msgstr "la grandària d'emmagatzematge de \"%D\" no és constant"
+
+#: c-decl.c:2867
+#, fuzzy
+msgid "%Jignoring asm-specifier for non-static local variable '%D'"
+msgstr "s'ignora el especificador asm per a la variable local no estàtica \"%s\""
+
+#: c-decl.c:2978
+msgid "ISO C forbids forward parameter declarations"
+msgstr "ISO C prohibeix declaracions avançades de paràmetres"
+
+#: c-decl.c:3160
+#, fuzzy
+msgid "<anonymous>"
+msgstr "<%s anònim>"
+
+#: c-decl.c:3169
+#, c-format
+msgid "bit-field `%s' width not an integer constant"
+msgstr "l'amplària del camp de bits \"%s\" no és una constant entera"
+
+#: c-decl.c:3177
+#, c-format
+msgid "negative width in bit-field `%s'"
+msgstr "amplària negativa en el camp de bit \"%s\""
+
+#: c-decl.c:3182
+#, c-format
+msgid "zero width for bit-field `%s'"
+msgstr "amplària zero per al camp de bits \"%s\""
+
+#: c-decl.c:3192
+#, c-format
+msgid "bit-field `%s' has invalid type"
+msgstr "el camp de bits \"%s\" té un tipus invàlid"
+
+#: c-decl.c:3201
+#, fuzzy, c-format
+msgid "type of bit-field `%s' is a GCC extension"
+msgstr "l'estil de la directiva de línia és una extenció del GCC"
+
+#: c-decl.c:3210
+#, c-format
+msgid "width of `%s' exceeds its type"
+msgstr "l'amplària de \"%s\" excedeix el seu tipus"
+
+#: c-decl.c:3220
+#, c-format
+msgid "`%s' is narrower than values of its type"
+msgstr "\"%s\" és més estret que els valors del seu tipus"
+
+#: c-decl.c:3370 cp/decl.c:6805
+msgid "`long long long' is too long for GCC"
+msgstr "\"long long long\" és massa llarg per a GCC"
+
+#: c-decl.c:3375
+msgid "ISO C90 does not support `long long'"
+msgstr "ISO C90 no dóna suport a \"long long\""
+
+#: c-decl.c:3384 c-decl.c:3387 cp/decl.c:6810
+#, c-format
+msgid "duplicate `%s'"
+msgstr "\"%s\" duplicat"
+
+#: c-decl.c:3397 cp/decl.c:6816
+msgid "`__thread' before `extern'"
+msgstr "\"__thread\" abans \"extern\""
+
+#: c-decl.c:3399 cp/decl.c:6818
+msgid "`__thread' before `static'"
+msgstr "\"__thread\" abans \"static\""
+
+#: c-decl.c:3407 cp/decl.c:6845
+#, c-format
+msgid "two or more data types in declaration of `%s'"
+msgstr "dos o més tipus de dades en la declaració de \"%s\""
+
+#: c-decl.c:3427 cp/decl.c:6850
+#, c-format
+msgid "`%s' fails to be a typedef or built in type"
+msgstr "\"%s\" falla al ser un typedef o un tipus intern del compilador"
+
+#: c-decl.c:3466
+#, c-format
+msgid "type defaults to `int' in declaration of `%s'"
+msgstr "el tipus de dada per omissió és \"int\" en la declaració de \"%s\""
+
+#: c-decl.c:3495
+#, c-format
+msgid "both long and short specified for `%s'"
+msgstr "s'especifica long i short al mateix temps per a \"%s\""
+
+#: c-decl.c:3499 cp/decl.c:6950
+#, c-format
+msgid "long or short specified with char for `%s'"
+msgstr "s'especifica long o short amb char per a \"%s\""
+
+#: c-decl.c:3506 cp/decl.c:6954
+#, c-format
+msgid "long or short specified with floating type for `%s'"
+msgstr "s'especifica long o short amb tipus floating per a \"%s\""
+
+#: c-decl.c:3509
+msgid "the only valid combination is `long double'"
+msgstr "l'única combinació vàlida és \"long double\""
+
+#: c-decl.c:3515
+#, c-format
+msgid "both signed and unsigned specified for `%s'"
+msgstr "s'especifica signed i unsigned al mateix temps per a \"%s\""
+
+#: c-decl.c:3517 cp/decl.c:6943
+#, c-format
+msgid "long, short, signed or unsigned invalid for `%s'"
+msgstr "long, short, signed o unsigned invàlids per a \"%s\""
+
+#: c-decl.c:3523 cp/decl.c:6963
+#, c-format
+msgid "long, short, signed or unsigned used invalidly for `%s'"
+msgstr "ús invàlid de long, short, signed o unsigned per a \"%s\""
+
+#: c-decl.c:3541 cp/decl.c:6984
+#, c-format
+msgid "complex invalid for `%s'"
+msgstr "complex invàlid per a \"%s\""
+
+#: c-decl.c:3583
+msgid "ISO C90 does not support complex types"
+msgstr "ISO C90 no té suport per a tipus complexos"
+
+#: c-decl.c:3595
+msgid "ISO C does not support plain `complex' meaning `double complex'"
+msgstr "ISO C no té suport per a \"complex\" simples que signifiquen \"double complex\""
+
+#: c-decl.c:3601 c-decl.c:3613
+msgid "ISO C does not support complex integer types"
+msgstr "ISO C no dóna suport a tipus enters complexos"
+
+#: c-decl.c:3643 c-decl.c:4104 cp/decl.c:7576
+msgid "duplicate `const'"
+msgstr "\"const\" duplicat"
+
+#: c-decl.c:3645 c-decl.c:4108 cp/decl.c:7580
+msgid "duplicate `restrict'"
+msgstr "\"restrict\" duplicat"
+
+#: c-decl.c:3647 c-decl.c:4106 cp/decl.c:7578
+msgid "duplicate `volatile'"
+msgstr "\"volatile\" duplicat"
+
+#: c-decl.c:3676 cp/decl.c:7147
+#, c-format
+msgid "multiple storage classes in declaration of `%s'"
+msgstr "múltiples classes d'emmagatzematge en la declaració de \"%s\""
+
+#: c-decl.c:3686
+msgid "function definition declared `auto'"
+msgstr "la definició de la funció ho va declarar com \"auto\""
+
+#: c-decl.c:3688
+msgid "function definition declared `register'"
+msgstr "la definició de la funció ho va declarar com \"register\""
+
+#: c-decl.c:3690
+msgid "function definition declared `typedef'"
+msgstr "la definició de la funció ho va declarar com \"typedef\""
+
+#: c-decl.c:3692
+msgid "function definition declared `__thread'"
+msgstr "la definició de la funció ho va declarar com \"__thread\""
+
+#: c-decl.c:3705
+#, c-format
+msgid "storage class specified for structure field `%s'"
+msgstr "es va especificar una classe d'emmagatzematge per al camp de l'estructura \"%s\""
+
+#: c-decl.c:3709 cp/decl.c:7192
+#, c-format
+msgid "storage class specified for parameter `%s'"
+msgstr "es va especificar una classe d'emmagatzematge per al paràmetre \"%s\""
+
+#: c-decl.c:3712 cp/decl.c:7194
+msgid "storage class specified for typename"
+msgstr "es va especificar una classe d'emmagatzematge per al nom de tipus"
+
+#: c-decl.c:3724 cp/decl.c:7209
+#, c-format
+msgid "`%s' initialized and declared `extern'"
+msgstr "\"%s\" iniciat i declarat com \"extern\""
+
+#: c-decl.c:3726 cp/decl.c:7212
+#, c-format
+msgid "`%s' has both `extern' and initializer"
+msgstr "\"%s\" té \"extern\" i assignador de valor inicial al mateix temps"
+
+#: c-decl.c:3731
+#, fuzzy, c-format
+msgid "file-scope declaration of `%s' specifies `auto'"
+msgstr "la declaració del nivell superior de \"%s\" especifica \"auto\""
+
+#: c-decl.c:3736 cp/decl.c:7216
+#, c-format
+msgid "nested function `%s' declared `extern'"
+msgstr "la funció niada \"%s\" es va declarar \"extern\""
+
+#: c-decl.c:3742 cp/decl.c:7226
+#, c-format
+msgid "function-scope `%s' implicitly auto and declared `__thread'"
+msgstr "l'àmbit de la funció \"%s\" és implícitament acte i declarada \"__thread\""
+
+#. Only the innermost declarator (making a parameter be of
+#. array type which is converted to pointer type)
+#. may have static or type qualifiers.
+#: c-decl.c:3781 c-decl.c:3974
+msgid "static or type qualifiers in non-parameter array declarator"
+msgstr "static o qualificador de tipus en un declarador de matriu que no és parametre"
+
+#: c-decl.c:3825
+#, c-format
+msgid "declaration of `%s' as array of voids"
+msgstr "declaració de \"%s\" com una matriu de voids"
+
+#: c-decl.c:3831
+#, c-format
+msgid "declaration of `%s' as array of functions"
+msgstr "declaració de \"%s\" com una matriu de funcions"
+
+#: c-decl.c:3836
+msgid "invalid use of structure with flexible array member"
+msgstr "ús invàlid de structura amb membres de matriu flexible"
+
+#: c-decl.c:3855
+#, c-format
+msgid "size of array `%s' has non-integer type"
+msgstr "la grandària de la matriu \"%s\" té un tipus no enter"
+
+#: c-decl.c:3860
+#, c-format
+msgid "ISO C forbids zero-size array `%s'"
+msgstr "ISO C prohibeix la matriu \"%s\" de grandària zero"
+
+#: c-decl.c:3867
+#, c-format
+msgid "size of array `%s' is negative"
+msgstr "la grandària de la matriu \"%s\" és negatiu"
+
+#: c-decl.c:3880
+#, c-format
+msgid "ISO C90 forbids array `%s' whose size can't be evaluated"
+msgstr "ISO C90 prohibeix matriu \"%s\" que la seua grandària no pot ser avaluada"
+
+#: c-decl.c:3883
+#, c-format
+msgid "ISO C90 forbids variable-size array `%s'"
+msgstr "ISO C90 prohibeix la matriu \"%s\" de grandària variable"
+
+#: c-decl.c:3913 c-decl.c:4131 cp/decl.c:7754
+#, c-format
+msgid "size of array `%s' is too large"
+msgstr "la grandària de la matriu \"%s\" és massa gran"
+
+#: c-decl.c:3939
+msgid "ISO C90 does not support flexible array members"
+msgstr "ISO C90 no té suport per a membres de matriu flexibles"
+
+#: c-decl.c:3949
+msgid "array type has incomplete element type"
+msgstr "el tipus array té tipus d'element incomplet"
+
+#: c-decl.c:3994 cp/decl.c:7347
+#, c-format
+msgid "`%s' declared as function returning a function"
+msgstr "\"%s\" que és declarat com funció retorna una funció"
+
+#: c-decl.c:3999 cp/decl.c:7352
+#, c-format
+msgid "`%s' declared as function returning an array"
+msgstr "\"%s\" que és declarat com funció retorna una matriu"
+
+#: c-decl.c:4027
+msgid "ISO C forbids qualified void function return type"
+msgstr "ISO C prohibeix el tipus qualificat de devolució d'una funció void"
+
+#: c-decl.c:4031
+msgid "type qualifiers ignored on function return type"
+msgstr "s'ignoren els calificatores de tipus en el tipus de devolució de la funció"
+
+#: c-decl.c:4060 c-decl.c:4146 c-decl.c:4270 c-decl.c:4356
+msgid "ISO C forbids qualified function types"
+msgstr "ISO C prohibeix els tipus de funció qualificats"
+
+#: c-decl.c:4100 cp/decl.c:7572
+msgid "invalid type modifier within pointer declarator"
+msgstr "modificador de tipus invàlid dintre de la declaració del punter"
+
+#: c-decl.c:4181
+msgid "ISO C forbids const or volatile function types"
+msgstr "ISO C prohibeix els tipus de funció const o volatile"
+
+#: c-decl.c:4201 cp/decl.c:8035
+#, c-format
+msgid "variable or field `%s' declared void"
+msgstr "variable o camp \"%s\" declarat void"
+
+#: c-decl.c:4234
+msgid "attributes in parameter array declarator ignored"
+msgstr "atributs en el declarador de parametres de matriu ignorats"
+
+#: c-decl.c:4259
+msgid "invalid type modifier within array declarator"
+msgstr "imodificador de tipus invalid dins d'un declarador de matriu"
+
+#: c-decl.c:4304
+#, c-format
+msgid "field `%s' declared as a function"
+msgstr "el camp \"%s\" es declarat com una funció"
+
+#: c-decl.c:4310
+#, c-format
+msgid "field `%s' has incomplete type"
+msgstr "el camp \"%s\" té tipus de dada incompleta"
+
+#: c-decl.c:4336 c-decl.c:4338 c-decl.c:4340 c-decl.c:4347
+#, c-format
+msgid "invalid storage class for function `%s'"
+msgstr "classe d'emmagatzematge invàlida per a la funció \"%s\""
+
+#: c-decl.c:4362
+msgid "`noreturn' function returns non-void value"
+msgstr "la funció \"no return\" retorna un valor que no és void"
+
+#: c-decl.c:4377
+msgid "cannot inline function `main'"
+msgstr "no es pot fer inline la funció \"main\""
+
+#: c-decl.c:4431
+#, fuzzy
+msgid "variable previously declared `static' redeclared `extern'"
+msgstr "variable o camp \"%s\" declarat void"
+
+#: c-decl.c:4440
+#, fuzzy
+msgid "%Jvariable '%D' declared `inline'"
+msgstr "la variable \"%s\" va ser declarada com \"inline\""
+
+#. A mere warning is sure to result in improper semantics
+#. at runtime. Don't bother to allow this to compile.
+#: c-decl.c:4468 cp/decl.c:5903
+msgid "thread-local storage not supported for this target"
+msgstr "no es dóna suport a -thread local strorage en aquest objectiu"
+
+#: c-decl.c:4529 c-decl.c:5495
+msgid "function declaration isn't a prototype"
+msgstr "la declaració de la funció no és un prototip"
+
+#: c-decl.c:4535
+msgid "parameter names (without types) in function declaration"
+msgstr "noms de paràmetres (sense tipus) en la declaració de la funció"
+
+#: c-decl.c:4563
+#, c-format
+msgid "parameter `%s' has incomplete type"
+msgstr "el paràmetre \"%s\" té tipus de dada incompleta"
+
+#: c-decl.c:4566
+msgid "parameter has incomplete type"
+msgstr "el paràmetre té tipus incomplet"
+
+#: c-decl.c:4615
+#, fuzzy
+msgid "\"void\" as only parameter may not be qualified"
+msgstr "el nom de la definició de tipus pot no ser qualificada per a la classe"
+
+#: c-decl.c:4636
+msgid "\"void\" must be the only parameter"
+msgstr ""
+
+#: c-decl.c:4653
+#, fuzzy
+msgid "%Jparameter \"%D\" has just a forward declaration"
+msgstr "el paràmetre \"%s\" només té una declaració posterior"
+
+#. The first %s will be one of 'struct', 'union', or 'enum'.
+#: c-decl.c:4681
+#, fuzzy, c-format
+msgid "\"%s %s\" declared inside parameter list"
+msgstr "\"struct %s\" declarat dintre d'una llista de paràmetres"
+
+#. The %s will be one of 'struct', 'union', or 'enum'.
+#: c-decl.c:4685
+#, fuzzy, c-format
+msgid "anonymous %s declared inside parameter list"
+msgstr "struct anònim declarat dintre d'una llista de paràmetres"
+
+#: c-decl.c:4689
+msgid "its scope is only this definition or declaration, which is probably not what you want"
+msgstr "el seu àmbit és solament aquesta definició o declaració, la qual cosa probablement no sigui el que desitja."
+
+#: c-decl.c:4774
+#, c-format
+msgid "redefinition of `union %s'"
+msgstr "redefinició de \"union %s\""
+
+#: c-decl.c:4776
+#, c-format
+msgid "redefinition of `struct %s'"
+msgstr "redefinició de \"struct %s\""
+
+#: c-decl.c:4844 cp/decl.c:3534
+msgid "declaration does not declare anything"
+msgstr "la declaració no declara res"
+
+#: c-decl.c:4889 c-decl.c:4905
+#, fuzzy
+msgid "%Jduplicate member '%D'"
+msgstr "membre duplicat \"%D\""
+
+#: c-decl.c:4939 c-decl.c:4942
+#, c-format
+msgid "%s defined inside parms"
+msgstr "es va definir %s dintre dels paràmetres"
+
+#: c-decl.c:4940 c-decl.c:4943 c-decl.c:4954
+msgid "union"
+msgstr "unió"
+
+#: c-decl.c:4940 c-decl.c:4943
+msgid "structure"
+msgstr "estructura"
+
+#: c-decl.c:4953
+#, c-format
+msgid "%s has no %s"
+msgstr "%s no té %s"
+
+#: c-decl.c:4954
+msgid "struct"
+msgstr "struct"
+
+#: c-decl.c:4955
+msgid "named members"
+msgstr "membres nomenats"
+
+#: c-decl.c:4955
+msgid "members"
+msgstr "membres"
+
+#: c-decl.c:4994
+#, c-format
+msgid "nested redefinition of `%s'"
+msgstr "redefinició niada de \"%s\""
+
+#: c-decl.c:5015
+#, fuzzy
+msgid "%Jflexible array member in union"
+msgstr "membre de matriu flexible en el union"
+
+#: c-decl.c:5020
+#, fuzzy
+msgid "%Jflexible array member not at end of struct"
+msgstr "el membre de matriu flexible no està al final del struct"
+
+#: c-decl.c:5025
+#, fuzzy
+msgid "%Jflexible array member in otherwise empty struct"
+msgstr "el membre de matriu flexible seria d'altra manera un struct buit"
+
+#: c-decl.c:5032
+#, fuzzy
+msgid "%Jinvalid use of structure with flexible array member"
+msgstr "ús invàlid de structura amb membres de matriu flexible"
+
+#: c-decl.c:5127
+msgid "union cannot be made transparent"
+msgstr "union no es pot fer transparent"
+
+#. This enum is a named one that has been declared already.
+#: c-decl.c:5196
+#, c-format
+msgid "redeclaration of `enum %s'"
+msgstr "redeclaració de \"enum %s\""
+
+#: c-decl.c:5227
+msgid "enum defined inside parms"
+msgstr "enum definit dintre dels paràmetres"
+
+#: c-decl.c:5260
+msgid "enumeration values exceed range of largest integer"
+msgstr "els valors d'enumeració excedeixen el rang de l'enter més gran"
+
+#: c-decl.c:5363
+#, c-format
+msgid "enumerator value for `%s' not integer constant"
+msgstr "el valor de enumerator per a \"%s\" no és una constant entera"
+
+#: c-decl.c:5376
+msgid "overflow in enumeration values"
+msgstr "desbordament en valors d'enumeració"
+
+#: c-decl.c:5381
+msgid "ISO C restricts enumerator values to range of `int'"
+msgstr "ISO C restringeix els valors d'enumeració al rang de \"int\""
+
+#: c-decl.c:5457
+msgid "return type is an incomplete type"
+msgstr "el tipus de devolució és un tipus de dada incompleta"
+
+#: c-decl.c:5465
+msgid "return type defaults to `int'"
+msgstr "el tipus de devolució per omissió és \"int\""
+
+#: c-decl.c:5501
+#, fuzzy
+msgid "%Jno previous prototype for '%D'"
+msgstr "no hi ha un prototip previ per a \"%s\""
+
+#: c-decl.c:5507
+#, fuzzy
+msgid "%J'%D' was used with no prototype before its definition"
+msgstr "es va usar \"%s\" sense prototip abans de la seva definició"
+
+#: c-decl.c:5514
+#, fuzzy
+msgid "%Jno previous declaration for '%D'"
+msgstr "no hi ha declaració prèvia per a \"%s\""
+
+#: c-decl.c:5520
+#, fuzzy
+msgid "%J`%D' was used with no declaration before its definition"
+msgstr "es va usar \"%s\" sense prototip abans de la seva definició"
+
+#: c-decl.c:5556 c-decl.c:6062
+#, fuzzy
+msgid "%Jreturn type of '%D' is not `int'"
+msgstr "el tipus de devolució de \"%s\" no és \"int\""
+
+#: c-decl.c:5571
+#, fuzzy
+msgid "%Jfirst argument of '%D' should be `int'"
+msgstr "el primer argument de \"%s\" deu ser \"int\""
+
+#: c-decl.c:5580
+#, fuzzy
+msgid "%Jsecond argument of '%D' should be 'char **'"
+msgstr "el segon argument de \"%s\" deu ser \"char **\""
+
+#: c-decl.c:5589
+#, fuzzy
+msgid "%Jthird argument of '%D' should probably be 'char **'"
+msgstr "el tercer argument de \"%s\" deuria ser \"char **\""
+
+#: c-decl.c:5599
+#, fuzzy
+msgid "%J'%D' takes only zero or two arguments"
+msgstr "\"%s\" només pren zero o dos arguments"
+
+#: c-decl.c:5602
+#, fuzzy
+msgid "%J'%D' is normally a non-static function"
+msgstr "\"%s\" generalment és una funció no estàtica"
+
+#: c-decl.c:5658
+msgid "%Jold-style parameter declarations in prototyped function definition"
+msgstr ""
+
+#: c-decl.c:5672
+#, fuzzy
+msgid "%Jparameter name omitted"
+msgstr "es va ometre el nom del paràmetre"
+
+#: c-decl.c:5747
+#, fuzzy
+msgid "%Jparameter name missing from parameter list"
+msgstr "falta el nom del paràmetre de la llista de paràmetres"
+
+#: c-decl.c:5757
+#, fuzzy
+msgid "%J\"%D\" declared as a non-parameter"
+msgstr "\"%D\" declarat com un friend"
+
+#: c-decl.c:5762
+#, fuzzy
+msgid "%Jmultiple parameters named \"%D\""
+msgstr "múltiples paràmetres nomenats \"%s\""
+
+#: c-decl.c:5770
+#, fuzzy
+msgid "%Jparameter \"%D\" declared void"
+msgstr "el paràmetre \"%D\" es va declarar void"
+
+#: c-decl.c:5785 c-decl.c:5787
+#, fuzzy
+msgid "%Jtype of \"%D\" defaults to \"int\""
+msgstr "el tipus de \"%s\" és \"int\" per omissió"
+
+#: c-decl.c:5801
+#, fuzzy
+msgid "%Jparameter \"%D\" has incomplete type"
+msgstr "el paràmetre té tipus incomplet"
+
+#: c-decl.c:5807
+#, fuzzy
+msgid "%Jdeclaration for parameter \"%D\" but no such parameter"
+msgstr "existeix la declaració per al paràmetre \"%s\" però no hi ha tal paràmetre"
+
+#: c-decl.c:5859
+msgid "number of arguments doesn't match prototype"
+msgstr "el nombre d'arguments no coincideixen amb el prototip"
+
+#: c-decl.c:5860 c-decl.c:5891 c-decl.c:5898
+#, fuzzy
+msgid "%Hprototype declaration"
+msgstr "declaració buida"
+
+#: c-decl.c:5889
+#, fuzzy
+msgid "promoted argument \"%D\" doesn't match prototype"
+msgstr "l'argument promogut \"%s\" no coincideix amb el prototip"
+
+#: c-decl.c:5897
+#, fuzzy
+msgid "argument \"%D\" doesn't match prototype"
+msgstr "l'argument \"%s\" no coincideix amb el prototip"
+
+#: c-decl.c:6094 cp/decl.c:10849
+msgid "no return statement in function returning non-void"
+msgstr "no hi ha una declaració de devolució en una funció que retorna non-void"
+
+#: c-decl.c:6101
+msgid "this function may return with or without a value"
+msgstr "aquesta funció pot retornar amb o sense un valor"
+
+#. If we get here, declarations have been used in a for loop without
+#. the C99 for loop scope. This doesn't make much sense, so don't
+#. allow it.
+#: c-decl.c:6200
+#, fuzzy
+msgid "'for' loop initial declaration used outside C99 mode"
+msgstr "es va usar la declaració inicial del cicle \"for\" fora de la manera C99"
+
+#: c-decl.c:6224
+#, fuzzy, c-format
+msgid "'struct %s' declared in 'for' loop initial declaration"
+msgstr "\"struct %s\" declarat en la declaració inicial del cicle \"for\""
+
+#: c-decl.c:6227
+#, fuzzy, c-format
+msgid "'union %s' declared in 'for' loop initial declaration"
+msgstr "\"union %s\" declarat en la declaració inicial del cicle \"for\""
+
+#: c-decl.c:6230
+#, fuzzy, c-format
+msgid "'enum %s' declared in 'for' loop initial declaration"
+msgstr "\"enum %s\" declarat en la declaració inicial del cicle \"for\""
+
+#: c-decl.c:6238
+#, fuzzy
+msgid "%Jdeclaration of non-variable '%D' in 'for' loop initial declaration"
+msgstr "declaració de \"%s\" que no és variable en la declaració inicial del cicle \"for\""
+
+#: c-decl.c:6241
+#, fuzzy
+msgid "%Jdeclaration of static variable '%D' in 'for' loop initial declaration"
+msgstr "declaració de la variable static \"%s\" en la declaració inicial del cicle \"for\""
+
+#: c-decl.c:6244
+#, fuzzy
+msgid "%Jdeclaration of 'extern' variable '%D' in 'for' loop initial declaration"
+msgstr "declaració de la variable \"extern\" \"%s\" en la declaració inicial del cicle `for\""
+
+#: c-decl.c:6557
+#, fuzzy
+msgid "%Jredefinition of global '%D'"
+msgstr "redefinició de \"%s\""
+
+#: c-decl.c:6558
+#, fuzzy
+msgid "%J'%D' previously defined here"
+msgstr "es va definir \"%#D\" prèviament aquí"
+
+#: c-format.c:94 c-format.c:210
+msgid "format string has invalid operand number"
+msgstr "la cadena de format té un nombre d'operadors invàlid"
+
+#: c-format.c:111
+msgid "function does not return string type"
+msgstr "la funció no retorna un tipus string"
+
+#: c-format.c:140
+msgid "format string arg not a string type"
+msgstr "l'argument de la cadena de format no és del tipus cadena de text"
+
+#: c-format.c:190
+msgid "unrecognized format specifier"
+msgstr "no es reconeix el especificador de format"
+
+#: c-format.c:203
+#, c-format
+msgid "`%s' is an unrecognized format function type"
+msgstr "\"%s\" és un format de tipus de funció no reconegut"
+
+#: c-format.c:216
+#, fuzzy
+msgid "'...' has invalid operand number"
+msgstr "la cadena de format té un nombre d'operadors invàlid"
+
+#: c-format.c:224
+msgid "format string arg follows the args to be formatted"
+msgstr "l'argument de la cadena de format segueix als arguments que rebran format"
+
+#: c-format.c:565 c-format.c:589
+msgid "` ' flag"
+msgstr "opció \" \""
+
+#: c-format.c:565 c-format.c:589
+msgid "the ` ' printf flag"
+msgstr "l'opció de printf \" \""
+
+#: c-format.c:566 c-format.c:590 c-format.c:627 c-format.c:683
+msgid "`+' flag"
+msgstr "opció \"+\""
+
+#: c-format.c:566 c-format.c:590 c-format.c:627
+msgid "the `+' printf flag"
+msgstr "l'opció \"+\" de printf"
+
+#: c-format.c:567 c-format.c:591 c-format.c:628 c-format.c:659
+msgid "`#' flag"
+msgstr "opció \"#\""
+
+#: c-format.c:567 c-format.c:591 c-format.c:628
+msgid "the `#' printf flag"
+msgstr "l'opció \"#\" de printf"
+
+#: c-format.c:568 c-format.c:592 c-format.c:657
+msgid "`0' flag"
+msgstr "opció \"0\""
+
+#: c-format.c:568 c-format.c:592
+msgid "the `0' printf flag"
+msgstr "l'opció \"0\" de printf"
+
+#: c-format.c:569 c-format.c:593 c-format.c:656 c-format.c:686
+msgid "`-' flag"
+msgstr "opció \"-\""
+
+#: c-format.c:569 c-format.c:593
+msgid "the `-' printf flag"
+msgstr "l'opció \"-\" de printf"
+
+#: c-format.c:570 c-format.c:640
+msgid "`'' flag"
+msgstr "opció \"'\""
+
+#: c-format.c:570
+msgid "the `'' printf flag"
+msgstr "l'opció \"'\" de printf"
+
+#: c-format.c:571 c-format.c:641
+msgid "`I' flag"
+msgstr "opció \"I\""
+
+#: c-format.c:571
+msgid "the `I' printf flag"
+msgstr "l'opció \"I\" de printf"
+
+#: c-format.c:572 c-format.c:594 c-format.c:638 c-format.c:660 c-format.c:687
+#: c-format.c:1802
+msgid "field width"
+msgstr "amplària de camp"
+
+#: c-format.c:572 c-format.c:594
+msgid "field width in printf format"
+msgstr "amplària de camp en format printf"
+
+#: c-format.c:573 c-format.c:595 c-format.c:618 c-format.c:629
+msgid "precision"
+msgstr "precisió"
+
+#: c-format.c:573 c-format.c:595 c-format.c:618 c-format.c:629
+msgid "precision in printf format"
+msgstr "precisió en format printf"
+
+#: c-format.c:574 c-format.c:596 c-format.c:619 c-format.c:630 c-format.c:639
+#: c-format.c:690
+msgid "length modifier"
+msgstr "modificador de longitud"
+
+#: c-format.c:574 c-format.c:596 c-format.c:619 c-format.c:630
+msgid "length modifier in printf format"
+msgstr "modificador de longitud en format printf"
+
+#: c-format.c:636
+msgid "assignment suppression"
+msgstr "supressió de l'assignació"
+
+#: c-format.c:636
+msgid "the assignment suppression scanf feature"
+msgstr "la supressió de l'assignació és una característica de scanf"
+
+#: c-format.c:637
+msgid "`a' flag"
+msgstr "opció \"a\""
+
+#: c-format.c:637
+msgid "the `a' scanf flag"
+msgstr "l'opció \"a\" de scanf"
+
+#: c-format.c:638
+msgid "field width in scanf format"
+msgstr "amplària de camp en format scanf"
+
+#: c-format.c:639
+msgid "length modifier in scanf format"
+msgstr "modificador de longitud en format scanf"
+
+#: c-format.c:640
+msgid "the `'' scanf flag"
+msgstr "l'opció \"'\" de scanf"
+
+#: c-format.c:641
+msgid "the `I' scanf flag"
+msgstr "l'opció \"I\" de scanf"
+
+#: c-format.c:655
+msgid "`_' flag"
+msgstr "l'opció \"_\""
+
+#: c-format.c:655
+msgid "the `_' strftime flag"
+msgstr "l'opció \"_\" de strftime"
+
+#: c-format.c:656
+msgid "the `-' strftime flag"
+msgstr "l'opció \"-\" de strftime"
+
+#: c-format.c:657
+msgid "the `0' strftime flag"
+msgstr "l'opció \"0\" de strftime"
+
+#: c-format.c:658 c-format.c:682
+msgid "`^' flag"
+msgstr "opció \"^\""
+
+#: c-format.c:658
+msgid "the `^' strftime flag"
+msgstr "l'opció \"^\" de strftime"
+
+#: c-format.c:659
+msgid "the `#' strftime flag"
+msgstr "l'opció \"#\" de strftime"
+
+#: c-format.c:660
+msgid "field width in strftime format"
+msgstr "amplària de camp en format strftime"
+
+#: c-format.c:661
+msgid "`E' modifier"
+msgstr "modificador \"E\""
+
+#: c-format.c:661
+msgid "the `E' strftime modifier"
+msgstr "el modificador \"E\" de strftime"
+
+#: c-format.c:662
+msgid "`O' modifier"
+msgstr "modificador \"O\""
+
+#: c-format.c:662
+msgid "the `O' strftime modifier"
+msgstr "el modificador \"O\" de strftime"
+
+#: c-format.c:663
+msgid "the `O' modifier"
+msgstr "el modificador \"O\""
+
+#: c-format.c:681
+msgid "fill character"
+msgstr "caràcter de farciment"
+
+#: c-format.c:681
+msgid "fill character in strfmon format"
+msgstr "caràcter de farciment en format strfmon"
+
+#: c-format.c:682
+msgid "the `^' strfmon flag"
+msgstr "l'opció \"^\" de strfmon"
+
+#: c-format.c:683
+msgid "the `+' strfmon flag"
+msgstr "l'opció \"+\" de strfmon"
+
+#: c-format.c:684
+msgid "`(' flag"
+msgstr "opció \"(\""
+
+#: c-format.c:684
+msgid "the `(' strfmon flag"
+msgstr "l'opció \"(\" de strfmon"
+
+#: c-format.c:685
+msgid "`!' flag"
+msgstr "opció \"!\""
+
+#: c-format.c:685
+msgid "the `!' strfmon flag"
+msgstr "l'opció \"!\" de strfmon"
+
+#: c-format.c:686
+msgid "the `-' strfmon flag"
+msgstr "l'opció \"-\" de strfmon"
+
+#: c-format.c:687
+msgid "field width in strfmon format"
+msgstr "amplària de camp en format strfmon"
+
+#: c-format.c:688
+msgid "left precision"
+msgstr "precisió esquerra"
+
+#: c-format.c:688
+msgid "left precision in strfmon format"
+msgstr "precisió esquerra en format strfmon"
+
+#: c-format.c:689
+msgid "right precision"
+msgstr "precisió de dreta"
+
+#: c-format.c:689
+msgid "right precision in strfmon format"
+msgstr "precisió de dreta en format strfmon"
+
+#: c-format.c:690
+msgid "length modifier in strfmon format"
+msgstr "modificador de longitud en format strfmon"
+
+#: c-format.c:1107
+#, c-format
+msgid "function might be possible candidate for `%s' format attribute"
+msgstr "la funció pot ser un candidat possible per a l'atribut de format \"%s\""
+
+#: c-format.c:1223 c-format.c:1244 c-format.c:2212
+msgid "missing $ operand number in format"
+msgstr "falta l'operant numèric $ en el format"
+
+#: c-format.c:1254
+#, c-format
+msgid "%s does not support %%n$ operand number formats"
+msgstr "%s no té suport per a l'operant de format de nombre %%n$"
+
+#: c-format.c:1261
+msgid "operand number out of range in format"
+msgstr "operant numèric fora de rang en el format"
+
+#: c-format.c:1284
+#, c-format
+msgid "format argument %d used more than once in %s format"
+msgstr "s'usa més d'una vegada l'argument de format %d en el format %s"
+
+#: c-format.c:1331
+#, c-format
+msgid "format argument %d unused before used argument %d in $-style format"
+msgstr "no s'usa l'argument de format %d abans d'usar l'argument %d en el format $-style"
+
+#: c-format.c:1429
+msgid "format not a string literal, format string not checked"
+msgstr "el format no és una cadena literal, no es va revisar la cadena de format"
+
+#: c-format.c:1443
+msgid "format not a string literal and no format arguments"
+msgstr "el format no és una cadena literal i no té arguments de format"
+
+#: c-format.c:1445
+msgid "format not a string literal, argument types not checked"
+msgstr "el format no és una cadena literal, no es van revisar els tipus d'argument"
+
+#: c-format.c:1458
+msgid "too many arguments for format"
+msgstr "massa arguments per al format"
+
+#: c-format.c:1461
+msgid "unused arguments in $-style format"
+msgstr "no es van usar arguments en el format d'estil-$"
+
+#: c-format.c:1464
+#, c-format
+msgid "zero-length %s format string"
+msgstr "cadena de format %s de longitud zero"
+
+#: c-format.c:1468
+msgid "format is a wide character string"
+msgstr "el format és una cadena de caràcter ampla"
+
+#: c-format.c:1471
+msgid "unterminated format string"
+msgstr "constant de format sense acabar"
+
+#: c-format.c:1681
+msgid "embedded `\\0' in format"
+msgstr "\"\\0\" incrustat en el format"
+
+#: c-format.c:1696
+#, c-format
+msgid "spurious trailing `%%' in format"
+msgstr "\"%%\" final espuri en el format"
+
+#: c-format.c:1735 c-format.c:1972
+#, c-format
+msgid "repeated %s in format"
+msgstr "es va repetir %s en el format"
+
+#: c-format.c:1748
+msgid "missing fill character at end of strfmon format"
+msgstr "falta el caràcter de farciment al final del format strfmon"
+
+#: c-format.c:1787 c-format.c:1886 c-format.c:2166 c-format.c:2219
+msgid "too few arguments for format"
+msgstr "molt pocs arguments per al format"
+
+#: c-format.c:1828
+#, c-format
+msgid "zero width in %s format"
+msgstr "amplària zero en el format %s"
+
+#: c-format.c:1847
+#, c-format
+msgid "empty left precision in %s format"
+msgstr "precisió esquerra buida en el format %s"
+
+#: c-format.c:1901
+msgid "field precision"
+msgstr "precisió del camp"
+
+#: c-format.c:1916
+#, c-format
+msgid "empty precision in %s format"
+msgstr "precisió buida en el format %s"
+
+#: c-format.c:1956
+#, c-format
+msgid "%s does not support the `%s' %s length modifier"
+msgstr "%s no té suport per al modificador de longitud %s \"%s\""
+
+#: c-format.c:2006
+msgid "conversion lacks type at end of format"
+msgstr "la conversió manca de tipus al final del format"
+
+#: c-format.c:2017
+#, c-format
+msgid "unknown conversion type character `%c' in format"
+msgstr "es desconeix el caràcter de tipus de conversió \"%c\" en el format"
+
+#: c-format.c:2020
+#, c-format
+msgid "unknown conversion type character 0x%x in format"
+msgstr "es desconeix el caràcter de tipus de conversió 0x%x en el format"
+
+#: c-format.c:2027
+#, c-format
+msgid "%s does not support the `%%%c' %s format"
+msgstr "%s no té suport per al format \"%%%c\" %s"
+
+#: c-format.c:2043
+#, c-format
+msgid "%s used with `%%%c' %s format"
+msgstr "es va usar %s amb el format \"%%%c\" %s"
+
+#: c-format.c:2052
+#, c-format
+msgid "%s does not support %s"
+msgstr "%s no té suport per a %s"
+
+#: c-format.c:2061
+#, c-format
+msgid "%s does not support %s with the `%%%c' %s format"
+msgstr "%s no té suport per a %s amb el format \"%%%c\" %s"
+
+#: c-format.c:2094
+#, c-format
+msgid "%s ignored with %s and `%%%c' %s format"
+msgstr "s'ignora %s amb %s i el format \"%%%c\" %s"
+
+#: c-format.c:2098
+#, c-format
+msgid "%s ignored with %s in %s format"
+msgstr "s'ignora %s amb %s en el format %s"
+
+#: c-format.c:2104
+#, c-format
+msgid "use of %s and %s together with `%%%c' %s format"
+msgstr "ús de %s i %s juntament amb el format \"%%%c\" %s"
+
+#: c-format.c:2108
+#, c-format
+msgid "use of %s and %s together in %s format"
+msgstr "ús de %s i %s junts en el format %s"
+
+#: c-format.c:2127
+#, c-format
+msgid "`%%%c' yields only last 2 digits of year in some locales"
+msgstr "\"%%%c\" només produeix els dos últims dígits de l'any en alguns llocs"
+
+#: c-format.c:2130
+#, c-format
+msgid "`%%%c' yields only last 2 digits of year"
+msgstr "\"%%%c\" només produeix els dos últims dígits de l'any"
+
+#. The end of the format string was reached.
+#: c-format.c:2146
+#, c-format
+msgid "no closing `]' for `%%[' format"
+msgstr "no hi ha un \"]\" que tancament per al format \"%%[\""
+
+#: c-format.c:2159
+#, c-format
+msgid "use of `%s' length modifier with `%c' type character"
+msgstr "ús del modificador de longitud \"%s\" amb el caràcter de tipus \"%c\""
+
+#: c-format.c:2180
+#, c-format
+msgid "%s does not support the `%%%s%c' %s format"
+msgstr "%s no té suport per al format \"%%%s%c\" %s"
+
+#: c-format.c:2195
+msgid "operand number specified with suppressed assignment"
+msgstr "nombre d'operadors especificat amb assignació suprimida"
+
+#: c-format.c:2197
+msgid "operand number specified for format taking no argument"
+msgstr "el nombre de operades especificats per al format no pren arguments"
+
+#: c-format.c:2309
+#, c-format
+msgid "writing through null pointer (arg %d)"
+msgstr "escrivint a través d'un punter nul (argument %d)"
+
+#: c-format.c:2318
+#, c-format
+msgid "reading through null pointer (arg %d)"
+msgstr "llegint a través d'un punter nul (argument %d)"
+
+#: c-format.c:2338
+#, c-format
+msgid "writing into constant object (arg %d)"
+msgstr "escrivint en un objecte constant (argument %d)"
+
+#: c-format.c:2348
+#, c-format
+msgid "extra type qualifiers in format argument (arg %d)"
+msgstr "qualificadores de tipus extra en l'argument de format (argument %d)"
+
+#: c-format.c:2355
+#, c-format
+msgid "format argument is not a pointer (arg %d)"
+msgstr "l'argument de format no és un punter (argument %d)"
+
+#: c-format.c:2357
+#, c-format
+msgid "format argument is not a pointer to a pointer (arg %d)"
+msgstr "l'argument de format no és un punter a un punter (argument %d)"
+
+#: c-format.c:2433
+msgid "pointer"
+msgstr "punter"
+
+#: c-format.c:2435
+msgid "different type"
+msgstr "diferents tipus"
+
+#: c-format.c:2456
+#, c-format
+msgid "%s is not type %s (arg %d)"
+msgstr "%s no és del tipus %s (argument %d)"
+
+#: c-format.c:2459
+#, c-format
+msgid "%s format, %s arg (arg %d)"
+msgstr "format %s, argument %s (argument %d)"
+
+#: c-format.c:2704
+msgid "args to be formatted is not '...'"
+msgstr "els arguments que rebran format no són \"...\""
+
+#: c-format.c:2713
+msgid "strftime formats cannot format arguments"
+msgstr "els formats de strftime no poden donar format als arguments"
+
+#: c-incpath.c:68
+#, c-format
+msgid "ignoring duplicate directory \"%s\"\n"
+msgstr "ignorant el directori duplicat \"%s\"\n"
+
+#: c-incpath.c:71
+msgid " as it is a non-system directory that duplicates a system directory\n"
+msgstr " perquè és un directori que no és del sistema que duplica un directori del sistema\n"
+
+#: c-incpath.c:75
+#, c-format
+msgid "ignoring nonexistent directory \"%s\"\n"
+msgstr "ignorant el directori inexistent \"%s\"\n"
+
+#: c-incpath.c:273
+msgid "#include \"...\" search starts here:\n"
+msgstr "la recerca de #include \"...\" s'inicia aquí:\n"
+
+#: c-incpath.c:277
+msgid "#include <...> search starts here:\n"
+msgstr "la recerca de #include <...> s'inicia aquí:\n"
+
+#: c-incpath.c:282
+msgid "End of search list.\n"
+msgstr "Fi de la llista de recerca.\n"
+
+#: c-lex.c:240
+msgid "badly nested C headers from preprocessor"
+msgstr "encapçalats C mal niats del preprocessador"
+
+#: c-lex.c:281
+#, c-format
+msgid "ignoring #pragma %s %s"
+msgstr "ignorant el #pragma %s %s"
+
+#. ... or not.
+#: c-lex.c:385
+#, fuzzy
+msgid "%Hstray '@' in program"
+msgstr "\"%c\" paràsit en el programa"
+
+#: c-lex.c:393
+#, c-format
+msgid "missing terminating %c character"
+msgstr "falta caràcter acabant %c"
+
+#: c-lex.c:395
+#, c-format
+msgid "stray '%c' in program"
+msgstr "\"%c\" paràsit en el programa"
+
+#: c-lex.c:397
+#, c-format
+msgid "stray '\\%o' in program"
+msgstr "\"\\%o\" paràsit en el programa"
+
+#: c-lex.c:535
+msgid "this decimal constant is unsigned only in ISO C90"
+msgstr "aquesta constant decimal només és unsigned en ISO C90"
+
+#: c-lex.c:538
+msgid "this decimal constant would be unsigned in ISO C90"
+msgstr "aquesta constant decimal serà unsigned en ISO C90 "
+
+#: c-lex.c:554
+#, c-format
+msgid "integer constant is too large for \"%s\" type"
+msgstr "la constant entera és massa gran pel tipus \"%s\""
+
+#: c-lex.c:620
+#, c-format
+msgid "floating constant exceeds range of \"%s\""
+msgstr "la constant de coma flotant excedeix el rang de \"%s\""
+
+#: c-lex.c:696
+#, fuzzy
+msgid "traditional C rejects string constant concatenation"
+msgstr "C tradicional rebutja la concatenació de cadenes"
+
+#: c-objc-common.c:82
+msgid "%Jfunction '%F' can never be inlined because it is suppressed using -fno-inline"
+msgstr ""
+
+#: c-objc-common.c:92
+msgid "%Jfunction '%F' can never be inlined because it might not be bound within this unit of translation"
+msgstr ""
+
+#: c-objc-common.c:100
+msgid "%Jfunction '%F' can never be inlined because it uses attributes conflicting with inlining"
+msgstr ""
+
+#: c-objc-common.c:115
+msgid "%Jfunction '%F' can never be inlined because it has pending sizes"
+msgstr ""
+
+#: c-objc-common.c:128
+msgid "%Jnested function '%F' can never be inlined because it has possibly saved pending sizes"
+msgstr ""
+
+#: c-opts.c:141
+#, fuzzy, c-format
+msgid "no class name specified with \"%s\""
+msgstr "no classes especificades amb \"-%s\""
+
+#: c-opts.c:145
+#, fuzzy, c-format
+msgid "assertion missing after \"%s\""
+msgstr "asserció faltant deprés de %s"
+
+#: c-opts.c:150
+#, fuzzy, c-format
+msgid "macro name missing after \"%s\""
+msgstr "nom de macro faltant deprés de %s"
+
+#: c-opts.c:157
+#, fuzzy, c-format
+msgid "missing path after \"%s\""
+msgstr "falta l'objectiu després de \"-%s\""
+
+#: c-opts.c:166
+#, fuzzy, c-format
+msgid "missing filename after \"%s\""
+msgstr "nom de fitxer faltant deprés de \"-%s\""
+
+#: c-opts.c:171
+#, fuzzy, c-format
+msgid "missing makefile target after \"%s\""
+msgstr "falta l'objectiu després de \"-%s\""
+
+#: c-opts.c:291
+msgid "-I- specified twice"
+msgstr "-I- especificat dues vegades"
+
+#: c-opts.c:692
+#, c-format
+msgid "switch \"%s\" is no longer supported"
+msgstr "el switch \"%s\" ja no té suport"
+
+#: c-opts.c:812
+#, fuzzy
+msgid "-fhandle-exceptions has been renamed -fexceptions (and is now on by default)"
+msgstr "es va re-nomenar -fhandle-exceptions a -fexceptions (i ara està activat per defecte)"
+
+#: c-opts.c:978
+msgid "output filename specified twice"
+msgstr "nom de fitxer de sortida especificat dues vegades"
+
+#: c-opts.c:1107
+msgid "-Wformat-y2k ignored without -Wformat"
+msgstr "s'ignora -Wformat-y2k sense -Wformat"
+
+#: c-opts.c:1109
+msgid "-Wformat-extra-args ignored without -Wformat"
+msgstr "s'ignora -Wformat-extra-args sense -Wformat"
+
+#: c-opts.c:1111
+msgid "-Wformat-zero-length ignored without -Wformat"
+msgstr "s'ignora -Wformat-zero-length sense -Wformat"
+
+#: c-opts.c:1113
+msgid "-Wformat-nonliteral ignored without -Wformat"
+msgstr "s'ignora -Wformat-nonliteral sense -Wformat"
+
+#: c-opts.c:1115
+msgid "-Wformat-security ignored without -Wformat"
+msgstr "s'ignora -Wformat-security sense -Wformat"
+
+#: c-opts.c:1117
+msgid "-Wmissing-format-attribute ignored without -Wformat"
+msgstr "s'ignora -Wformat-attribute sense -Wformat"
+
+#: c-opts.c:1131
+#, fuzzy, c-format
+msgid "opening output file %s: %m"
+msgstr "obrint el fitxer de sortida %s"
+
+#: c-opts.c:1136
+#, c-format
+msgid "too many filenames given. Type %s --help for usage"
+msgstr "massa noms de fitxers. Teclegi %s --help per a informació d'ùs"
+
+#: c-opts.c:1215
+msgid "YYDEBUG not defined"
+msgstr "no es va definir YYDEBUG"
+
+#: c-opts.c:1261
+#, fuzzy, c-format
+msgid "opening dependency file %s: %m"
+msgstr "obrint el fitxer de dependències %s"
+
+#: c-opts.c:1271
+#, fuzzy, c-format
+msgid "closing dependency file %s: %m"
+msgstr "tancant el fitxer de dependències %s"
+
+#: c-opts.c:1274
+#, fuzzy, c-format
+msgid "when writing output to %s: %m"
+msgstr "a l'escriure a %s"
+
+#: c-opts.c:1344
+msgid "to generate dependencies you must specify either -M or -MM"
+msgstr "per a generar dependències deu especificar -M o -MM"
+
+#: c-opts.c:1404
+msgid "<built-in>"
+msgstr "<built-in>"
+
+#: c-opts.c:1419
+msgid "<command line>"
+msgstr "<command line>"
+
+#: c-opts.c:1503
+msgid "too late for # directive to set debug directory"
+msgstr ""
+
+#. Like YYERROR but do call yyerror.
+#: c-parse.y:54 objc/objc-parse.y:54
+msgid "syntax error"
+msgstr "error sintàctic"
+
+#: /usr/share/bison/bison.simple:179
+msgid "syntax error: cannot back up"
+msgstr "error sintàctic: no es pot regressar"
+
+#: c-parse.y:320 objc/objc-parse.y:344
+msgid "ISO C forbids an empty source file"
+msgstr "ISO C prohibeix un fitxer font buit"
+
+#: c-parse.y:349 c-typeck.c:6225 objc/objc-parse.y:374
+msgid "argument of `asm' is not a constant string"
+msgstr "l'argument de \"asm\" no és una cadena constant"
+
+#: c-parse.y:357 objc/objc-parse.y:382
+msgid "ISO C forbids data definition with no type or storage class"
+msgstr "ISO C prohibeix la definició de dades sense tipus o classe d'emmagatzematge"
+
+#: c-parse.y:359 objc/objc-parse.y:384
+msgid "data definition has no type or storage class"
+msgstr "la definició de dades no té tipus o classe d'emmagatzematge"
+
+#: c-parse.y:372 objc/objc-parse.y:397
+msgid "ISO C does not allow extra `;' outside of a function"
+msgstr "ISO C no permet \";\" extra fora d'una funció"
+
+#: c-parse.y:429 cppexp.c:1253
+msgid "traditional C rejects the unary plus operator"
+msgstr "C tradicional rebutja l'operador unari mes"
+
+#: c-parse.y:476 objc/objc-parse.y:501
+msgid "`sizeof' applied to a bit-field"
+msgstr "\"sizeof\" aplicat a un camp de bits"
+
+#: c-parse.y:563 objc/objc-parse.y:588
+msgid "ISO C forbids omitting the middle term of a ?: expression"
+msgstr "ISO C prohibeix l'omissió del terme mig d'una expressió ?:"
+
+#: c-parse.y:611 objc/objc-parse.y:636
+#, fuzzy
+msgid "ISO C90 forbids compound literals"
+msgstr "ISO C89 prohibeix les literals compostoses"
+
+#: c-parse.y:625 objc/objc-parse.y:650
+msgid "ISO C forbids braced-groups within expressions"
+msgstr "ISO C prohibeix grups de claus dintre d'expressions"
+
+#: c-parse.y:653 objc/objc-parse.y:678
+msgid "first argument to __builtin_choose_expr not a constant"
+msgstr "el primer argument per a __builtin_choose_expr no és una constant"
+
+#: c-parse.y:696 objc/objc-parse.y:737
+msgid "traditional C rejects ISO C style function definitions"
+msgstr "C tradicional rebutja la definició de funcions d'estil ISO·C"
+
+#: c-parse.y:699 c-parse.y:705 objc/objc-parse.y:740 objc/objc-parse.y:746
+#, fuzzy
+msgid "old-style parameter declaration"
+msgstr "no es pot usar \"::\" en la declaració de paràmetres"
+
+#: c-parse.y:967 c-parse.y:973 c-parse.y:979 c-parse.y:985 c-parse.y:1006
+#: c-parse.y:1012 c-parse.y:1018 c-parse.y:1024 c-parse.y:1057 c-parse.y:1063
+#: c-parse.y:1069 c-parse.y:1075 c-parse.y:1120 c-parse.y:1126 c-parse.y:1132
+#: c-parse.y:1138 objc/objc-parse.y:1008 objc/objc-parse.y:1014
+#: objc/objc-parse.y:1020 objc/objc-parse.y:1026 objc/objc-parse.y:1047
+#: objc/objc-parse.y:1053 objc/objc-parse.y:1059 objc/objc-parse.y:1065
+#: objc/objc-parse.y:1098 objc/objc-parse.y:1104 objc/objc-parse.y:1110
+#: objc/objc-parse.y:1116 objc/objc-parse.y:1161 objc/objc-parse.y:1167
+#: objc/objc-parse.y:1173 objc/objc-parse.y:1179
+#, c-format
+msgid "`%s' is not at beginning of declaration"
+msgstr "\"%s\" no està en l'inici de la declaració"
+
+#: c-parse.y:1300 objc/objc-parse.y:1350
+#, fuzzy
+msgid "`typeof' applied to a bit-field"
+msgstr "\"sizeof\" aplicat a un camp de bits"
+
+#: c-parse.y:1427 objc/objc-parse.y:1477
+msgid "ISO C forbids empty initializer braces"
+msgstr "ISO C prohibeix les claus de iniciador buides"
+
+#: c-parse.y:1441 objc/objc-parse.y:1491
+#, fuzzy
+msgid "ISO C90 forbids specifying subobject to initialize"
+msgstr "ISO C89 prohibeix l'especificació de subobjectes a iniciar"
+
+#: c-parse.y:1444 objc/objc-parse.y:1494
+msgid "obsolete use of designated initializer without `='"
+msgstr "ús obsolet del iniciador designat sense \"=\""
+
+#: c-parse.y:1448 objc/objc-parse.y:1498
+msgid "obsolete use of designated initializer with `:'"
+msgstr "ús obsolet del iniciador designat amb \":\""
+
+#: c-parse.y:1475 objc/objc-parse.y:1525
+msgid "ISO C forbids specifying range of elements to initialize"
+msgstr "ISO C prohibeix l'especificació de rangs d'elements a iniciar"
+
+#: c-parse.y:1483 c-parse.y:1514 objc/objc-parse.y:1533 objc/objc-parse.y:1564
+msgid "ISO C forbids nested functions"
+msgstr "ISO C prohibeix les funcions niades"
+
+#: c-parse.y:1691 objc/objc-parse.y:1743
+msgid "ISO C forbids forward references to `enum' types"
+msgstr "ISO C prohibeix les declaracions posteriors per a tipus \"enum\""
+
+#: c-parse.y:1703 cp/parser.c:9307 objc/objc-parse.y:1755
+msgid "comma at end of enumerator list"
+msgstr "coma al final de la llista de numeradors"
+
+#: c-parse.y:1723 objc/objc-parse.y:1775
+msgid "no semicolon at end of struct or union"
+msgstr "no hi ha punt i coma al final del struct o union"
+
+#: c-parse.y:1732 objc/objc-parse.y:1784 objc/objc-parse.y:2846
+msgid "extra semicolon in struct or union specified"
+msgstr "es va especificar un punt i coma extra en un struct o union"
+
+#: c-parse.y:1745 objc/objc-parse.y:1800
+msgid "ISO C doesn't support unnamed structs/unions"
+msgstr "ISO C no té suport per a structs/unions sense nom"
+
+#: c-parse.y:1754 objc/objc-parse.y:1809
+msgid "ISO C forbids member declarations with no members"
+msgstr "ISO C prohibeix declaracions de membres sense membres"
+
+#: c-parse.y:1915 objc/objc-parse.y:1970
+#, fuzzy
+msgid "label at end of compound statement"
+msgstr "ús depreciada de l'etiqueta al final de la declaració compostosa"
+
+#: c-parse.y:1934 objc/objc-parse.y:1989
+#, fuzzy
+msgid "ISO C90 forbids mixed declarations and code"
+msgstr "ISO C89 prohibeix les declaracions barrejades i codi"
+
+#: c-parse.y:2012 objc/objc-parse.y:2069
+msgid "ISO C forbids label declarations"
+msgstr "ISO C prohibeix les declaracions etiquetades"
+
+#: c-parse.y:2062 objc/objc-parse.y:2119
+msgid "braced-group within expression allowed only inside a function"
+msgstr "un grup de claus dintre d'una expressió només es permet dintre d'una funció"
+
+#: c-parse.y:2184 objc/objc-parse.y:2241
+msgid "empty body in an else-statement"
+msgstr "cos buit en una declaració else"
+
+#: c-parse.y:2192 objc/objc-parse.y:2249
+#, fuzzy
+msgid "%Hempty body in an if-statement"
+msgstr "cos buit en una declaració else"
+
+#: c-parse.y:2272 cp/parser.c:6045 objc/objc-parse.y:2329
+msgid "break statement not within loop or switch"
+msgstr "la declaració break no està dintre d'un cicle o switch"
+
+#: c-parse.y:2281 cp/parser.c:6056 objc/objc-parse.y:2338
+msgid "continue statement not within a loop"
+msgstr "la declaració continue no està dintre dintre d'un cicle"
+
+#: c-parse.y:2323 objc/objc-parse.y:2380
+msgid "ISO C forbids `goto *expr;'"
+msgstr "ISO C prohibeix \"goto *expr;\""
+
+#. Gcc used to allow this as an extension. However, it does
+#. not work for all targets, and thus has been disabled.
+#. Also, since func (...) and func () are indistinguishable,
+#. it caused problems with the code in expand_builtin which
+#. tries to verify that BUILT_IN_NEXT_ARG is being used
+#. correctly.
+#: c-parse.y:2440 objc/objc-parse.y:2548
+msgid "ISO C requires a named argument before `...'"
+msgstr "ISO C requereix un argument amb nom abans de \"...\""
+
+#: c-parse.y:2538 objc/objc-parse.y:2646
+msgid "`...' in old-style identifier list"
+msgstr "\"...\" en una llista d'identificadors d'estil antic"
+
+#: /usr/share/bison/bison.simple:795
+msgid "parse error; also virtual memory exhausted"
+msgstr "error d'analitza; també es va excedir la memòria virtual"
+
+#: /usr/share/bison/bison.simple:799
+msgid "parse error"
+msgstr "error d'analitza"
+
+#: /usr/share/bison/bison.simple:924
+msgid "parser stack overflow"
+msgstr "desbordament de la pila del analitzador"
+
+#: c-parse.y:2968 objc/objc-parse.y:3663
+#, c-format
+msgid "syntax error at '%s' token"
+msgstr "error sintàctic en l'element \"%s\""
+
+#: c-pch.c:125
+#, fuzzy, c-format
+msgid "can't create precompiled header %s: %m"
+msgstr "%s: no es pot crear/obrir el fitxer net \"%s\": %s\n"
+
+#: c-pch.c:146
+#, fuzzy, c-format
+msgid "can't write to %s: %m"
+msgstr "no es pot escriure al fitxer de sortida"
+
+#: c-pch.c:152
+#, fuzzy, c-format
+msgid "`%s' is not a valid output file"
+msgstr "\"%s\" no és un nom de fitxer vàlid"
+
+#: c-pch.c:181 c-pch.c:197 c-pch.c:209
+#, fuzzy, c-format
+msgid "can't write %s: %m"
+msgstr "no és pot obrir %s"
+
+#: c-pch.c:187
+#, fuzzy, c-format
+msgid "can't seek in %s: %m"
+msgstr "no és pot obrir %s"
+
+#: c-pch.c:195 c-pch.c:240 c-pch.c:268 c-pch.c:273 c-pch.c:351
+#, fuzzy, c-format
+msgid "can't read %s: %m"
+msgstr "no és pot obrir %s"
+
+#: c-pch.c:253
+#, c-format
+msgid "%s: not compatible with this GCC version"
+msgstr ""
+
+#. It's a PCH for the wrong language.
+#: c-pch.c:256
+#, fuzzy, c-format
+msgid "%s: not for %s"
+msgstr "%s no té suport per a %s"
+
+#. Not any kind of PCH.
+#: c-pch.c:260
+#, fuzzy, c-format
+msgid "%s: not a PCH file"
+msgstr "%s: no és un fitxer COFF"
+
+#: c-pch.c:279
+#, c-format
+msgid "%s: created on host `%.*s', but used on host `%s'"
+msgstr ""
+
+#: c-pch.c:289
+#, c-format
+msgid "%s: created for target `%.*s', but used for target `%s'"
+msgstr ""
+
+#: c-pch.c:302
+#, c-format
+msgid "%s: created by version `%.*s', but this is version `%s'"
+msgstr ""
+
+#: c-pch.c:313
+#, fuzzy, c-format
+msgid "%s: created using different flags"
+msgstr "\"%s\" redeclarat com un tipus diferent de símbol"
+
+#: c-pch.c:326
+#, c-format
+msgid "%s: created with -g%s, but used with -g%s"
+msgstr ""
+
+#: c-pch.c:340
+#, c-format
+msgid "%s: had text segment at different address"
+msgstr ""
+
+#: c-pch.c:357 cpperror.c:176 gcc.c:6554
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: c-pch.c:388
+#, fuzzy
+msgid "calling fdopen"
+msgstr "fdopen"
+
+#: c-pch.c:396 c-pch.c:408
+#, fuzzy
+msgid "reading"
+msgstr "creant %s"
+
+#: c-pragma.c:106
+msgid "#pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
+msgstr "es va trobar un #pragma pack (pop) sense un #pragma pack (push, <n>) coincident"
+
+#: c-pragma.c:124
+#, c-format
+msgid "#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
+msgstr "es va trobar un #pragma pack (pop, %s) sense un #pragma pack (push, %s, <n>) coincident"
+
+#: c-pragma.c:144
+msgid "#pragma pack(push[, id], <n>) is not supported on this target"
+msgstr "no es dóna suport a #pragma pack(push[, id], <n>) en aquest objectiu"
+
+#: c-pragma.c:146
+msgid "#pragma pack(pop[, id], <n>) is not supported on this target"
+msgstr "no es dóna suport a #pragma pack(pop[, id], <n>) en aquest objectiu"
+
+#: c-pragma.c:165
+msgid "missing '(' after '#pragma pack' - ignored"
+msgstr "\"(\" faltant desprès de \"#pragma pack\" - ignorat"
+
+#: c-pragma.c:178 c-pragma.c:228
+msgid "malformed '#pragma pack' - ignored"
+msgstr "\"#pragma pack\" malformat - ignorat"
+
+#: c-pragma.c:183
+msgid "malformed '#pragma pack(push[, id], <n>)' - ignored"
+msgstr "\"#pragma pack(push[, id], <n>)\" malformat - ignorat"
+
+#: c-pragma.c:185
+msgid "malformed '#pragma pack(pop[, id])' - ignored"
+msgstr "\"#pragma pack(pop[, id])\" malformat - ignorat"
+
+#: c-pragma.c:194
+#, c-format
+msgid "unknown action '%s' for '#pragma pack' - ignored"
+msgstr "acció \"%s\" desconeguda per a \"#pragma pack\" - ignorat"
+
+#: c-pragma.c:231
+msgid "junk at end of '#pragma pack'"
+msgstr "escombraries al final de \"#pragma pack\""
+
+#: c-pragma.c:245
+#, c-format
+msgid "alignment must be a small power of two, not %d"
+msgstr "l'alineació deu ser una potència petita de dos, no %d"
+
+#: c-pragma.c:278
+#, fuzzy
+msgid "%Japplying #pragma weak '%D' after first use results in unspecified behavior"
+msgstr "l'aplicació del #pragma weak \"%s\" després del primer ús resulta en conducta no especificada"
+
+#: c-pragma.c:325 c-pragma.c:330
+msgid "malformed #pragma weak, ignored"
+msgstr "#pragma weak malformat, ignorat"
+
+#: c-pragma.c:334
+msgid "junk at end of #pragma weak"
+msgstr "escombraries al final de \"#pragma weak\""
+
+#: c-pragma.c:367 c-pragma.c:372
+msgid "malformed #pragma redefine_extname, ignored"
+msgstr "#pragma redefine_extname malformat, ignorat"
+
+#: c-pragma.c:377
+msgid "junk at end of #pragma redefine_extname"
+msgstr "escombraries al final de #pragma redefine_extname"
+
+#: c-pragma.c:384 c-pragma.c:462
+msgid "#pragma redefine_extname conflicts with declaration"
+msgstr "#pragma redefine_extname té conflictes amb la declaració"
+
+#: c-pragma.c:413
+msgid "malformed #pragma extern_prefix, ignored"
+msgstr "#pragma extern_prefix malformat, ignorat"
+
+#: c-pragma.c:418
+msgid "junk at end of #pragma extern_prefix"
+msgstr "escombraries al final de #pragma extern_prefix"
+
+#: c-pragma.c:449
+msgid "asm declaration conflicts with previous rename"
+msgstr "la declaració asm causa conflictes amb el rename previ"
+
+#: c-semantics.c:697
+#, fuzzy
+msgid "destructor needed for `%D'"
+msgstr "es necessita un destructor per a \"%#D\""
+
+#: c-semantics.c:698
+msgid "where case label appears here"
+msgstr "on l'etiqueta casi apareix aquí"
+
+#: c-semantics.c:701
+msgid "(enclose actions of previous case statements requiring destructors in their own scope.)"
+msgstr "(les accions adjuntes de declaracions casi prèvies requereixen destructors en el seu propi àmbit.)"
+
+#: c-semantics.c:737 c-typeck.c:6247 cp/semantics.c:1070
+#, c-format
+msgid "%s qualifier ignored on asm"
+msgstr "qualificador %s ignorat en asm"
+
+#: c-semantics.c:991
+#, fuzzy
+msgid "will never be executed"
+msgstr "la cridada %2d mai s'executa\n"
+
+#: c-typeck.c:120
+#, c-format
+msgid "`%s' has an incomplete type"
+msgstr "\"%s\" té un tipus incompleta"
+
+#: c-typeck.c:142 cp/call.c:2532
+msgid "invalid use of void expression"
+msgstr "ús invàlid de l'expressió void"
+
+#: c-typeck.c:150
+msgid "invalid use of flexible array member"
+msgstr "ús invàlid de membres de matriu flexible"
+
+#: c-typeck.c:156
+msgid "invalid use of array with unspecified bounds"
+msgstr "ús invàlid de matrius amb límits sense especificar"
+
+#: c-typeck.c:164
+#, c-format
+msgid "invalid use of undefined type `%s %s'"
+msgstr "ús invàlid del tipus indefinit \"%s %s\""
+
+#. If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.
+#: c-typeck.c:168
+#, c-format
+msgid "invalid use of incomplete typedef `%s'"
+msgstr "ús invàlid del typedef incomplet \"%s\""
+
+#: c-typeck.c:415 c-typeck.c:430
+msgid "function types not truly compatible in ISO C"
+msgstr "els tipus de funció no són totalment compatibles en ISO C"
+
+#: c-typeck.c:611
+msgid "types are not quite compatible"
+msgstr "els tipus no són totalment compatibles"
+
+#: c-typeck.c:824
+#, fuzzy
+msgid "function return types not compatible due to `volatile'"
+msgstr "el tipus de devolució d'una funció no pot ser una funció"
+
+#: c-typeck.c:970 c-typeck.c:2151
+msgid "arithmetic on pointer to an incomplete type"
+msgstr "aritmètica en apuntador a un tipus incomplet"
+
+#: c-typeck.c:1343
+#, c-format
+msgid "%s has no member named `%s'"
+msgstr "%s no té un membre cridat \"%s\""
+
+#: c-typeck.c:1379
+#, c-format
+msgid "request for member `%s' in something not a structure or union"
+msgstr "petició del membre \"%s\" en alguna cosa que no és estructura o unió"
+
+#: c-typeck.c:1408
+msgid "dereferencing pointer to incomplete type"
+msgstr "punter dereferènciat a tipus de dada incompleta"
+
+#: c-typeck.c:1412
+msgid "dereferencing `void *' pointer"
+msgstr "dereferènciant el punter \"void *\""
+
+#: c-typeck.c:1429 cp/typeck.c:2104
+#, c-format
+msgid "invalid type argument of `%s'"
+msgstr "argument de tipus invàlid de \"%s\""
+
+#: c-typeck.c:1447 cp/typeck.c:2129
+msgid "subscript missing in array reference"
+msgstr "falta subindici en la referència de la matriu"
+
+#: c-typeck.c:1468 cp/typeck.c:2171
+msgid "array subscript has type `char'"
+msgstr "el subindici de matriu té un tipus \"char\""
+
+#: c-typeck.c:1476 c-typeck.c:1565 cp/typeck.c:2175 cp/typeck.c:2261
+msgid "array subscript is not an integer"
+msgstr "el subindici de la matriu no és un enter"
+
+#: c-typeck.c:1509
+msgid "ISO C forbids subscripting `register' array"
+msgstr "ISO C prohibeix el subindici d'una matriu \"register\""
+
+#: c-typeck.c:1511
+msgid "ISO C90 forbids subscripting non-lvalue array"
+msgstr "ISO C90 prohibeix el subindici d'una matriu non-lvalue"
+
+#: c-typeck.c:1544
+msgid "subscript has type `char'"
+msgstr "el subindici és de tipus \"char\""
+
+#: c-typeck.c:1560 cp/typeck.c:2256
+msgid "subscripted value is neither array nor pointer"
+msgstr "el valor indicat pel subindici no és ni matriu ni punter"
+
+#: c-typeck.c:1590
+#, c-format
+msgid "local declaration of `%s' hides instance variable"
+msgstr "la declaració local de \"%s\" oculta la variable d'instància"
+
+#: c-typeck.c:1683
+msgid "called object is not a function"
+msgstr "l'objecte cridat no és una funció"
+
+#. This situation leads to run-time undefined behavior. We can't,
+#. therefore, simply error unless we can prove that all possible
+#. executions of the program must execute the code.
+#: c-typeck.c:1715
+msgid "function called through a non-compatible type"
+msgstr ""
+
+#: c-typeck.c:1813 cp/typeck.c:2544
+msgid "too many arguments to function"
+msgstr "massa arguments per a la funció"
+
+#: c-typeck.c:1834
+#, c-format
+msgid "type of formal parameter %d is incomplete"
+msgstr "el tipus de dada del paràmetre formal %d està incomplet"
+
+#: c-typeck.c:1847
+#, c-format
+msgid "%s as integer rather than floating due to prototype"
+msgstr "%s com enter en lloc de coma flotant a causa del prototip"
+
+#: c-typeck.c:1850
+#, c-format
+msgid "%s as integer rather than complex due to prototype"
+msgstr "%s com enter en lloc de complex a causa del prototip"
+
+#: c-typeck.c:1853
+#, c-format
+msgid "%s as complex rather than floating due to prototype"
+msgstr "%s com complex en lloc de coma flotant a causa del prototip"
+
+#: c-typeck.c:1856
+#, c-format
+msgid "%s as floating rather than integer due to prototype"
+msgstr "%s com coma flotant en lloc d'enter a causa del prototip"
+
+#: c-typeck.c:1859
+#, c-format
+msgid "%s as complex rather than integer due to prototype"
+msgstr "%s com complex en lloc d'enter a causa del prototip"
+
+#: c-typeck.c:1862
+#, c-format
+msgid "%s as floating rather than complex due to prototype"
+msgstr "%s com coma flotant en lloc de complex a causa del prototip"
+
+#: c-typeck.c:1872
+#, c-format
+msgid "%s as `float' rather than `double' due to prototype"
+msgstr "%s com \"float\" en lloc de \"double\" a causa del prototip"
+
+#: c-typeck.c:1890
+#, c-format
+msgid "%s with different width due to prototype"
+msgstr "%s amb amplària diferent a causa del prototip"
+
+#: c-typeck.c:1916
+#, c-format
+msgid "%s as unsigned due to prototype"
+msgstr "%s com unsigned a causa del prototip"
+
+#: c-typeck.c:1918
+#, c-format
+msgid "%s as signed due to prototype"
+msgstr "%s com signed a causa del prototip"
+
+#: c-typeck.c:1952 cp/typeck.c:2650
+msgid "too few arguments to function"
+msgstr "molt pocs arguments per a la funció"
+
+#: c-typeck.c:1992
+msgid "suggest parentheses around + or - inside shift"
+msgstr "se suggereixen parèntesi al voltant de + o - dintre d'un desplaçament"
+
+#: c-typeck.c:1999
+msgid "suggest parentheses around && within ||"
+msgstr "se suggereixen parèntesi al voltant de && dintre de ||"
+
+#: c-typeck.c:2008
+msgid "suggest parentheses around arithmetic in operand of |"
+msgstr "se suggereixen parèntesi al voltant de l'aritmètica per a operada de |"
+
+#: c-typeck.c:2011
+msgid "suggest parentheses around comparison in operand of |"
+msgstr "se suggereixen parèntesi al voltant de les comparances per a operada de |"
+
+#: c-typeck.c:2020
+msgid "suggest parentheses around arithmetic in operand of ^"
+msgstr "se suggereixen parèntesi al voltant de l'aritmètica per a operada de ^"
+
+#: c-typeck.c:2023
+msgid "suggest parentheses around comparison in operand of ^"
+msgstr "se suggereixen parèntesi al voltant de les comparances per a operada de ^"
+
+#: c-typeck.c:2030
+msgid "suggest parentheses around + or - in operand of &"
+msgstr "se suggereixen parèntesi al voltant de + o - per a operada de &"
+
+#: c-typeck.c:2033
+msgid "suggest parentheses around comparison in operand of &"
+msgstr "se suggereixen parèntesi al voltant de les comparances per a operada de &"
+
+#: c-typeck.c:2040
+msgid "comparisons like X<=Y<=Z do not have their mathematical meaning"
+msgstr "les comparances com X<=Y<=Z no tenen el seu significat matemàtic"
+
+#: c-typeck.c:2103
+msgid "pointer of type `void *' used in subtraction"
+msgstr "es va usar un punter de tipus \"void *\" en la substracció"
+
+#: c-typeck.c:2105
+msgid "pointer to a function used in subtraction"
+msgstr "es va usar un punter a una funció en la substracció"
+
+#: c-typeck.c:2199
+msgid "wrong type argument to unary plus"
+msgstr "argument de tipus erroni per a l'increment unari"
+
+#: c-typeck.c:2212
+msgid "wrong type argument to unary minus"
+msgstr "argument de tipus erroni per al decrement unari"
+
+#: c-typeck.c:2229
+msgid "ISO C does not support `~' for complex conjugation"
+msgstr "ISO C no té suport de \"~\" per a conjugacions complexes"
+
+#: c-typeck.c:2235
+msgid "wrong type argument to bit-complement"
+msgstr "argument de tipus erroni per a complement de bits"
+
+#: c-typeck.c:2243
+msgid "wrong type argument to abs"
+msgstr "argument de tipus erroni per a abs"
+
+#: c-typeck.c:2255
+msgid "wrong type argument to conjugation"
+msgstr "argument de tipus erroni per a la conjugació"
+
+#: c-typeck.c:2269
+msgid "wrong type argument to unary exclamation mark"
+msgstr "argument de tipus erroni per al signe d'exclamació unari"
+
+#: c-typeck.c:2312
+msgid "ISO C does not support `++' and `--' on complex types"
+msgstr "ISO C no té suport per a \"++\" i \"--\" en tipus complexos"
+
+#: c-typeck.c:2327 c-typeck.c:2359
+msgid "wrong type argument to increment"
+msgstr "argument de tipus erroni per a l'increment"
+
+#: c-typeck.c:2329 c-typeck.c:2361
+msgid "wrong type argument to decrement"
+msgstr "argument de tipus erroni pel decrement"
+
+#: c-typeck.c:2350
+msgid "increment of pointer to unknown structure"
+msgstr "increment de punter a estructura desconeguda"
+
+#: c-typeck.c:2352
+msgid "decrement of pointer to unknown structure"
+msgstr "decrement de punter a estructura desconeguda"
+
+#: c-typeck.c:2477
+msgid "invalid lvalue in unary `&'"
+msgstr "l-value invàlid en \"&\" unari"
+
+#: c-typeck.c:2509
+#, c-format
+msgid "attempt to take address of bit-field structure member `%s'"
+msgstr "es va intentar prendre l'adreça del membre de l'estructura de camps de bits \"%s\""
+
+#: c-typeck.c:2642
+#, fuzzy
+msgid "use of conditional expressions as lvalues is deprecated"
+msgstr "ISO C prohibeix l'ús d'expressions condicionals com l-values"
+
+#: c-typeck.c:2645
+#, fuzzy
+msgid "use of compound expressions as lvalues is deprecated"
+msgstr "ISO C prohibeix l'ús d'expressions compostoses com l-valors"
+
+#: c-typeck.c:2648
+#, fuzzy
+msgid "use of cast expressions as lvalues is deprecated"
+msgstr "ISO C prohibeix l'ús d'expressions de conversió com l-valors"
+
+#: c-typeck.c:2663
+#, c-format
+msgid "%s of read-only member `%s'"
+msgstr "%s del membre de només lectura \"%s\""
+
+#: c-typeck.c:2667
+#, c-format
+msgid "%s of read-only variable `%s'"
+msgstr "%s de la variable de només lectura \"%s\""
+
+#: c-typeck.c:2670
+#, c-format
+msgid "%s of read-only location"
+msgstr "%s de la ubicació de només lectura"
+
+#: c-typeck.c:2688
+#, c-format
+msgid "cannot take address of bit-field `%s'"
+msgstr "no es pot adquirir l'adreça del camp de bits \"%s\""
+
+#: c-typeck.c:2716 treelang/treetree.c:946
+#, c-format
+msgid "global register variable `%s' used in nested function"
+msgstr "es va usar la variable de registre global \"%s\" en funcions niades"
+
+#: c-typeck.c:2720 treelang/treetree.c:950
+#, c-format
+msgid "register variable `%s' used in nested function"
+msgstr "es va usar la va variable \"%s\" en funcions niades"
+
+#: c-typeck.c:2727 treelang/treetree.c:957
+#, c-format
+msgid "address of global register variable `%s' requested"
+msgstr "es va sol·licitar l'adreça de la variable de registre global \"%s\""
+
+#: c-typeck.c:2739
+msgid "cannot put object with volatile field into register"
+msgstr "no es pot posar objecte amb camp volatile en register"
+
+#: c-typeck.c:2743 treelang/treetree.c:962
+#, c-format
+msgid "address of register variable `%s' requested"
+msgstr "es va sol·licitar l'adreça de la variable register \"%s\""
+
+#: c-typeck.c:2828
+msgid "signed and unsigned type in conditional expression"
+msgstr "tipus signed i unsigned en l'expressió condicional"
+
+#: c-typeck.c:2835
+msgid "ISO C forbids conditional expr with only one void side"
+msgstr "ISO C prohibeix una expressió condicional amb només un costat void"
+
+#: c-typeck.c:2851 c-typeck.c:2858
+msgid "ISO C forbids conditional expr between `void *' and function pointer"
+msgstr "ISO C prohibeix expressions condicionals entre \"void *\" i punters de funcions"
+
+#: c-typeck.c:2864
+msgid "pointer type mismatch in conditional expression"
+msgstr "els tipus de dades punters no coincideixen en l'expressió condicional"
+
+#: c-typeck.c:2871 c-typeck.c:2881
+msgid "pointer/integer type mismatch in conditional expression"
+msgstr "els tipus de dades punters/enters no coincideixen en l'expressió condicional"
+
+#: c-typeck.c:2895
+msgid "type mismatch in conditional expression"
+msgstr "els tipus de dades no coincideixen en l'expressió condicional"
+
+#: c-typeck.c:2955
+msgid "left-hand operand of comma expression has no effect"
+msgstr "l'operador del costat esquerre de l'expressió coma no té efecte"
+
+#: c-typeck.c:2986
+msgid "cast specifies array type"
+msgstr "la conversió especifica el tipus matriu"
+
+#: c-typeck.c:2992
+msgid "cast specifies function type"
+msgstr "la conversió especifica el tipus funció"
+
+#: c-typeck.c:3002
+msgid "ISO C forbids casting nonscalar to the same type"
+msgstr "ISO C prohibeix la conversió d'un no escalar al mateix tipus"
+
+#: c-typeck.c:3020
+msgid "ISO C forbids casts to union type"
+msgstr "ISO C prohibeix la conversió al tipus union"
+
+#: c-typeck.c:3028
+msgid "cast to union type from type not present in union"
+msgstr "conversió a tipus union des d'un tipus no presenti en union"
+
+#: c-typeck.c:3079
+msgid "cast adds new qualifiers to function type"
+msgstr "la conversió afegeix nou qualificadors del tipus de la funció"
+
+#. There are qualifiers present in IN_OTYPE that are not
+#. present in IN_TYPE.
+#: c-typeck.c:3084
+msgid "cast discards qualifiers from pointer target type"
+msgstr "la conversió descarta els qualificadors del tipus de la destinació del punter"
+
+#: c-typeck.c:3099
+msgid "cast increases required alignment of target type"
+msgstr "la conversió incrementa l'alineació requerida del tipus de la destinació"
+
+#: c-typeck.c:3105 cp/typeck.c:4897
+msgid "cast from pointer to integer of different size"
+msgstr "conversió de punter a enter de grandària diferent"
+
+#: c-typeck.c:3110
+msgid "cast does not match function type"
+msgstr "la conversió no coincideix amb el tipus de la funció"
+
+#: c-typeck.c:3117 cp/typeck.c:4904
+msgid "cast to pointer from integer of different size"
+msgstr "conversió a punter des d'un enter de grandària diferent"
+
+#: c-typeck.c:3129
+msgid "type-punning to incomplete type might break strict-aliasing rules"
+msgstr "el càstig de tipus a tipus incomplet pot trencar les regles d'alies estricte"
+
+#: c-typeck.c:3133
+msgid "dereferencing type-punned pointer will break strict-aliasing rules"
+msgstr "el retorn de punters de tipus castigat trencarà les regles d'alies estricte"
+
+#: c-typeck.c:3144
+#, fuzzy
+msgid "ISO C forbids conversion of function pointer to object pointer type"
+msgstr "ISO C prohibeix la comparança de \"void *\" amb un punter de funció"
+
+#: c-typeck.c:3153
+#, fuzzy
+msgid "ISO C forbids conversion of object pointer to function pointer type"
+msgstr "ISO C prohibeix la comparança de \"void *\" amb un punter de funció"
+
+#. Now we have handled acceptable kinds of LHS that are not truly lvalues.
+#. Reject anything strange now.
+#: c-typeck.c:3311
+msgid "invalid lvalue in assignment"
+msgstr "l-value invàlid en l'assignació"
+
+#. Convert new value to destination type.
+#: c-typeck.c:3320 c-typeck.c:3345 c-typeck.c:3362 cp/typeck.c:5016
+#: cp/typeck.c:5163 cp/typeck.c:5178
+msgid "assignment"
+msgstr "assignació"
+
+#: c-typeck.c:3429
+msgid "cannot pass rvalue to reference parameter"
+msgstr "no es pot passar un valor-r a un paràmetre de referència"
+
+#: c-typeck.c:3538 c-typeck.c:3614
+#, c-format
+msgid "%s makes qualified function pointer from unqualified"
+msgstr "%s fa un punter de funció qualificat des d'un no qualificat"
+
+#: c-typeck.c:3542 c-typeck.c:3594
+#, c-format
+msgid "%s discards qualifiers from pointer target type"
+msgstr "%s descarta els calificadors del tipus de la destinació del punter"
+
+#: c-typeck.c:3548
+msgid "ISO C prohibits argument conversion to union type"
+msgstr "ISO C prohibeix la conversió d'arguments a tipus union"
+
+#: c-typeck.c:3586
+#, c-format
+msgid "ISO C forbids %s between function pointer and `void *'"
+msgstr "ISO C prohibeix %s entre punters a funció i \"void *\""
+
+#: c-typeck.c:3603
+#, c-format
+msgid "pointer targets in %s differ in signedness"
+msgstr "el punter que apunta a %s difereix en signe"
+
+#: c-typeck.c:3619
+#, c-format
+msgid "%s from incompatible pointer type"
+msgstr "%s de tipus de punter incompatible"
+
+#: c-typeck.c:3625 c-typeck.c:4132 cp/typeck.c:1366
+msgid "invalid use of non-lvalue array"
+msgstr "ús invàlid de matriu no lvaluada"
+
+#: c-typeck.c:3639
+#, c-format
+msgid "%s makes pointer from integer without a cast"
+msgstr "%s crea un punter des d'un enter sense una conversió"
+
+#: c-typeck.c:3646
+#, c-format
+msgid "%s makes integer from pointer without a cast"
+msgstr "%s crea un enter des d'un punter sense una conversió"
+
+#: c-typeck.c:3660 c-typeck.c:3663
+#, c-format
+msgid "incompatible type for argument %d of `%s'"
+msgstr "tipus incompatible per a l'argument %d de \"%s\""
+
+#: c-typeck.c:3667
+#, c-format
+msgid "incompatible type for argument %d of indirect function call"
+msgstr "tipus incompatible per a l'argument %d de la cridada indirecta a funció"
+
+#: c-typeck.c:3671
+#, c-format
+msgid "incompatible types in %s"
+msgstr "tipus incompatibles en %s"
+
+#. Function name is known; supply it.
+#: c-typeck.c:3727
+#, c-format
+msgid "passing arg of `%s'"
+msgstr "passant l'argument de \"%s\""
+
+#. Function name unknown (call through ptr).
+#: c-typeck.c:3736
+msgid "passing arg of pointer to function"
+msgstr "passant l'argument del punter a la funció"
+
+#. Function name is known; supply it.
+#: c-typeck.c:3744
+#, c-format
+msgid "passing arg %d of `%s'"
+msgstr "passant l'argument %d de \"%s\""
+
+#. Function name unknown (call through ptr); just give arg number.
+#: c-typeck.c:3753
+#, c-format
+msgid "passing arg %d of pointer to function"
+msgstr "passant l'argument %d del punter a la funció"
+
+#: c-typeck.c:3810
+msgid "traditional C rejects automatic aggregate initialization"
+msgstr "C tradicional rebutja la iniciació automàtica d'agregats"
+
+#: c-typeck.c:3981 c-typeck.c:3996 c-typeck.c:4011
+#, c-format
+msgid "(near initialization for `%s')"
+msgstr "(prop de l'assignació de valors inicials per a \"%s\")"
+
+#: c-typeck.c:4060 cp/typeck2.c:560
+msgid "char-array initialized from wide string"
+msgstr "matriu de caràcters amb valors inicials assignats d'una cadena ampla"
+
+#: c-typeck.c:4067 cp/typeck2.c:567
+msgid "int-array initialized from non-wide string"
+msgstr "matriu d'enters amb valors inicials assignats d'una cadena no ampla"
+
+#: c-typeck.c:4085 cp/typeck2.c:582
+msgid "initializer-string for array of chars is too long"
+msgstr "la cadena de valors inicials per a la matriu de caràcters és massa llarga"
+
+#: c-typeck.c:4155
+msgid "array initialized from non-constant array expression"
+msgstr "matriu amb valors inicials assignats d'una expressió matricial que no és constant"
+
+#: c-typeck.c:4172 c-typeck.c:4174 c-typeck.c:4190 c-typeck.c:4211
+#: c-typeck.c:5593
+msgid "initializer element is not constant"
+msgstr "l'element de valor inicial no és constant"
+
+#: c-typeck.c:4206
+msgid "initialization"
+msgstr "assignació de valors inicials"
+
+#: c-typeck.c:4217 c-typeck.c:5598
+msgid "initializer element is not computable at load time"
+msgstr "l'element de valor inicial no és calculable al moment de la càrrega"
+
+#: c-typeck.c:4232 cp/typeck2.c:659
+msgid "invalid initializer"
+msgstr "valor inicial invàlid"
+
+#: c-typeck.c:4517 cp/decl.c:4484
+#, fuzzy
+msgid "opaque vector types cannot be initialized"
+msgstr "un objecte de grandària variable de tipus \"%T\" no pot ser inicialitzat"
+
+#: c-typeck.c:4711
+msgid "extra brace group at end of initializer"
+msgstr "grup extra de claus al final dels valors inicials"
+
+#: c-typeck.c:4731
+msgid "missing braces around initializer"
+msgstr "falten claus al voltant dels valors inicials"
+
+#: c-typeck.c:4791
+msgid "braces around scalar initializer"
+msgstr "claus al voltant del valor inicial escalar"
+
+#: c-typeck.c:4842
+msgid "initialization of flexible array member in a nested context"
+msgstr "iniciació d'un membre de matriu flexible en un context niat"
+
+#: c-typeck.c:4844
+msgid "initialization of a flexible array member"
+msgstr "iniciació d'un membre de matriu flexible"
+
+#: c-typeck.c:4875
+msgid "missing initializer"
+msgstr "falta valor inicial"
+
+#: c-typeck.c:4897
+msgid "empty scalar initializer"
+msgstr "valor inicial escalar buidor"
+
+#: c-typeck.c:4902
+msgid "extra elements in scalar initializer"
+msgstr "elements extres en valor inicial escalar"
+
+#: c-typeck.c:4987
+msgid "initialization designators may not nest"
+msgstr "no es poden niar els designadors d'iniciació"
+
+#: c-typeck.c:5008 c-typeck.c:5076
+msgid "array index in non-array initializer"
+msgstr "índex de matriu en valor inicial que no és de matriu"
+
+#: c-typeck.c:5013 c-typeck.c:5129
+msgid "field name not in record or union initializer"
+msgstr "el nom del camp no està en el inicialitzador de record o union"
+
+#: c-typeck.c:5072 c-typeck.c:5074
+msgid "nonconstant array index in initializer"
+msgstr "índex de matriu no constant en valor inicial"
+
+#: c-typeck.c:5078 c-typeck.c:5081
+msgid "array index in initializer exceeds array bounds"
+msgstr "l'índex de matriu en el valor inicial excedeix els límits de la matriu"
+
+#: c-typeck.c:5092
+msgid "empty index range in initializer"
+msgstr "rang d'índexs buit en valor inicial"
+
+#: c-typeck.c:5101
+msgid "array index range in initializer exceeds array bounds"
+msgstr "el rang d'índexs de la matriu en el valor inicial excedeix els límits de la matriu"
+
+#: c-typeck.c:5141
+#, c-format
+msgid "unknown field `%s' specified in initializer"
+msgstr "camp \"%s\" desconegut especificat en el valor inicial"
+
+#: c-typeck.c:5177 c-typeck.c:5198 c-typeck.c:5660
+msgid "initialized field with side-effects overwritten"
+msgstr "camp iniciat amb efectes laterals sobreescrits"
+
+#: c-typeck.c:5868
+msgid "excess elements in char array initializer"
+msgstr "excés d'elements en valors inicials de matriu de caràcters"
+
+#: c-typeck.c:5875 c-typeck.c:5921
+msgid "excess elements in struct initializer"
+msgstr "excés d'elements en valors inicials de struct"
+
+#: c-typeck.c:5936
+msgid "non-static initialization of a flexible array member"
+msgstr "iniciació no estàtica d'un membre de matriu flexible"
+
+#: c-typeck.c:6003
+msgid "excess elements in union initializer"
+msgstr "excés d'elements en valors inicials de union"
+
+#: c-typeck.c:6024
+msgid "traditional C rejects initialization of unions"
+msgstr "C tradicional rebutja els valors inicials de unions"
+
+#: c-typeck.c:6087
+msgid "excess elements in array initializer"
+msgstr "excés d'elements en valors inicials de matriu"
+
+#: c-typeck.c:6116
+msgid "excess elements in vector initializer"
+msgstr "excés d'elements en valor inicial vectorial"
+
+#: c-typeck.c:6138
+msgid "excess elements in scalar initializer"
+msgstr "excés d'elements en valor inicial escalar"
+
+#: c-typeck.c:6240
+msgid "asm template is not a string constant"
+msgstr "la plantilla asm no és una cadena constant"
+
+#: c-typeck.c:6272
+msgid "invalid lvalue in asm statement"
+msgstr "lvalue invàlid en declaració asm"
+
+#: c-typeck.c:6344 cp/typeck.c:5854
+msgid "modification by `asm'"
+msgstr "modificació per \"asm\""
+
+#: c-typeck.c:6362 cp/typeck.c:5938
+msgid "function declared `noreturn' has a `return' statement"
+msgstr "la funció declarada \"noreturn\" té una declaració \"return\""
+
+#: c-typeck.c:6369
+msgid "`return' with no value, in function returning non-void"
+msgstr "\"return\" sense valors, en una funció que retorna non-void"
+
+#: c-typeck.c:6375
+msgid "`return' with a value, in function returning void"
+msgstr "\"return\" amb valor, en una funció que retorna void"
+
+#: c-typeck.c:6379
+msgid "return"
+msgstr "return"
+
+#: c-typeck.c:6431
+msgid "function returns address of local variable"
+msgstr "la funció retorna l'adreça d'una variable local"
+
+#: c-typeck.c:6486 cp/semantics.c:749
+msgid "switch quantity not an integer"
+msgstr "la quantitat de switch no és un enter"
+
+#: c-typeck.c:6496
+msgid "`long' switch expression not converted to `int' in ISO C"
+msgstr "no es converteix l'expressió de switch \"long\" a \"int\" en ISO C"
+
+#: c-typeck.c:6537 cp/parser.c:5555
+msgid "case label not within a switch statement"
+msgstr "l'etiqueta casi no es troba dintre d'una declaració switch"
+
+#: c-typeck.c:6539
+msgid "`default' label not within a switch statement"
+msgstr "l'etiqueta \"default\" no està dintre d'una declaració switch"
+
+#: c-typeck.c:6691 c-typeck.c:6725
+msgid "division by zero"
+msgstr "divisió per zero"
+
+#: c-typeck.c:6770 cp/typeck.c:2930
+msgid "right shift count is negative"
+msgstr "el compte de desplaçament a la dreta es negatiu"
+
+#: c-typeck.c:6777 cp/typeck.c:2936
+msgid "right shift count >= width of type"
+msgstr "compte de desplaçament a la dreta >= amplària del tipus"
+
+#: c-typeck.c:6798 cp/typeck.c:2955
+msgid "left shift count is negative"
+msgstr "el compte de desplaçament a l'esquerra és negativa"
+
+#: c-typeck.c:6801 cp/typeck.c:2957
+msgid "left shift count >= width of type"
+msgstr "compte de desplaçament a l'esquerra >= amplària del tipus"
+
+#: c-typeck.c:6822
+msgid "shift count is negative"
+msgstr "compte de desplaçament a la dreta negatiu"
+
+#: c-typeck.c:6824
+msgid "shift count >= width of type"
+msgstr "ompte de desplaçament a la dreta >= amplària del tipus"
+
+#: c-typeck.c:6841 cp/typeck.c:2992
+msgid "comparing floating point with == or != is unsafe"
+msgstr "no és segura la comparança de coma flotant amb == o !="
+
+#: c-typeck.c:6865 c-typeck.c:6871
+msgid "ISO C forbids comparison of `void *' with function pointer"
+msgstr "ISO C prohibeix la comparança de \"void *\" amb un punter de funció"
+
+#: c-typeck.c:6874 c-typeck.c:6914 c-typeck.c:6942
+msgid "comparison of distinct pointer types lacks a cast"
+msgstr "la comparança de diferents tipus de punter manca d'una conversió"
+
+#: c-typeck.c:6888 c-typeck.c:6893 c-typeck.c:6962 c-typeck.c:6967
+msgid "comparison between pointer and integer"
+msgstr "comparança entre punter i enter"
+
+#: c-typeck.c:6909 c-typeck.c:6937
+msgid "ISO C forbids ordered comparisons of pointers to functions"
+msgstr "ISO C prohibeix la comparança entre punters a funcions"
+
+#: c-typeck.c:6934
+msgid "comparison of complete and incomplete pointers"
+msgstr "comparança de punters complets i incomplets"
+
+#: c-typeck.c:6950 c-typeck.c:6957
+msgid "ordered comparison of pointer with integer zero"
+msgstr "comparança ordenada de punter amb l'enter zero"
+
+#: c-typeck.c:6981 cp/typeck.c:3128
+msgid "unordered comparison on non-floating point argument"
+msgstr "comparança sense ordre en argument de coma no flotant"
+
+#: c-typeck.c:7191
+msgid "comparison between signed and unsigned"
+msgstr "comparança entre signed i unsigned"
+
+#: c-typeck.c:7237 cp/typeck.c:3375
+msgid "comparison of promoted ~unsigned with constant"
+msgstr "comparança d'un ~unsigned promogut amb una constant"
+
+#: c-typeck.c:7245 cp/typeck.c:3383
+msgid "comparison of promoted ~unsigned with unsigned"
+msgstr "comparança d'un ~unsigned promogut amb unsigned"
+
+#: calls.c:1838
+#, fuzzy
+msgid "%Jinlining failed in call to '%F'"
+msgstr "el \"inlining\" va fallar en la cridada a \"%s\""
+
+#: calls.c:1839 calls.c:2211 tree-inline.c:1339 tree-inline.c:1346
+msgid "called from here"
+msgstr "cridat des d'aquí"
+
+#: calls.c:2210
+#, fuzzy
+msgid "%Jcan't inline call to '%F'"
+msgstr "no es poden fer la cridada inline a \"%s\""
+
+#: calls.c:2219
+msgid "ignoring return value of `%D', declared with attribute warn_unused_result"
+msgstr ""
+
+#: calls.c:2232
+msgid "ignoring return value of function declared with attribute warn_unused_result"
+msgstr ""
+
+#: calls.c:2242
+msgid "function call has aggregate value"
+msgstr "la cridada a la funció té valor agregat"
+
+#: cfg.c:835
+#, c-format
+msgid "bb %d on wrong place"
+msgstr "bb %d en un lloc equivocat"
+
+#: cfg.c:841
+#, c-format
+msgid "prev_bb of %d should be %d, not %d"
+msgstr "el prev_bb de %d deu ser %d, no %d"
+
+#: cfg.c:857
+#, c-format
+msgid "verify_flow_info: Wrong count of block %i %i"
+msgstr "verify_flow_info: Compte erroni del bloc %i %i"
+
+#: cfg.c:863
+#, c-format
+msgid "verify_flow_info: Wrong frequency of block %i %i"
+msgstr "verify_flow_info: Freqüència errònia del bloc %i %i"
+
+#: cfg.c:871
+#, c-format
+msgid "verify_flow_info: Duplicate edge %i->%i"
+msgstr "verify_flow_info: Vora duplicada %i->%i"
+
+#: cfg.c:877
+#, c-format
+msgid "verify_flow_info: Wrong probability of edge %i->%i %i"
+msgstr "verify_flow_info: Probabilitat errònia de la vora %i->%i %i"
+
+#: cfg.c:883
+#, c-format
+msgid "verify_flow_info: Wrong count of edge %i->%i %i"
+msgstr "verify_flow_info: Compte erroni de la vora %i->%i %i"
+
+#: cfg.c:895
+#, c-format
+msgid "verify_flow_info: Basic block %d succ edge is corrupted"
+msgstr "verify_flow_info: El bloc bàsic %d succ edge està corrupte"
+
+#: cfg.c:909 cfgrtl.c:1971
+#, c-format
+msgid "Wrong amount of branch edges after unconditional jump %i"
+msgstr "Quantitat errònia de vores de ramificació després del salt incondicional %i"
+
+#: cfg.c:917
+#, c-format
+msgid "basic block %d pred edge is corrupted"
+msgstr "el bloc bàsic %d pred edge està corrupte"
+
+#: cfg.c:943
+#, c-format
+msgid "basic block %i edge lists are corrupted"
+msgstr "les llistes de vora del bloc bàsic %i estan corruptes"
+
+#: cfg.c:955
+msgid "verify_flow_info failed"
+msgstr "verify_flow_info fallat"
+
+#: cfgloop.c:1134
+#, c-format
+msgid "Size of loop %d should be %d, not %d."
+msgstr "La grandària del cicle %d deu ser %d, no %d."
+
+#: cfgloop.c:1153
+#, c-format
+msgid "Bb %d do not belong to loop %d."
+msgstr "Bb %d no pertany al cicle %d."
+
+#: cfgloop.c:1171
+#, c-format
+msgid "Loop %d's header does not have exactly 2 entries."
+msgstr "L'encapçalat del cicle %d no té exactament 2 entrades."
+
+#: cfgloop.c:1179
+#, c-format
+msgid "Loop %d's latch does not have exactly 1 successor."
+msgstr "El forrellat del cicle %d no té exactament 1 successor."
+
+#: cfgloop.c:1184
+#, c-format
+msgid "Loop %d's latch does not have header as successor."
+msgstr "El forrellat del cicle %d no té un encapçalat com successor."
+
+#: cfgloop.c:1189
+#, c-format
+msgid "Loop %d's latch does not belong directly to it."
+msgstr "El forrellat del cicle %d no pertany directament a ell."
+
+#: cfgloop.c:1195
+#, c-format
+msgid "Loop %d's header does not belong directly to it."
+msgstr "L'encapçalat del cicle %d no pertany directament a ell."
+
+#: cfgloop.c:1201
+#, fuzzy, c-format
+msgid "Loop %d's latch is marked as part of irreducible region."
+msgstr "El forrellat del cicle %d no pertany directament a ell."
+
+#: cfgloop.c:1231
+#, c-format
+msgid "Basic block %d should be marked irreducible."
+msgstr ""
+
+#: cfgloop.c:1237
+#, c-format
+msgid "Basic block %d should not be marked irreducible."
+msgstr ""
+
+#: cfgloop.c:1245
+#, c-format
+msgid "Edge from %d to %d should be marked irreducible."
+msgstr ""
+
+#: cfgloop.c:1252
+#, c-format
+msgid "Edge from %d to %d should not be marked irreducible."
+msgstr ""
+
+#: cfgrtl.c:1877
+#, c-format
+msgid "end insn %d for block %d not found in the insn stream"
+msgstr "el insn final %d per al bloc %d no es troba en el fluix insn"
+
+#: cfgrtl.c:1891
+#, c-format
+msgid "insn %d is in multiple basic blocks (%d and %d)"
+msgstr "insn %d està en múltiples blocs bàsics (%d i %d)"
+
+#: cfgrtl.c:1903
+#, c-format
+msgid "head insn %d for block %d not found in the insn stream"
+msgstr "el cap insn %d per al bloc %d no es troba en el fluix insn"
+
+#: cfgrtl.c:1925
+#, fuzzy
+msgid "verify_flow_info: REG_BR_PROB does not match cfg %wi %i"
+msgstr "verify_flow_info: REG_BR_PROB no coincideix amb la configuració %i %i"
+
+#: cfgrtl.c:1953
+#, c-format
+msgid "Missing REG_EH_REGION note in the end of bb %i"
+msgstr "Manca la nota REG_EH_REGION al final de bb %i"
+
+#: cfgrtl.c:1961
+#, c-format
+msgid "Too many outgoing branch edges from bb %i"
+msgstr "Massa vores de ramificació de sortida de bb %i"
+
+#: cfgrtl.c:1966
+#, c-format
+msgid "Fallthru edge after unconditional jump %i"
+msgstr "Vora de caiguda després del salt incondicional %i"
+
+#: cfgrtl.c:1977
+#, c-format
+msgid "Wrong amount of branch edges after conditional jump %i"
+msgstr "Quantitat errònia de vores de ramificació després del salt condicional %i"
+
+#: cfgrtl.c:1982
+#, c-format
+msgid "Call edges for non-call insn in bb %i"
+msgstr "Bords de cridada per a una insn que no és cridada en bb %i"
+
+#: cfgrtl.c:1991
+#, c-format
+msgid "Abnormal edges for no purpose in bb %i"
+msgstr "Vores anormals sense cap propòsit en bb %i"
+
+#: cfgrtl.c:2001
+#, c-format
+msgid "insn %d inside basic block %d but block_for_insn is NULL"
+msgstr "insn %d està dintre del bloc bàsic %d però block_for_insn és NULL"
+
+#: cfgrtl.c:2005
+#, c-format
+msgid "insn %d inside basic block %d but block_for_insn is %i"
+msgstr "insn %d està dintre del bloc bàsic %d però block_for_insn és %i"
+
+#: cfgrtl.c:2019 cfgrtl.c:2029
+#, c-format
+msgid "NOTE_INSN_BASIC_BLOCK is missing for block %d"
+msgstr "NOTE_INSN_BASIC_BLOCK mancada per al bloc %d"
+
+#: cfgrtl.c:2042
+#, c-format
+msgid "NOTE_INSN_BASIC_BLOCK %d in middle of basic block %d"
+msgstr "NOTE_INSN_BASIC_BLOCK %d en el mitjà del bloc bàsic %d"
+
+#: cfgrtl.c:2052
+#, c-format
+msgid "in basic block %d:"
+msgstr "en el bloc bàsic %d:"
+
+#: cfgrtl.c:2053
+msgid "flow control insn inside a basic block"
+msgstr "control de fluix insn dintre el bloc bàsic"
+
+#: cfgrtl.c:2099
+#, c-format
+msgid "missing barrier after block %i"
+msgstr "falta una barrera després del bloc %i"
+
+#: cfgrtl.c:2112
+#, c-format
+msgid "verify_flow_info: Incorrect blocks for fallthru %i->%i"
+msgstr "verify_flow_info: Blocs incorrectes per al respatller %i->%i"
+
+#: cfgrtl.c:2127
+#, c-format
+msgid "verify_flow_info: Incorrect fallthru %i->%i"
+msgstr "verify_flow_info: Respatller incorrecte %i->%i"
+
+#: cfgrtl.c:2129
+msgid "wrong insn in the fallthru edge"
+msgstr "insn erroni en la vora del respatller"
+
+#: cfgrtl.c:2146
+#, fuzzy
+msgid "basic blocks not laid down consecutively"
+msgstr "els blocs bàsics no estan numerats consecutivament"
+
+#: cfgrtl.c:2171
+msgid "insn outside basic block"
+msgstr "insn fora del bloc bàsic"
+
+#: cfgrtl.c:2179
+msgid "return not followed by barrier"
+msgstr "return no és seguit per una barrera"
+
+#: cfgrtl.c:2186
+#, c-format
+msgid "number of bb notes in insn chain (%d) != n_basic_blocks (%d)"
+msgstr "el nombre de notes bb en la cadena insn (%d) != n_basic_blocks (%d)"
+
+#: cgraph.c:161
+#, fuzzy
+msgid "function body not available"
+msgstr "la funció no pot ser inline"
+
+#: cgraph.c:163 cgraphunit.c:340
+#, fuzzy
+msgid "redefined extern inline functions are not considered for inlining"
+msgstr "Avisar quan una funció inline no pot ser inline"
+
+#: cgraph.c:166 cgraphunit.c:345
+#, fuzzy
+msgid "function not considered for inlining"
+msgstr "la funció no pot ser inline"
+
+#: cgraph.c:168 cgraphunit.c:343
+#, fuzzy
+msgid "function not inlinable"
+msgstr "la funció no pot ser inline"
+
+#: cgraph.c:476
+msgid "%D renamed after being referenced in assembly"
+msgstr ""
+
+#: cgraphunit.c:1041
+msgid "--param large-function-growth limit reached"
+msgstr ""
+
+#: cgraphunit.c:1054
+msgid "--param large-function-growth limit reached while inlining the caller"
+msgstr ""
+
+#: cgraphunit.c:1119
+msgid "--param max-inline-insns-single limit reached"
+msgstr ""
+
+#: cgraphunit.c:1143
+msgid "--param max-inline-insns-single limit reached after inlining into the callee"
+msgstr ""
+
+#: cgraphunit.c:1220
+msgid "--param inline-unit-growth limit reached"
+msgstr ""
+
+#: cgraphunit.c:1292 cgraphunit.c:1436
+msgid "recursive inlining"
+msgstr ""
+
+#: collect2.c:406
+msgid "internal error"
+msgstr "error intern"
+
+#: collect2.c:894
+msgid "no arguments"
+msgstr "sense arguments"
+
+#: collect2.c:1226 collect2.c:1374 collect2.c:1409
+#, c-format
+msgid "fopen %s"
+msgstr "fopen %s"
+
+#: collect2.c:1229 collect2.c:1379 collect2.c:1412
+#, c-format
+msgid "fclose %s"
+msgstr "fclose %s"
+
+#: collect2.c:1238
+#, c-format
+msgid "collect2 version %s"
+msgstr "collect2 versió %s"
+
+#: collect2.c:1328
+#, c-format
+msgid "%d constructor(s) found\n"
+msgstr "es troba(en) %d constructor(s)\n"
+
+#: collect2.c:1329
+#, c-format
+msgid "%d destructor(s) found\n"
+msgstr "es troba(en) %d destructor(s)\n"
+
+#: collect2.c:1330
+#, c-format
+msgid "%d frame table(s) found\n"
+msgstr "es troba(en) %d marcs de matriu(es)\n"
+
+#: collect2.c:1472
+#, c-format
+msgid "%s terminated with signal %d [%s]%s"
+msgstr "%s acabat amb el senyal %d [%s]%s"
+
+#: collect2.c:1490
+#, c-format
+msgid "%s returned %d exit status"
+msgstr "%s va retornar l'estat de sortida %d"
+
+#: collect2.c:1515
+#, c-format
+msgid "[cannot find %s]"
+msgstr "[no es pot trobar %s]"
+
+#: collect2.c:1530
+#, c-format
+msgid "cannot find `%s'"
+msgstr "no es pot trobar \"%s\""
+
+#: collect2.c:1541 collect2.c:1544
+#, c-format
+msgid "redirecting stdout: %s"
+msgstr "redirigint sortida estàndard: %s"
+
+#: collect2.c:1583
+#, c-format
+msgid "[Leaving %s]\n"
+msgstr "[Deixant %s]\n"
+
+#: collect2.c:1803
+#, c-format
+msgid ""
+"\n"
+"write_c_file - output name is %s, prefix is %s\n"
+msgstr ""
+"\n"
+"write_c_file - el nom de sortida és %s, el prefix és %s\n"
+
+#: collect2.c:2007
+msgid "cannot find `nm'"
+msgstr "no es pot trobar \"nm\""
+
+#: collect2.c:2017 collect2.c:2446
+msgid "pipe"
+msgstr "pipe"
+
+#: collect2.c:2021 collect2.c:2450
+msgid "fdopen"
+msgstr "fdopen"
+
+#: collect2.c:2047 collect2.c:2476
+#, c-format
+msgid "dup2 %d 1"
+msgstr "dup2 %d 1"
+
+#: collect2.c:2050 collect2.c:2053 collect2.c:2066 collect2.c:2479
+#: collect2.c:2482 collect2.c:2495
+#, c-format
+msgid "close %d"
+msgstr "close %d"
+
+#: collect2.c:2056 collect2.c:2485
+#, c-format
+msgid "execv %s"
+msgstr "execv %s"
+
+#: collect2.c:2110
+#, c-format
+msgid "init function found in object %s"
+msgstr "es va trobar la funció init en l'objecte %s"
+
+#: collect2.c:2118
+#, c-format
+msgid "fini function found in object %s"
+msgstr "es va trobar la funció fini en l'objecte %s"
+
+#: collect2.c:2141 collect2.c:2534
+msgid "fclose"
+msgstr "fclose"
+
+#: collect2.c:2183
+#, c-format
+msgid "unable to open file '%s'"
+msgstr "no es pot obrir el fitxer \"%s\""
+
+#: collect2.c:2185
+#, c-format
+msgid "unable to stat file '%s'"
+msgstr "no es pot avaluar el fitxer \"%s\""
+
+#: collect2.c:2191
+#, c-format
+msgid "unable to mmap file '%s'"
+msgstr "no es pot fer mmap al fitxer \"%s\""
+
+#: collect2.c:2337
+msgid "not found\n"
+msgstr "no trobat\n"
+
+#: collect2.c:2339 collect2.c:2513
+#, c-format
+msgid "dynamic dependency %s not found"
+msgstr "no es troba la dependència dinàmica %s"
+
+#: collect2.c:2358
+#, c-format
+msgid "bad magic number in file '%s'"
+msgstr "nombre màgic erroni en el fitxer \"%s\""
+
+#: collect2.c:2380
+msgid "dynamic dependencies.\n"
+msgstr "dependències dinàmiques.\n"
+
+#: collect2.c:2437
+msgid "cannot find `ldd'"
+msgstr "no es troba \"ldd\""
+
+#: collect2.c:2498
+msgid ""
+"\n"
+"ldd output with constructors/destructors.\n"
+msgstr ""
+"\n"
+"sortida de ldd amb constructors/destructors.\n"
+
+#: collect2.c:2525
+#, c-format
+msgid "unable to open dynamic dependency '%s'"
+msgstr "no es pot obrir la dependència dinàmica \"%s\""
+
+#: collect2.c:2685
+#, c-format
+msgid "%s: not a COFF file"
+msgstr "%s: no és un fitxer COFF"
+
+#: collect2.c:2805
+#, c-format
+msgid "%s: cannot open as COFF file"
+msgstr "%s: no es pot obrir com un fitxer COFF"
+
+#: collect2.c:2860
+#, c-format
+msgid "library lib%s not found"
+msgstr "no es troba la biblioteca lib%s"
+
+#: combine.c:13038
+#, c-format
+msgid ""
+";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n"
+";; %d successes.\n"
+"\n"
+msgstr ""
+";; Estadístiques del combinador: %d intents, %d substitucions (%d van requerir espai nou),\n"
+";; %d èxits.\n"
+"\n"
+
+#: combine.c:13047
+#, c-format
+msgid ""
+"\n"
+";; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n"
+";; %d successes.\n"
+msgstr ""
+"\n"
+";; Totals del combinador: %d intents, %d substitucions (%d van requerir espai nou),\n"
+";; %d èxits.\n"
+
+#: convert.c:70
+msgid "cannot convert to a pointer type"
+msgstr "no es pot convertir a un tipus punter"
+
+#: convert.c:267
+msgid "pointer value used where a floating point value was expected"
+msgstr "es va usar un valor de punter on s'esperava un valor de coma flotant"
+
+#: convert.c:271
+msgid "aggregate value used where a float was expected"
+msgstr "es va usar un valor agregat on s'esperava un float"
+
+#: convert.c:296
+msgid "conversion to incomplete type"
+msgstr "conversió a tipus de dada incompleta"
+
+#: convert.c:600 convert.c:678
+msgid "can't convert between vector values of different size"
+msgstr "no es pot convertir entre valors vectorials de grandàries diferents"
+
+#: convert.c:606
+msgid "aggregate value used where an integer was expected"
+msgstr "es va usar un valor agregat on s'esperava un enter"
+
+#: convert.c:657 f/com.c:1101
+msgid "pointer value used where a complex was expected"
+msgstr "es va usar un valor de punter on s'esperava un complex"
+
+#: convert.c:661 f/com.c:1103
+msgid "aggregate value used where a complex was expected"
+msgstr "es va usar un valor agregat on s'esperava un complex"
+
+#: convert.c:684
+msgid "can't convert value to a vector"
+msgstr "no es pot convertir el valor a un vector"
+
+#: coverage.c:164
+#, fuzzy, c-format
+msgid "`%s' is not a gcov data file"
+msgstr "\"%s\" no és un nom de fitxer vàlid"
+
+#: coverage.c:175
+#, fuzzy, c-format
+msgid "`%s' is version `%.4s', expected version `%.4s'"
+msgstr "controlador gcc versió %s executant gcc versió %s\n"
+
+#: coverage.c:255 coverage.c:263
+#, c-format
+msgid "coverage mismatch for function %u while reading execution counters."
+msgstr ""
+
+#: coverage.c:257 coverage.c:340
+#, c-format
+msgid "checksum is %x instead of %x"
+msgstr ""
+
+#: coverage.c:265 coverage.c:348
+#, c-format
+msgid "number of counters is %d instead of %d"
+msgstr ""
+
+#: coverage.c:271
+#, fuzzy, c-format
+msgid "cannot merge separate %s counters for function %u"
+msgstr "no es pot usar va_start en una funció d'interrupció"
+
+#: coverage.c:296
+#, fuzzy, c-format
+msgid "`%s' has overflowed"
+msgstr "desbordament de la pila del analitzador"
+
+#: coverage.c:296
+#, fuzzy, c-format
+msgid "`%s' is corrupted"
+msgstr "\"%s\" és depreciat"
+
+#: coverage.c:319
+#, c-format
+msgid "file %s not found, execution counts assumed to be zero"
+msgstr "no es troba el fitxer %s, s'assumeix que el compte d'execució és zero."
+
+#: coverage.c:329
+#, fuzzy, c-format
+msgid "no coverage for function '%s' found."
+msgstr "classe d'emmagatzematge invàlida per a la funció \"%s\""
+
+#: coverage.c:337 coverage.c:345
+#, c-format
+msgid "coverage mismatch for function '%s' while reading counter '%s'."
+msgstr ""
+
+#: coverage.c:493
+#, fuzzy, c-format
+msgid "cannot open %s"
+msgstr "no és pot obrir %s"
+
+#: coverage.c:528
+#, fuzzy, c-format
+msgid "error writing `%s'"
+msgstr "error a l'escriure a %s"
+
+#. XXX should be DL_SORRY
+#: cppcharset.c:653
+#, fuzzy, c-format
+msgid "conversion from %s to %s not supported by iconv"
+msgstr "la conversió de \"%T\" a \"%T\" és ambigua"
+
+#: cppcharset.c:656
+msgid "iconv_open"
+msgstr ""
+
+#. XXX should be DL_SORRY
+#: cppcharset.c:664
+#, c-format
+msgid "no iconv implementation, cannot convert from %s to %s"
+msgstr ""
+
+#: cppcharset.c:808
+#, fuzzy
+msgid "universal character names are only valid in C++ and C99"
+msgstr "universal-character-name \"\\U%08x\" no és vàlid en l'identificador"
+
+#: cppcharset.c:811
+#, c-format
+msgid "the meaning of '\\%c' is different in traditional C"
+msgstr "el significat de \"\\%c\" és diferent en C tradicional"
+
+#: cppcharset.c:837
+#, fuzzy, c-format
+msgid "incomplete universal character name %.*s"
+msgstr "universal-character-name incomplet"
+
+#: cppcharset.c:849
+#, fuzzy, c-format
+msgid "%.*s is not a valid universal character"
+msgstr "\"%T::%D\" no és una declaració vàlida"
+
+#: cppcharset.c:859
+#, fuzzy, c-format
+msgid "universal character %.*s is not valid in an identifier"
+msgstr "universal-character-name \"\\U%08x\" no és vàlid en l'identificador"
+
+#: cppcharset.c:863
+#, fuzzy, c-format
+msgid "universal character %.*s is not valid at the start of an identifier"
+msgstr "universal-character-name \"\\U%08x\" no és vàlid en l'identificador"
+
+#: cppcharset.c:898
+#, fuzzy
+msgid "converting UCN to source character set"
+msgstr "convertint NULL a un tipus que no és apuntador"
+
+#: cppcharset.c:902
+#, fuzzy
+msgid "converting UCN to execution character set"
+msgstr "convertint NULL a un tipus que no és apuntador"
+
+#: cppcharset.c:967
+msgid "the meaning of '\\x' is different in traditional C"
+msgstr "el significat de \"\\x\" és diferent en C tradicional"
+
+#: cppcharset.c:984 f/lex.c:580
+msgid "\\x used with no following hex digits"
+msgstr "es va usar \\x sense dígits hexadecimales a continuació"
+
+#: cppcharset.c:991
+msgid "hex escape sequence out of range"
+msgstr "seqüència d'escapi hexadecimal fora de rang"
+
+#: cppcharset.c:1030
+msgid "octal escape sequence out of range"
+msgstr "seqüència d'escapi octal fora de rang"
+
+#: cppcharset.c:1098
+msgid "the meaning of '\\a' is different in traditional C"
+msgstr "el significat de \"\\a\" és diferent en C tradicional"
+
+#: cppcharset.c:1105
+#, c-format
+msgid "non-ISO-standard escape sequence, '\\%c'"
+msgstr "seqüència d'escapi que no és estàndard ISO, \"\\%c\""
+
+#: cppcharset.c:1113
+#, c-format
+msgid "unknown escape sequence '\\%c'"
+msgstr "seqüència d'escapi \"\\%c\" desconeguda"
+
+#: cppcharset.c:1116
+#, c-format
+msgid "unknown escape sequence: '\\%03o'"
+msgstr "seqüència d'escapi desconeguda: '\\%03o'"
+
+#: cppcharset.c:1122
+#, fuzzy
+msgid "converting escape sequence to execution character set"
+msgstr "seqüència d'escapi octal fora de rang"
+
+#: cppcharset.c:1181
+msgid "converting to execution character set"
+msgstr ""
+
+#: cppcharset.c:1244 cppcharset.c:1307
+msgid "character constant too long for its type"
+msgstr "constant de caràcter massa gran pel seu tipus"
+
+#: cppcharset.c:1247
+msgid "multi-character character constant"
+msgstr "constant de caràcter amb múltiples caràcters"
+
+#: cppcharset.c:1339
+msgid "empty character constant"
+msgstr "constant de caràter buida"
+
+#: cppcharset.c:1378
+#, fuzzy, c-format
+msgid "failure to convert %s to %s"
+msgstr "no es pot convertir \"%E\" a \"%T\""
+
+#: cpperror.c:110 diagnostic.def:5
+msgid "warning: "
+msgstr "avís: "
+
+#: cpperror.c:112
+msgid "internal error: "
+msgstr "error intern: "
+
+#: cpperror.c:174
+msgid "stdout"
+msgstr "stdout"
+
+#: cppexp.c:192
+msgid "too many decimal points in number"
+msgstr "massa punts decimals en el nombre"
+
+#: cppexp.c:212
+#, c-format
+msgid "invalid digit \"%c\" in octal constant"
+msgstr "dígit \"%c\" invàlid en la constant octal"
+
+#: cppexp.c:218
+msgid "use of C99 hexadecimal floating constant"
+msgstr "ús d'una constant de coma flotant hexadecimal C99"
+
+#: cppexp.c:227
+msgid "exponent has no digits"
+msgstr "exponent no té dígits"
+
+#: cppexp.c:234
+msgid "hexadecimal floating constants require an exponent"
+msgstr "la constant de coma flotant hexadecimal requereixe un exponent"
+
+#: cppexp.c:240
+#, c-format
+msgid "invalid suffix \"%.*s\" on floating constant"
+msgstr "sufix \"%.*s\" invàlid en la constant de coma flotant"
+
+#: cppexp.c:250 cppexp.c:275
+#, c-format
+msgid "traditional C rejects the \"%.*s\" suffix"
+msgstr "C tradicional rebutja el sufix \"%.*s\""
+
+#: cppexp.c:261
+#, c-format
+msgid "invalid suffix \"%.*s\" on integer constant"
+msgstr "sufix \"%.*s\" invàlid en constant entera"
+
+#: cppexp.c:283
+msgid "use of C99 long long integer constant"
+msgstr "ús d'una constant entera long long C99"
+
+#: cppexp.c:290
+msgid "imaginary constants are a GCC extension"
+msgstr "les constants imaginàries són una extensió GCC"
+
+#: cppexp.c:376
+msgid "integer constant is too large for its type"
+msgstr "la constant entera és massa gran per al seu tipus"
+
+#: cppexp.c:388
+msgid "integer constant is so large that it is unsigned"
+msgstr "la constant entera és tan gran que és unsigned"
+
+#: cppexp.c:470
+msgid "missing ')' after \"defined\""
+msgstr "falta \")\" després de \"defined\""
+
+#: cppexp.c:477
+msgid "operator \"defined\" requires an identifier"
+msgstr "l'operador \"defined\" requereix un identificador"
+
+#: cppexp.c:485
+#, c-format
+msgid "(\"%s\" is an alternative token for \"%s\" in C++)"
+msgstr "(\"%s\" és un element alternatiu per a \"%s\" en C++)"
+
+#: cppexp.c:495
+msgid "this use of \"defined\" may not be portable"
+msgstr "aquest ùs de \"defined\" podria ser no portable"
+
+#: cppexp.c:531
+msgid "floating constant in preprocessor expression"
+msgstr "constant de coma flotant en l'expressió del preprocessador"
+
+#: cppexp.c:537
+msgid "imaginary number in preprocessor expression"
+msgstr "nombre imaginari en l'expressió del preprocessador"
+
+#: cppexp.c:582
+#, c-format
+msgid "\"%s\" is not defined"
+msgstr "\"%s\" no és definit"
+
+#: cppexp.c:714 cppexp.c:743
+#, c-format
+msgid "missing binary operator before token \"%s\""
+msgstr "operador binari faltant abans de l'element \"%s\""
+
+#: cppexp.c:734
+#, c-format
+msgid "token \"%s\" is not valid in preprocessor expressions"
+msgstr "l'element \"%s\" no és vàlid en les expressions del preprocesador"
+
+#: cppexp.c:753
+msgid "void expression between '(' and ')'"
+msgstr "expressión void entre \"(\" i \")\""
+
+#: cppexp.c:756
+msgid "#if with no expression"
+msgstr "#if sense expressió"
+
+#: cppexp.c:758
+#, c-format
+msgid "operator '%s' has no right operand"
+msgstr "l'operador \"%s\" no té operant de dreta"
+
+#: cppexp.c:784
+msgid " ':' without preceding '?'"
+msgstr " \":\" sense \"?\" precedent"
+
+#: cppexp.c:811
+msgid "unbalanced stack in #if"
+msgstr "pila desequilibrada en #if"
+
+#: cppexp.c:830
+#, c-format
+msgid "impossible operator '%u'"
+msgstr "operador \"%u\" impossible"
+
+#: cppexp.c:922
+msgid "missing ')' in expression"
+msgstr "\")\" faltant en l'expressió"
+
+#: cppexp.c:943
+msgid "'?' without following ':'"
+msgstr " \"?\" sense \":\" següent"
+
+#: cppexp.c:953
+msgid "integer overflow in preprocessor expression"
+msgstr "desbordament d'enter en l'expressió del preprocessador"
+
+#: cppexp.c:958
+msgid "missing '(' in expression"
+msgstr "\"(\" faltant en l'expressió"
+
+#: cppexp.c:990
+#, c-format
+msgid "the left operand of \"%s\" changes sign when promoted"
+msgstr "l'operant esquerre de \"%s\" canvia el signe quan és promogut"
+
+#: cppexp.c:995
+#, c-format
+msgid "the right operand of \"%s\" changes sign when promoted"
+msgstr "l'operant dret de \"%s\" canvia el signe quan és promogut"
+
+#: cppexp.c:1353
+msgid "comma operator in operand of #if"
+msgstr "operador coma en operant de #if"
+
+#: cppexp.c:1484
+msgid "division by zero in #if"
+msgstr "divisió per zero en #if"
+
+#: cppfiles.c:370
+msgid "NULL directory in find_file"
+msgstr ""
+
+#: cppfiles.c:397
+msgid "one or more PCH files were found, but they were invalid"
+msgstr ""
+
+#: cppfiles.c:400
+msgid "use -Winvalid-pch for more information"
+msgstr ""
+
+#: cppfiles.c:458
+#, c-format
+msgid "%s is a block device"
+msgstr "%s és un dispositiu de blocs"
+
+#: cppfiles.c:475
+#, c-format
+msgid "%s is too large"
+msgstr "%s és massa gran"
+
+#: cppfiles.c:510
+#, c-format
+msgid "%s is shorter than expected"
+msgstr "%s és més curt de l'esperat"
+
+#: cppfiles.c:696
+#, fuzzy, c-format
+msgid "no include path in which to search for %s"
+msgstr "no hi ha ruta d'inclusió en la qual es trobi %s"
+
+#: cppfiles.c:956
+msgid "Multiple include guards may be useful for:\n"
+msgstr "Guàrdies múltiples de include poden ser útils per a:\n"
+
+#: cppinit.c:387
+msgid "cppchar_t must be an unsigned type"
+msgstr "cppchar_t deu ser d'un tipus unsigned"
+
+#: cppinit.c:391
+#, c-format
+msgid "preprocessor arithmetic has maximum precision of %lu bits; target requires %lu bits"
+msgstr "l'aritmètica del preprocesador té una precisió màxima de %lu bits; l'objectiu requereix %lu bits"
+
+#: cppinit.c:398
+msgid "CPP arithmetic must be at least as precise as a target int"
+msgstr "l'aritmètica de CPP deu ser almenys tan precisa com un int de l'objectiu"
+
+#: cppinit.c:401
+msgid "target char is less than 8 bits wide"
+msgstr "el char de l'objectiu té menys de 8 bits d'ample"
+
+#: cppinit.c:405
+msgid "target wchar_t is narrower than target char"
+msgstr "el wchar_t de l'objectiu és més estret que el char de l'objectiu"
+
+#: cppinit.c:409
+msgid "target int is narrower than target char"
+msgstr "el int de l'objectiu és més estret que el char de l'objectiu"
+
+#: cppinit.c:414
+msgid "CPP half-integer narrower than CPP character"
+msgstr "el mitj-enter de CPP és més estret que el caràcter de CPP"
+
+#: cppinit.c:418
+#, c-format
+msgid "CPP on this host cannot handle wide character constants over %lu bits, but the target requires %lu bits"
+msgstr "CPP no pot manejar constants de caràcter amples més enllà de %lu bits en aquestobjectiu, però l'objectiu requereix %lu bits"
+
+#: cpplex.c:410
+msgid "null character(s) ignored"
+msgstr "caràter(es) nul(s) ignorats"
+
+#: cpplex.c:445
+#, fuzzy
+msgid "'$' in identifier or number"
+msgstr "caràcter/(es) \"$\" en l'identificador o nombre"
+
+#: cpplex.c:492
+#, c-format
+msgid "attempt to use poisoned \"%s\""
+msgstr "intent d'usar \"%s\" enverinat"
+
+#: cpplex.c:500
+msgid "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro"
+msgstr "__VA_ARGS__ solament pot aparèixer en l'expansió d'una macro variadic C99"
+
+#: cpplex.c:596
+msgid "null character(s) preserved in literal"
+msgstr "caràcter(es) nul(s) preservats en la literal"
+
+#: cpplex.c:919
+msgid "unterminated comment"
+msgstr "comentari sense acabar"
+
+#: cpplex.c:930
+msgid "C++ style comments are not allowed in ISO C90"
+msgstr "els comentaris d'estil C++ no són permesos en ISO C90"
+
+#: cpplex.c:932
+msgid "(this will be reported only once per input file)"
+msgstr "(això es reportarà solament una vegada per cada fitxer d'entrada)"
+
+#: cpplex.c:937
+msgid "multi-line comment"
+msgstr "comentari en múltiples línies"
+
+#: cpplex.c:1201
+#, c-format
+msgid "unspellable token %s"
+msgstr "Element %s impronunciable"
+
+#: cpplib.c:218
+#, c-format
+msgid "extra tokens at end of #%s directive"
+msgstr "elements extra al final de la directiva #%s"
+
+#: cpplib.c:304
+#, c-format
+msgid "#%s is a GCC extension"
+msgstr "#%s és una extenció del GCC"
+
+#: cpplib.c:316
+msgid "suggest not using #elif in traditional C"
+msgstr "es suggereix no usar #elif en C tradicional"
+
+#: cpplib.c:319
+#, c-format
+msgid "traditional C ignores #%s with the # indented"
+msgstr "C tradicional ignora #%s amb el # indentat"
+
+#: cpplib.c:323
+#, c-format
+msgid "suggest hiding #%s from traditional C with an indented #"
+msgstr "es suggereix ocultar #%s del C tradicional amb el # indentat"
+
+#: cpplib.c:345
+msgid "embedding a directive within macro arguments is not portable"
+msgstr ""
+
+#: cpplib.c:365
+msgid "style of line directive is a GCC extension"
+msgstr "l'estil de la directiva de línia és una extenció del GCC"
+
+#: cpplib.c:415
+#, c-format
+msgid "invalid preprocessing directive #%s"
+msgstr "directiva de preprocessament #%s invàlida"
+
+#: cpplib.c:484
+msgid "\"defined\" cannot be used as a macro name"
+msgstr "\"defined\" no es pot usar com un nom de macro"
+
+#: cpplib.c:490
+#, c-format
+msgid "\"%s\" cannot be used as a macro name as it is an operator in C++"
+msgstr "no es pot usar \"%s\" com un nom de macro perquè és un operador en C++"
+
+#: cpplib.c:493
+#, c-format
+msgid "no macro name given in #%s directive"
+msgstr "no es va donar un nom de macro en la directiva #%s"
+
+#: cpplib.c:496
+msgid "macro names must be identifiers"
+msgstr "els noms de macro deuen ser identificadors"
+
+#: cpplib.c:537
+#, c-format
+msgid "undefining \"%s\""
+msgstr "esborrant la definició de \"%s\""
+
+#: cpplib.c:609
+msgid "missing terminating > character"
+msgstr "falta el caràcter de terminació >"
+
+#: cpplib.c:662
+#, c-format
+msgid "#%s expects \"FILENAME\" or <FILENAME>"
+msgstr "#%s espera \"NOM_DE_FITXER\" o <NOM_DE_FITXER>"
+
+#: cpplib.c:685
+msgid "#include nested too deeply"
+msgstr "#include niat amb massa profunditat"
+
+#: cpplib.c:723
+msgid "#include_next in primary source file"
+msgstr "#include_next en el fitxer font primari"
+
+#: cpplib.c:749
+#, c-format
+msgid "invalid flag \"%s\" in line directive"
+msgstr "indicador \"%s\" invàlid en la línia de la directiva"
+
+#: cpplib.c:794
+#, c-format
+msgid "\"%s\" after #line is not a positive integer"
+msgstr "\"%s\" desprès de #line no és un enter positiu"
+
+#: cpplib.c:800
+msgid "line number out of range"
+msgstr "nombre de línia fora de rang"
+
+#: cpplib.c:812 cpplib.c:885
+#, c-format
+msgid "\"%s\" is not a valid filename"
+msgstr "\"%s\" no és un nom de fitxer vàlid"
+
+#: cpplib.c:847
+#, c-format
+msgid "\"%s\" after # is not a positive integer"
+msgstr "\"%s\" desprès de # no és un enter positiu"
+
+#: cpplib.c:947
+msgid "invalid #ident directive"
+msgstr "directiva #ident invàlida"
+
+#: cpplib.c:1027
+#, c-format
+msgid "registering \"%s\" as both a pragma and a pragma namespace"
+msgstr "desant \"%s\" com a pragma i espai de noms de pragma"
+
+#: cpplib.c:1030
+#, c-format
+msgid "#pragma %s %s is already registered"
+msgstr "ja s'ha desat #pragma %s %s"
+
+#: cpplib.c:1033
+#, c-format
+msgid "#pragma %s is already registered"
+msgstr "ja s'ha desat #pragma %s"
+
+#: cpplib.c:1175
+msgid "#pragma once in main file"
+msgstr "#pragma una vegada en el fitxer principal"
+
+#: cpplib.c:1198
+msgid "invalid #pragma GCC poison directive"
+msgstr "directiva #pragma de GCC enverinada invàlida"
+
+#: cpplib.c:1207
+#, c-format
+msgid "poisoning existing macro \"%s\""
+msgstr "enverinant la macro existent \"%s\""
+
+#: cpplib.c:1228
+msgid "#pragma system_header ignored outside include file"
+msgstr "#pragma system_header ignorat fora del fitxer d'inclusió"
+
+#: cpplib.c:1252
+#, fuzzy, c-format
+msgid "cannot find source file %s"
+msgstr "no es pot trobar la font %s"
+
+#: cpplib.c:1256
+#, c-format
+msgid "current file is older than %s"
+msgstr "el fitxer actual és més vell que %s"
+
+#: cpplib.c:1370
+msgid "_Pragma takes a parenthesized string literal"
+msgstr "_Pragma duu una cadena literal entre parèntesis"
+
+#: cpplib.c:1448
+msgid "#else without #if"
+msgstr "#else sense #if"
+
+#: cpplib.c:1453
+msgid "#else after #else"
+msgstr "#else després de #else"
+
+#: cpplib.c:1481
+msgid "#elif without #if"
+msgstr "#elif sense #if"
+
+#: cpplib.c:1486
+msgid "#elif after #else"
+msgstr "#elif després de #else"
+
+#: cpplib.c:1516
+msgid "#endif without #if"
+msgstr "#endif sense #if"
+
+#: cpplib.c:1593
+msgid "missing '(' after predicate"
+msgstr "falta \"(\" abans del predicat"
+
+#: cpplib.c:1608
+msgid "missing ')' to complete answer"
+msgstr "falta \")\" per a completar la resposta"
+
+#: cpplib.c:1628
+msgid "predicate's answer is empty"
+msgstr "el predicat de la resposta està buidor"
+
+#: cpplib.c:1655
+msgid "assertion without predicate"
+msgstr "afirmació sense predicat"
+
+#: cpplib.c:1657
+msgid "predicate must be an identifier"
+msgstr "el predicat deu ser un identificador"
+
+#: cpplib.c:1741
+#, c-format
+msgid "\"%s\" re-asserted"
+msgstr "\"%s\" reafirmat"
+
+#: cppmacro.c:125 cppmacro.c:280
+#, c-format
+msgid "invalid built-in macro \"%s\""
+msgstr "macro interna \"%s\" invàlida"
+
+#: cppmacro.c:221
+msgid "could not determine date and time"
+msgstr "no es pot determinar la data i l'hora"
+
+#: cppmacro.c:393
+msgid "invalid string literal, ignoring final '\\'"
+msgstr "cadena literal invàlida, s'ignora el \"\\\" finals"
+
+#: cppmacro.c:476
+#, c-format
+msgid "pasting \"%s\" and \"%s\" does not give a valid preprocessing token"
+msgstr "pegar \"%s\" i \"%s\" no dóna un element vàlid de preprocessament"
+
+#: cppmacro.c:514
+msgid "ISO C99 requires rest arguments to be used"
+msgstr "ISO C99 requereix que la resta dels arguments sigui usat"
+
+#: cppmacro.c:519
+#, c-format
+msgid "macro \"%s\" requires %u arguments, but only %u given"
+msgstr "la macro \"%s\" requereix %u arguments, però sol es proporcionen %u"
+
+#: cppmacro.c:524
+#, c-format
+msgid "macro \"%s\" passed %u arguments, but takes just %u"
+msgstr "la macro \"%s\" va rebre %u arguments, però solament va prendre %u"
+
+#: cppmacro.c:635
+#, c-format
+msgid "unterminated argument list invoking macro \"%s\""
+msgstr "llista d'arguments sense acabar a l'invocar la macro \"%s\""
+
+#: cppmacro.c:738
+#, c-format
+msgid "function-like macro \"%s\" must be used with arguments in traditional C"
+msgstr "la funció de macro \"%s\" es deu usar amb arguments en C tradicional"
+
+#: cppmacro.c:1245
+#, c-format
+msgid "duplicate macro parameter \"%s\""
+msgstr "paràmetre de macro \"%s\" duplicat"
+
+#: cppmacro.c:1290
+#, c-format
+msgid "\"%s\" may not appear in macro parameter list"
+msgstr "\"%s\" podria faltar en la llista de paràmetre de macro"
+
+#: cppmacro.c:1298
+msgid "macro parameters must be comma-separated"
+msgstr "els paràmetres de macro deuen ser separats per comes"
+
+#: cppmacro.c:1315
+msgid "parameter name missing"
+msgstr "falta el nom del paràmetre"
+
+#: cppmacro.c:1330
+msgid "anonymous variadic macros were introduced in C99"
+msgstr "els macros variadic anònims es van introduir en C99"
+
+#: cppmacro.c:1334
+msgid "ISO C does not permit named variadic macros"
+msgstr "ISO C no permet macros variadic nomenats"
+
+#: cppmacro.c:1343
+msgid "missing ')' in macro parameter list"
+msgstr "falta parèntesi dret en la llista de paràmetres de macro"
+
+#: cppmacro.c:1406
+msgid "ISO C requires whitespace after the macro name"
+msgstr "ISO C requereix espais en blanc després del nom de macro"
+
+#: cppmacro.c:1434
+msgid "'#' is not followed by a macro parameter"
+msgstr "\"#\" no és seguit per un paràmetre de macro"
+
+#: cppmacro.c:1453
+msgid "'##' cannot appear at either end of a macro expansion"
+msgstr "\"##\" no pot apareixer en o al final d'una expansió de macro"
+
+#: cppmacro.c:1592
+#, c-format
+msgid "macro argument \"%s\" would be stringified in traditional C"
+msgstr "l'argument de macro \"%s\" deuria ser convertit a cadena en C traditional"
+
+#: cppmacro.c:1615
+#, c-format
+msgid "invalid hash type %d in cpp_macro_definition"
+msgstr "tipus de hash %d invàlid en cpp_macro_definition"
+
+#: cpppch.c:84 cpppch.c:332 cpppch.c:356 cpppch.c:365
+msgid "while writing precompiled header"
+msgstr ""
+
+#: cpppch.c:463
+#, fuzzy, c-format
+msgid "%s: not used because `%.*s' not defined"
+msgstr "s'usa l'etiqueta \"%s\" però no està definida"
+
+#: cpppch.c:475
+#, c-format
+msgid "%s: not used because `%.*s' defined as `%s' not `%.*s'"
+msgstr ""
+
+#: cpppch.c:516
+#, fuzzy, c-format
+msgid "%s: not used because `%s' is defined"
+msgstr "\"%s\" utilitzat però mai definit"
+
+#: cpppch.c:529 cpppch.c:715
+msgid "while reading precompiled header"
+msgstr ""
+
+#: cppspec.c:106
+#, c-format
+msgid "\"%s\" is not a valid option to the preprocessor"
+msgstr "\"%s\" no es una opció vàlida per el preprocessador"
+
+#: cppspec.c:128
+msgid "too many input files"
+msgstr "massa fitxers d'entrada"
+
+#: cpptrad.c:744
+#, c-format
+msgid "detected recursion whilst expanding macro \"%s\""
+msgstr ""
+
+#: cpptrad.c:911
+#, fuzzy
+msgid "syntax error in macro parameter list"
+msgstr "\"%s\" podria faltar en la llista de paràmetre de macro"
+
+#: cse.c:7060
+#, c-format
+msgid ";; Processing block from %d to %d, %d sets.\n"
+msgstr ";; Processant el bloc de %d a %d, %d establerts.\n"
+
+#: diagnostic.c:209
+#, c-format
+msgid "%s:%d: confused by earlier errors, bailing out\n"
+msgstr "%s:%d: confusió per errors precedentes, abandó\n"
+
+#: diagnostic.c:281
+msgid "compilation terminated.\n"
+msgstr "compilació acabada.\n"
+
+#: diagnostic.c:572
+msgid "Internal compiler error: Error reporting routines re-entered.\n"
+msgstr "Error intern del compilador: Error al reportar rutines reentrades.\n"
+
+#: diagnostic.c:584
+#, c-format
+msgid "in %s, at %s:%d"
+msgstr "en %s, en %s:%d"
+
+#: dominance.c:763
+#, c-format
+msgid "dominator of %d should be %d, not %d"
+msgstr ""
+
+#: dwarf2out.c:3229
+#, c-format
+msgid "DW_LOC_OP %s not implemented\n"
+msgstr "DW_LOC_OP %s no està implementat\n"
+
+#: emit-rtl.c:1155
+msgid "can't access real part of complex value in hard register"
+msgstr "No es pot accedir a la part real d'un valor complex en un registre fix"
+
+#: emit-rtl.c:1182
+msgid "can't access imaginary part of complex value in hard register"
+msgstr "No es pot accedir a la part imaginària d'un valor complex en un registre fix"
+
+#: emit-rtl.c:2327
+#, fuzzy
+msgid "Invalid rtl sharing found in the insn"
+msgstr "operant invàlid en la instrucció"
+
+#: emit-rtl.c:2329
+msgid "Shared rtx"
+msgstr ""
+
+#: emit-rtl.c:3464
+msgid "ICE: emit_insn used where emit_jump_insn needed:\n"
+msgstr "ICE:s'usa emit_insn on es necessita emit_jump_insn:\n"
+
+#: errors.c:129
+#, c-format
+msgid "abort in %s, at %s:%d"
+msgstr "abandó en %s, en %s:%d"
+
+#: except.c:357
+msgid "exception handling disabled, use -fexceptions to enable"
+msgstr "maneig d'excepcions desactivat, usi -fexceptions per a activar"
+
+#: except.c:2953
+msgid "argument of `__builtin_eh_return_regno' must be constant"
+msgstr "l'argument de \"__builtin_eh_return_regno\" deu ser constant"
+
+#: except.c:3084
+msgid "__builtin_eh_return not supported on this target"
+msgstr "no es dóna suport a _builtin_eh_return en aquest objectiu"
+
+#: explow.c:1319
+msgid "stack limits not supported on this target"
+msgstr "no es dóna suport a límits de la pila en aquest objectiu"
+
+#: expr.c:2998
+msgid "function using short complex types cannot be inline"
+msgstr "les funcions que usen tipus short complex no poden ser inline"
+
+#: expr.c:6385
+#, fuzzy
+msgid "%Jprior parameter's size depends on '%D'"
+msgstr "la grandària del paràmetre previ depèn de \"%s\""
+
+#: expr.c:6752
+msgid "returned value in block_exit_expr"
+msgstr "es va regressar un valor en block_exit_expr"
+
+#. We can't make a bitwise copy of this object, so fail.
+#: expr.c:8895
+msgid "cannot take the address of an unaligned member"
+msgstr "no es pot prendre l'adreça d'un membre desalineat"
+
+#: final.c:1058
+msgid "negative insn length"
+msgstr "longitud insn negativa"
+
+#: final.c:2429
+msgid "could not split insn"
+msgstr "no es pot separar insn"
+
+#: final.c:2771
+msgid "invalid `asm': "
+msgstr "\"asm\" invàlid: "
+
+#: final.c:2954
+msgid "nested assembly dialect alternatives"
+msgstr "reunió de dialectes alternatius imbricats"
+
+#: final.c:2971 final.c:2983
+msgid "unterminated assembly dialect alternative"
+msgstr "reunió de dialectes alternatius no terminada"
+
+#: final.c:3027
+#, c-format
+msgid "operand number missing after %%-letter"
+msgstr "falta nombre operant després de %%-letter"
+
+#: final.c:3030 final.c:3069
+msgid "operand number out of range"
+msgstr "nombre operant fora de rang"
+
+#: final.c:3088
+#, c-format
+msgid "invalid %%-code"
+msgstr "%%-codi invàlid"
+
+#: final.c:3118
+#, c-format
+msgid "`%%l' operand isn't a label"
+msgstr "l'operant \"%%l\" no és una etiqueta"
+
+#. We can't handle floating point constants;
+#. PRINT_OPERAND must handle them.
+#: final.c:3220 vmsdbgout.c:467 config/i386/i386.c:6751
+#: config/pdp11/pdp11.c:1646
+msgid "floating constant misused"
+msgstr "constant de coma flotant mal usada"
+
+#: final.c:3276 vmsdbgout.c:524 config/i386/i386.c:6829
+#: config/pdp11/pdp11.c:1693
+msgid "invalid expression as operand"
+msgstr "expressió invàlida com operant"
+
+#: flow.c:329
+msgid "function might be possible candidate for attribute `noreturn'"
+msgstr "la funció pot ser un candidat possible per a l'atribut \"noreturn\""
+
+#: flow.c:334
+msgid "`noreturn' function does return"
+msgstr "la funció \"noreturn\" retorna"
+
+#: flow.c:355
+msgid "control reaches end of non-void function"
+msgstr "el control arriba a el final d'una funció que no és void"
+
+#: flow.c:1582
+msgid "Attempt to delete prologue/epilogue insn:"
+msgstr "Intent d'esborrar insn pròleg/epíleg:"
+
+#: fold-const.c:2878 fold-const.c:2891
+#, c-format
+msgid "comparison is always %d due to width of bit-field"
+msgstr "la comparança sempre és %d a causa de l'amplària del camp de bit"
+
+#: fold-const.c:4093 fold-const.c:4110
+#, c-format
+msgid "comparison is always %d"
+msgstr "la comparança sempre és %d"
+
+#: fold-const.c:4241
+msgid "`or' of unmatched not-equal tests is always 1"
+msgstr "un \"or\" de proves no equivalents sense coincidència sempre és 1"
+
+#: fold-const.c:4246
+msgid "`and' of mutually exclusive equal-tests is always 0"
+msgstr "un \"and\" de proves equivalents mútuament exclusives sempre és 0"
+
+#: fold-const.c:8393
+msgid "fold check: original tree changed by fold"
+msgstr ""
+
+#: function.c:884 varasm.c:1408
+#, fuzzy
+msgid "%Jsize of variable '%D' is too large"
+msgstr "la grandària de la variable \"%s\" és massa gran"
+
+#: function.c:3742
+msgid "impossible constraint in `asm'"
+msgstr "restricció impossible en \"asm\""
+
+#: function.c:5723
+#, fuzzy
+msgid "%J'%D' might be used uninitialized in this function"
+msgstr "\"%s\" es deuria usar sense iniciar en aquesta funció"
+
+#: function.c:5730
+#, fuzzy
+msgid "%Jvariable '%D' might be clobbered by `longjmp' or `vfork'"
+msgstr "la variable \"%s\" podria ser sobreescrita per \"longjmp\" o \"vfork\""
+
+#: function.c:5749
+#, fuzzy
+msgid "%Jargument '%D' might be clobbered by `longjmp' or `vfork'"
+msgstr "l'argument \"%s\" podria ser sobreescrit per \"longjmp\" o \"vfork\""
+
+#: function.c:6523
+msgid "function returns an aggregate"
+msgstr "la funció retorna un agregat"
+
+#: function.c:7006
+#, fuzzy
+msgid "%Junused parameter '%D'"
+msgstr "paràmetre \"%s\" sense ús"
+
+#: gcc.c:1191
+#, c-format
+msgid "ambiguous abbreviation %s"
+msgstr "abreujament ambigu %s"
+
+#: gcc.c:1218
+#, c-format
+msgid "incomplete `%s' option"
+msgstr "Opció \"%s\" incompleta"
+
+#: gcc.c:1229
+#, c-format
+msgid "missing argument to `%s' option"
+msgstr "Falten arguments per a l'opció \"%s\""
+
+#: gcc.c:1242
+#, c-format
+msgid "extraneous argument to `%s' option"
+msgstr "argument estrany per a l'opció \"%s\""
+
+#: gcc.c:1570
+msgid "Using built-in specs.\n"
+msgstr "Usant especificacions internes.\n"
+
+#: gcc.c:1755
+#, c-format
+msgid ""
+"Setting spec %s to '%s'\n"
+"\n"
+msgstr ""
+"Canviant l'especificació de %s a \"%s\"\n"
+"\n"
+
+#: gcc.c:1857
+#, c-format
+msgid "Reading specs from %s\n"
+msgstr "Llegint especificacions de %s\n"
+
+#: gcc.c:1953 gcc.c:1972
+#, c-format
+msgid "specs %%include syntax malformed after %ld characters"
+msgstr "specs sintaxi mal formada de %%include després de %ld caràcters"
+
+#: gcc.c:1980
+#, c-format
+msgid "could not find specs file %s\n"
+msgstr "No es pot trobar el fitxer d'especificacions %s\n"
+
+#: gcc.c:1997 gcc.c:2005 gcc.c:2014 gcc.c:2023
+#, c-format
+msgid "specs %%rename syntax malformed after %ld characters"
+msgstr "specs sintaxi mal formada de %%rename després de %ld caràcters"
+
+#: gcc.c:2032
+#, c-format
+msgid "specs %s spec was not found to be renamed"
+msgstr "specs l'especificació %s no es va trobar per a ser re-nomenada"
+
+#: gcc.c:2039
+#, c-format
+msgid "%s: attempt to rename spec '%s' to already defined spec '%s'"
+msgstr ""
+
+#: gcc.c:2044
+#, c-format
+msgid "rename spec %s to %s\n"
+msgstr "re-nomenada especificació %s a %s\n"
+
+#: gcc.c:2046
+#, c-format
+msgid ""
+"spec is '%s'\n"
+"\n"
+msgstr ""
+"la especificació és \"%s\"\n"
+"\n"
+
+#: gcc.c:2059
+#, c-format
+msgid "specs unknown %% command after %ld characters"
+msgstr "specs comanda %% desconegut després de %ld caràcters"
+
+#: gcc.c:2070 gcc.c:2083
+#, c-format
+msgid "specs file malformed after %ld characters"
+msgstr "specs fitxer mal format després de %ld caràcters"
+
+#: gcc.c:2136
+msgid "spec file has no spec for linking"
+msgstr "el fitxer d'especificacions no té especificacions per a enllaçar"
+
+#: gcc.c:2641
+msgid "-pipe not supported"
+msgstr "-pipe no té suport"
+
+#: gcc.c:2703
+msgid ""
+"\n"
+"Go ahead? (y or n) "
+msgstr ""
+"\n"
+"Continuar? (s o n) "
+
+#: gcc.c:2829
+#, c-format
+msgid ""
+"Internal error: %s (program %s)\n"
+"Please submit a full bug report.\n"
+"See %s for instructions."
+msgstr ""
+"Error intern: %s (programa %s)\n"
+"Per favor envieu un informe complet d'error.\n"
+"Consulta %s per a més instruccions."
+
+#: gcc.c:2847
+#, c-format
+msgid "# %s %.2f %.2f\n"
+msgstr "# %s %.2f %.2f\n"
+
+#: gcc.c:2980
+#, c-format
+msgid "Usage: %s [options] file...\n"
+msgstr "Utilització: %s [opcions] fitxer...\n"
+
+#: gcc.c:2981
+msgid "Options:\n"
+msgstr "Opcions:\n"
+
+#: gcc.c:2983
+msgid " -pass-exit-codes Exit with highest error code from a phase\n"
+msgstr " -pass-exit-codes Sortir amb el codi d'error més alt d'una fase\n"
+
+#: gcc.c:2984
+msgid " --help Display this information\n"
+msgstr " --help Mostra aquesta informació\n"
+
+#: gcc.c:2985
+msgid " --target-help Display target specific command line options\n"
+msgstr ""
+" --target-help Mostra opcions de línia de comando específiques de\n"
+" l'objectiu\n"
+
+#: gcc.c:2987
+msgid " (Use '-v --help' to display command line options of sub-processes)\n"
+msgstr " (Usi \"-v --help\" per a mostrar les opcions de línia de comando dels subprocès)\n"
+
+#: gcc.c:2988
+msgid " -dumpspecs Display all of the built in spec strings\n"
+msgstr " -dumpspecs Mostra totes les cadenes internes d'especificació\n"
+
+#: gcc.c:2989
+msgid " -dumpversion Display the version of the compiler\n"
+msgstr " -dumpversion Mostra la versió del compilador\n"
+
+#: gcc.c:2990
+msgid " -dumpmachine Display the compiler's target processor\n"
+msgstr " -dumpmachine Mostra el processador objectiu del compilador\n"
+
+#: gcc.c:2991
+msgid " -print-search-dirs Display the directories in the compiler's search path\n"
+msgstr ""
+" -print-search-dirs Mostra les directoris en la ruta de recerca del\n"
+" compilador\n"
+
+#: gcc.c:2992
+msgid " -print-libgcc-file-name Display the name of the compiler's companion library\n"
+msgstr ""
+" -print-libgcc-file-name Mostra el nom de la biblioteca que acompanya el\n"
+" compilador\n"
+
+#: gcc.c:2993
+msgid " -print-file-name=<lib> Display the full path to library <lib>\n"
+msgstr " -print-file-name=<lib> Mostra la ruta completa a la biblioteca <lib>\n"
+
+#: gcc.c:2994
+msgid " -print-prog-name=<prog> Display the full path to compiler component <prog>\n"
+msgstr ""
+" -print-prog-name=<prog> Mostra la ruta completa del programa component del\n"
+" compilador <prog>\n"
+
+#: gcc.c:2995
+msgid " -print-multi-directory Display the root directory for versions of libgcc\n"
+msgstr " -print-multi-directory Mostra el directori arrel per a versoins de libgcc\n"
+
+#: gcc.c:2996
+msgid ""
+" -print-multi-lib Display the mapping between command line options and\n"
+" multiple library search directories\n"
+msgstr ""
+" -print-multi-lib Mostra el mapatge entre les opcions de línia de\n"
+" comanda i els múltiples directoris de la recerca\n"
+" de biblioteques\n"
+
+#: gcc.c:2999
+msgid " -print-multi-os-directory Display the relative path to OS libraries\n"
+msgstr " -print-multi-os-directory Mostra la ruta relativa per a les biblioteques del SO\n"
+
+#: gcc.c:3000
+msgid " -Wa,<options> Pass comma-separated <options> on to the assembler\n"
+msgstr " -Wa,<options> Passa <opcions> separades per coma al assemblador\n"
+
+#: gcc.c:3001
+msgid " -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"
+msgstr " -Wp,<opcions> Passa <opcions> separades per coma al preprocesador\n"
+
+#: gcc.c:3002
+msgid " -Wl,<options> Pass comma-separated <options> on to the linker\n"
+msgstr " -Wl,<opcions> Passa <opcions> separades per coma al enllaçador\n"
+
+#: gcc.c:3003
+#, fuzzy
+msgid " -Xassembler <arg> Pass <arg> on to the assembler\n"
+msgstr " -Xlinker <arg> Passa el <arg> al enllaçador\n"
+
+#: gcc.c:3004
+#, fuzzy
+msgid " -Xpreprocessor <arg> Pass <arg> on to the preprocessor\n"
+msgstr " -Xlinker <arg> Passa el <arg> al enllaçador\n"
+
+#: gcc.c:3005
+msgid " -Xlinker <arg> Pass <arg> on to the linker\n"
+msgstr " -Xlinker <arg> Passa el <arg> al enllaçador\n"
+
+#: gcc.c:3006
+msgid " -save-temps Do not delete intermediate files\n"
+msgstr " -save-temps No esborra els fitxers intermedis\n"
+
+#: gcc.c:3007
+msgid " -pipe Use pipes rather than intermediate files\n"
+msgstr " -pipe Usa canonades en lloc de fitxers intermedis\n"
+
+#: gcc.c:3008
+msgid " -time Time the execution of each subprocess\n"
+msgstr " -time Obté el temps d'execució de cada subprocès\n"
+
+#: gcc.c:3009
+msgid " -specs=<file> Override built-in specs with the contents of <file>\n"
+msgstr ""
+" -specs=<file> Sobreposa les especificacions internes amb el\n"
+" contingut de <fitxer>\n"
+
+#: gcc.c:3010
+msgid " -std=<standard> Assume that the input sources are for <standard>\n"
+msgstr ""
+" -std=<estàndard> Assumeix que les fitxers d'entrada són per a el\n"
+" <estàndard>\n"
+
+#: gcc.c:3011
+msgid " -B <directory> Add <directory> to the compiler's search paths\n"
+msgstr ""
+" -B <directori> Agrega el <directori> a les rutes de recerca del\n"
+" compilador\n"
+
+#: gcc.c:3012
+msgid " -b <machine> Run gcc for target <machine>, if installed\n"
+msgstr ""
+" -b <màquina> Executa gcc per a l'objectiu <màquina>,\n"
+" si va ser instal·lat\n"
+
+#: gcc.c:3013
+msgid " -V <version> Run gcc version number <version>, if installed\n"
+msgstr ""
+" -V <versió> Executa el gcc amb nombre de versió <versió>,\n"
+" si va ser instal·lat\n"
+
+#: gcc.c:3014
+msgid " -v Display the programs invoked by the compiler\n"
+msgstr " -v Mostra els programes invocats pel compilador\n"
+
+#: gcc.c:3015
+msgid " -### Like -v but options quoted and commands not executed\n"
+msgstr ""
+" -### Com -v però les opcions i comandes entr \"\" no estan\n"
+" executades\n"
+
+#: gcc.c:3016
+msgid " -E Preprocess only; do not compile, assemble or link\n"
+msgstr " -E Solament preprocessa; no compila, assembla o enllaça\n"
+
+#: gcc.c:3017
+msgid " -S Compile only; do not assemble or link\n"
+msgstr " -S Solament compila; no assembla o enllaça\n"
+
+#: gcc.c:3018
+msgid " -c Compile and assemble, but do not link\n"
+msgstr " -c Compila i assembla, però no enllaça\n"
+
+#: gcc.c:3019
+msgid " -o <file> Place the output into <file>\n"
+msgstr " -o <fitxer> Col·loca la sortida en el <fitxer>\n"
+
+#: gcc.c:3020
+msgid ""
+" -x <language> Specify the language of the following input files\n"
+" Permissible languages include: c c++ assembler none\n"
+" 'none' means revert to the default behavior of\n"
+" guessing the language based on the file's extension\n"
+msgstr ""
+" -x <llenguatge> Especifica el llenguatge dels següents fitxers d''\n"
+" entrada. Els llenguatges permesos inclouen: c c++\n"
+" assembler none. \"none\" significa revertir a la\n"
+" conducta habitual de endevinar el llenguatge basat\n"
+" en l'extensió del fitxer\n"
+
+#: gcc.c:3027
+#, c-format
+msgid ""
+"\n"
+"Options starting with -g, -f, -m, -O, -W, or --param are automatically\n"
+" passed on to the various sub-processes invoked by %s. In order to pass\n"
+" other options on to these processes the -W<letter> options must be used.\n"
+msgstr ""
+"\n"
+"Les opcions que comencen amb -g, -f, -m, -O, -W, o --param es passen\n"
+" automàticament als varis subprocesos invocats per %s. Per passar altres\n"
+" opcions a aquests processos es deuen usar les opcions -W<lletra>\n"
+
+#: gcc.c:3148
+#, c-format
+msgid "`-%c' option must have argument"
+msgstr "l'opció \"-%c\" deu tenir arguments"
+
+#: gcc.c:3170
+#, c-format
+msgid "couldn't run `%s': %s"
+msgstr ""
+
+#. translate_options () has turned --version into -fversion.
+#: gcc.c:3356
+#, c-format
+msgid "%s (GCC) %s\n"
+msgstr "%s (GCC) %s\n"
+
+#: gcc.c:3358 gcov.c:424 f/g77spec.c:351
+msgid "(C)"
+msgstr ""
+
+#: gcc.c:3359
+msgid ""
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+"\n"
+msgstr ""
+"Això és programari lliure; vegi el codi font per a les condicions de còpia.\n"
+"Aquest és programari lliure; vegeu el codi font per les condicions\n"
+"de còpia. No hi ha CAP garantia; ni tan sols de COMERCIABILITAT o\n"
+"ADEQUACIÓ A UN PROPÒSIT PARTICULAR.\n"
+
+#: gcc.c:3460
+msgid "argument to `-Xlinker' is missing"
+msgstr "falta l'argument per a \"-Xlinker\""
+
+#: gcc.c:3468
+#, fuzzy
+msgid "argument to `-Xpreprocessor' is missing"
+msgstr "falta l'argument per a \"-specs\""
+
+#: gcc.c:3475
+#, fuzzy
+msgid "argument to `-Xassembler' is missing"
+msgstr "falta l'argument per a \"-Xlinker\""
+
+#: gcc.c:3482
+msgid "argument to `-l' is missing"
+msgstr "falta l'argument per a \"-I\""
+
+#: gcc.c:3498
+msgid "argument to `-specs' is missing"
+msgstr "falta l'argument per a \"-specs\""
+
+#: gcc.c:3512
+msgid "argument to `-specs=' is missing"
+msgstr "falta l'argument per a \"-specs=\""
+
+#: gcc.c:3549
+#, c-format
+msgid "`-%c' must come at the start of the command line"
+msgstr ""
+
+#: gcc.c:3558
+msgid "argument to `-B' is missing"
+msgstr "falta l'argument per a \"-B\""
+
+#: gcc.c:3735
+msgid "warning: -pipe ignored because -save-temps specified"
+msgstr "Avís: s'ignora -pipe perquè es va especificar -save-temps"
+
+#: gcc.c:3739
+msgid "warning: -pipe ignored because -time specified"
+msgstr "Avís: s'ignora -pipe perquè es va especificar -time"
+
+#: gcc.c:3951
+msgid "argument to `-x' is missing"
+msgstr "falta l'argument per a \"-x\""
+
+#: gcc.c:3979
+#, c-format
+msgid "argument to `-%s' is missing"
+msgstr "falta l'argument per a \"-%s\""
+
+#: gcc.c:4040
+#, c-format
+msgid "warning: `-x %s' after last input file has no effect"
+msgstr "avís: \"-x %s\" després de l'últim fitxer d'entrada no té efecte"
+
+#: gcc.c:4441
+msgid "invalid specification! Bug in cc"
+msgstr "Especificació invàlida! Bug en cc."
+
+#: gcc.c:4595
+#, c-format
+msgid "%s\n"
+msgstr "%s\n"
+
+#. Catch the case where a spec string contains something like
+#. '%{foo:%*}'. ie there is no * in the pattern on the left
+#. hand side of the :.
+#: gcc.c:5099
+#, c-format
+msgid "spec failure: '%%*' has not been initialized by pattern match"
+msgstr "Falla en spec: \"%%*\" no ha estat iniciat per coincidència de patró"
+
+#: gcc.c:5108
+#, c-format
+msgid "warning: use of obsolete %%[ operator in specs"
+msgstr "Avís: ús de l'operador obsolet %%[ en specs"
+
+#: gcc.c:5126
+#, c-format
+msgid "Processing spec %c%s%c, which is '%s'\n"
+msgstr "Processant l'especificació %c%s%c, el qual és \"%s\"\n"
+
+#: gcc.c:5189
+#, c-format
+msgid "spec failure: unrecognized spec option '%c'"
+msgstr "Falla en spec: Opció d'especificació \"%c\" no reconeguda"
+
+#: gcc.c:5268
+#, c-format
+msgid "unknown spec function `%s'"
+msgstr "funció d'especificació \"%s\" desconeguda"
+
+#: gcc.c:5287
+#, c-format
+msgid "error in args to spec function `%s'"
+msgstr "error en els arguments per a la funció d'especificació \"%s\""
+
+#: gcc.c:5335
+msgid "malformed spec function name"
+msgstr "nom de la funció d'especificació malformat"
+
+#. )
+#: gcc.c:5338
+msgid "no arguments for spec function"
+msgstr "molt pocs arguments per a la funció spec"
+
+#: gcc.c:5357
+msgid "malformed spec function arguments"
+msgstr ""
+
+#: gcc.c:6083
+msgid "spec failure: more than one arg to SYSROOT_SUFFIX_SPEC."
+msgstr ""
+
+#: gcc.c:6093
+msgid "spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC."
+msgstr ""
+
+#: gcc.c:6186
+#, c-format
+msgid "unrecognized option `-%s'"
+msgstr "opció \"-%s\" no reconeguda"
+
+#: gcc.c:6192
+#, c-format
+msgid "install: %s%s\n"
+msgstr "instal·lar: %s%s\n"
+
+#: gcc.c:6193
+#, c-format
+msgid "programs: %s\n"
+msgstr "programes: %s\n"
+
+#: gcc.c:6194
+#, c-format
+msgid "libraries: %s\n"
+msgstr "biblioteques: %s\n"
+
+#: gcc.c:6251
+msgid ""
+"\n"
+"For bug reporting instructions, please see:\n"
+msgstr ""
+"\n"
+"Per a instruccions de report de bug, si us plau per favor vegi:\n"
+
+#: gcc.c:6267
+#, c-format
+msgid "Configured with: %s\n"
+msgstr "Configurat amb: %s\n"
+
+#: gcc.c:6281
+#, c-format
+msgid "Thread model: %s\n"
+msgstr "Model de fils: %s\n"
+
+#: gcc.c:6292
+#, c-format
+msgid "gcc version %s\n"
+msgstr "gcc versió %s\n"
+
+#: gcc.c:6294
+#, c-format
+msgid "gcc driver version %s executing gcc version %s\n"
+msgstr "controlador gcc versió %s executant gcc versió %s\n"
+
+#: gcc.c:6302
+msgid "no input files"
+msgstr "no hi ha fitxers d'entrada"
+
+#: gcc.c:6324 gcc.c:6443
+#, c-format
+msgid "%s: linker input file unused because linking not done"
+msgstr "%s: fitxer d'entrada de l'enllaçador sense ùs perquè no es va fer enllaç"
+
+#: gcc.c:6327
+#, fuzzy
+msgid "cannot specify -o with -c or -S and multiple languages"
+msgstr "no es pot especificar -o amb -c o -S i múltiples compilacions"
+
+#: gcc.c:6362
+#, c-format
+msgid "%s: %s compiler not installed on this system"
+msgstr "%s: el compilador %s no està instal·lat en aquest sistema"
+
+#: gcc.c:6483
+#, c-format
+msgid "language %s not recognized"
+msgstr "no es reconeix el llenguatge %s"
+
+#: gcc.c:6580
+msgid "internal gcc abort"
+msgstr "avortament intern de gcc"
+
+#: gcov.c:384
+msgid "Internal gcov abort.\n"
+msgstr "avortament intern de gcov.\n"
+
+#: gcov.c:397
+msgid ""
+"Usage: gcov [OPTION]... SOURCEFILE\n"
+"\n"
+msgstr ""
+"Us: gcov [OPCIO]... FITXERFONT\n"
+"\n"
+
+#: gcov.c:398
+msgid ""
+"Print code coverage information.\n"
+"\n"
+msgstr ""
+"Produire les informacions de la covertura del codi.\n"
+"\n"
+
+#: gcov.c:399
+msgid " -h, --help Print this help, then exit\n"
+msgstr " -h, --help Mostra aquesta informació, i surt\n"
+
+#: gcov.c:400
+msgid " -v, --version Print version number, then exit\n"
+msgstr " -v, --version Mostra el numero de versió, i surt\n"
+
+#: gcov.c:401
+msgid " -a, --all-blocks Show information for every basic block\n"
+msgstr ""
+
+#: gcov.c:402
+msgid " -b, --branch-probabilities Include branch probabilities in output\n"
+msgstr " -b, --branch-probabilities Incloure les probabilitats de brancament en la sortida\n"
+
+#: gcov.c:403
+msgid ""
+" -c, --branch-counts Given counts of branches taken\n"
+" rather than percentages\n"
+msgstr ""
+" -c, --branch-counts Dóna el compte de branques pres\n"
+" enlloc de percentatges\n"
+
+#: gcov.c:405
+msgid " -n, --no-output Do not create an output file\n"
+msgstr " -n, --no-output No crea un fitxer de sortida\n"
+
+#: gcov.c:406
+msgid ""
+" -l, --long-file-names Use long output file names for included\n"
+" source files\n"
+msgstr ""
+" -l, --long-file-names Usar nom de fitxers de sortida llargs per a\n"
+" les fitxers font inclòs\n"
+
+#: gcov.c:408
+msgid " -f, --function-summaries Output summaries for each function\n"
+msgstr " -f, --function-summaries Fer un resum per a cada funció\n"
+
+#: gcov.c:409
+msgid " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n"
+msgstr " -o, --object-directory DIR|FIT Cerca les fitxers objectes en DIR o el FITxer\n"
+
+#: gcov.c:410
+msgid " -p, --preserve-paths Preserve all pathname components\n"
+msgstr ""
+
+#: gcov.c:411
+msgid " -u, --unconditional-branches Show unconditional branch counts too\n"
+msgstr ""
+
+#: gcov.c:412
+#, c-format
+msgid ""
+"\n"
+"For bug reporting instructions, please see:\n"
+"%s.\n"
+msgstr ""
+"\n"
+"Per a instrucions d'informe de bug, si us plau consulta:\n"
+"%s.\n"
+
+#: gcov.c:422
+#, c-format
+msgid "gcov (GCC) %s\n"
+msgstr "gcov (GCC) %s\n"
+
+#: gcov.c:426
+#, fuzzy
+msgid ""
+"This is free software; see the source for copying conditions.\n"
+"There is NO warranty; not even for MERCHANTABILITY or \n"
+"FITNESS FOR A PARTICULAR PURPOSE.\n"
+"\n"
+msgstr ""
+"Això és programari lliure; vegi el codi font per a les condicions de còpia.\n"
+"Aquest és programari lliure; vegeu el codi font per les condicions\n"
+"de còpia. No hi ha CAP garantia; ni tan sols de COMERCIABILITAT o\n"
+"ADEQUACIÓ A UN PROPÒSIT PARTICULAR.\n"
+
+#: gcov.c:516
+#, fuzzy, c-format
+msgid "%s:no functions found\n"
+msgstr "no es troben cmd_strings"
+
+#: gcov.c:537 gcov.c:565
+#, fuzzy
+msgid "\n"
+msgstr ":\n"
+
+#: gcov.c:552
+#, fuzzy, c-format
+msgid "%s:creating `%s'\n"
+msgstr "creant %s"
+
+#: gcov.c:556
+#, fuzzy, c-format
+msgid "%s:error writing output file `%s'\n"
+msgstr "Error a l'escriure al fitxer de sortida %s.\n"
+
+#: gcov.c:561
+#, fuzzy, c-format
+msgid "%s:could not open output file `%s'\n"
+msgstr "No es pot obrir el fitxer de sortida %s.\n"
+
+#: gcov.c:712
+#, fuzzy, c-format
+msgid "%s:cannot open graph file\n"
+msgstr "%s: no es pot obrir com un fitxer COFF"
+
+#: gcov.c:718
+#, fuzzy, c-format
+msgid "%s:not a gcov graph file\n"
+msgstr "%s: no és un fitxer COFF"
+
+#: gcov.c:731
+#, c-format
+msgid "%s:version `%.4s', prefer `%.4s'\n"
+msgstr ""
+
+#: gcov.c:783
+#, c-format
+msgid "%s:already seen blocks for `%s'\n"
+msgstr ""
+
+#: gcov.c:904 gcov.c:1063
+#, c-format
+msgid "%s:corrupted\n"
+msgstr ""
+
+#: gcov.c:977
+#, fuzzy, c-format
+msgid "%s:cannot open data file\n"
+msgstr "%s: no es pot obrir com un fitxer COFF"
+
+#: gcov.c:982
+#, fuzzy, c-format
+msgid "%s:not a gcov data file\n"
+msgstr "%s: no és un fitxer COFF"
+
+#: gcov.c:995
+#, c-format
+msgid "%s:version `%.4s', prefer version `%.4s'\n"
+msgstr ""
+
+#: gcov.c:1001
+#, c-format
+msgid "%s:stamp mismatch with graph file\n"
+msgstr ""
+
+#: gcov.c:1027
+#, fuzzy, c-format
+msgid "%s:unknown function `%u'\n"
+msgstr "funció d'especificació \"%s\" desconeguda"
+
+#: gcov.c:1040
+#, c-format
+msgid "%s:profile mismatch for `%s'\n"
+msgstr ""
+
+#: gcov.c:1063
+#, c-format
+msgid "%s:overflowed\n"
+msgstr ""
+
+#: gcov.c:1086
+#, c-format
+msgid "%s:`%s' lacks entry and/or exit blocks\n"
+msgstr ""
+
+#: gcov.c:1091
+#, c-format
+msgid "%s:`%s' has arcs to entry block\n"
+msgstr ""
+
+#: gcov.c:1099
+#, c-format
+msgid "%s:`%s' has arcs from exit block\n"
+msgstr ""
+
+#: gcov.c:1307
+#, c-format
+msgid "%s:graph is unsolvable for `%s'\n"
+msgstr ""
+
+#: gcov.c:1387
+#, fuzzy, c-format
+msgid "%s `%s'\n"
+msgstr "En %s \"%s\":"
+
+#: gcov.c:1390
+#, fuzzy, c-format
+msgid "Lines executed:%s of %d\n"
+msgstr "es van executar %s de %d línies en %s %s\n"
+
+#: gcov.c:1394
+#, fuzzy
+msgid "No executable lines"
+msgstr "No hi ha línies de codi font executable en %s %s\n"
+
+#: gcov.c:1400
+#, fuzzy, c-format
+msgid "Branches executed:%s of %d\n"
+msgstr "%s de %d ramificacions executades en %s %s\n"
+
+#: gcov.c:1404
+#, fuzzy, c-format
+msgid "Taken at least once:%s of %d\n"
+msgstr "%s de %d ramificacions visitades almenys una vegada en %s %s\n"
+
+#: gcov.c:1410
+#, fuzzy
+msgid "No branches\n"
+msgstr "No hi ha ramificacions en %s %s\n"
+
+#: gcov.c:1412
+#, fuzzy, c-format
+msgid "Calls executed:%s of %d\n"
+msgstr "%s de %d cridades executades en %s %s\n"
+
+#: gcov.c:1416
+#, fuzzy
+msgid "No calls\n"
+msgstr "No hi ha cridades en %s %s\n"
+
+#: gcov.c:1557
+#, fuzzy, c-format
+msgid "%s:no lines for `%s'\n"
+msgstr "%s abans de \"%s\""
+
+#: gcov.c:1752
+#, fuzzy, c-format
+msgid "call %2d returned %s\n"
+msgstr "la cridada %2d retorna %s\n"
+
+#: gcov.c:1757
+#, c-format
+msgid "call %2d never executed\n"
+msgstr "la cridada %2d mai s'executa\n"
+
+#: gcov.c:1762
+#, fuzzy, c-format
+msgid "branch %2d taken %s%s\n"
+msgstr "ramificació %2d presa %s\n"
+
+#: gcov.c:1766
+#, c-format
+msgid "branch %2d never executed\n"
+msgstr "la ramificació %2d mai s'executa\n"
+
+#: gcov.c:1771
+#, fuzzy, c-format
+msgid "unconditional %2d taken %s\n"
+msgstr "ramificació %2d presa %s\n"
+
+#: gcov.c:1774
+#, fuzzy, c-format
+msgid "unconditional %2d never executed\n"
+msgstr "la cridada %2d mai s'executa\n"
+
+#: gcov.c:1806
+#, fuzzy, c-format
+msgid "%s:cannot open source file\n"
+msgstr "%s: no es pot obrir com un fitxer COFF"
+
+#: gcov.c:1816
+#, fuzzy, c-format
+msgid "%s:source file is newer than graph file `%s'\n"
+msgstr "Avís: el fitxer actual %s és més nou que %s\n"
+
+#. Return if there's nothing to do, or it is too expensive.
+#: gcse.c:747
+msgid "GCSE disabled"
+msgstr ""
+
+#: gcse.c:6124
+msgid "NULL pointer checks disabled"
+msgstr ""
+
+#. Return if there's nothing to do, or it is too expensive.
+#: gcse.c:8010
+#, fuzzy
+msgid "jump bypassing disabled"
+msgstr "opció -g desactivada"
+
+#: gcse.c:8071
+#, fuzzy, c-format
+msgid "%s: %d basic blocks and %d edges/basic block"
+msgstr "GCSE desactivat: %d > 1000 blocs bàsics i %d >= 20 blocs bord/bàsics"
+
+#: gcse.c:8084
+#, fuzzy, c-format
+msgid "%s: %d basic blocks and %d registers"
+msgstr "GCSE desactivat: %d blocs bàsics i %d registres"
+
+#: ggc-common.c:398 ggc-common.c:406 ggc-common.c:487 ggc-common.c:507
+#: ggc-page.c:2030 ggc-page.c:2062 ggc-page.c:2069 ggc-zone.c:1361
+#: ggc-zone.c:1367 ggc-zone.c:1372 ggc-zone.c:1379
+#, fuzzy, c-format
+msgid "can't write PCH file: %m"
+msgstr "no es pot escriure al fitxer de sortida"
+
+#: ggc-common.c:500
+#, fuzzy, c-format
+msgid "can't get position in PCH file: %m"
+msgstr "no es pot crear el fitxer d'informació de \"repository\" \"%s\""
+
+#: ggc-common.c:510
+#, fuzzy, c-format
+msgid "can't write padding to PCH file: %m"
+msgstr "no es pot escriure al fitxer de sortida"
+
+#: ggc-common.c:563 ggc-common.c:571 ggc-common.c:578 ggc-common.c:581
+#: ggc-common.c:654 ggc-common.c:657 ggc-page.c:2157 ggc-zone.c:1389
+#, fuzzy, c-format
+msgid "can't read PCH file: %m"
+msgstr "no es pot llegir dès del fitxer temporal"
+
+#: ggc-common.c:681
+msgid "had to relocate PCH"
+msgstr ""
+
+#: ggc-page.c:1325
+#, c-format
+msgid "open /dev/zero: %m"
+msgstr ""
+
+#: ggc-page.c:2047 ggc-page.c:2053
+#, fuzzy
+msgid "can't write PCH file"
+msgstr "no es pot escriure al fitxer de sortida"
+
+#: ggc-simple.c:526
+msgid "Generating PCH files is not supported when using ggc-simple.c"
+msgstr ""
+
+#: global.c:356 global.c:369 global.c:383
+#, fuzzy, c-format
+msgid "%s cannot be used in asm here"
+msgstr "no es pot usar \"%E\" com una funció"
+
+#: graph.c:403 toplev.c:1498 toplev.c:4432 f/com.c:14202 java/jcf-parse.c:883
+#: java/jcf-parse.c:1029 java/lex.c:1828 objc/objc-act.c:503
+#, fuzzy, c-format
+msgid "can't open %s: %m"
+msgstr "no és pot obrir %s"
+
+#: haifa-sched.c:196
+#, c-format
+msgid "fix_sched_param: unknown param: %s"
+msgstr "fix_sched_param: paràmetre desconegut: %s"
+
+#: integrate.c:166
+msgid "function cannot be inline"
+msgstr "la funció no pot ser inline"
+
+#: integrate.c:170
+msgid "varargs function cannot be inline"
+msgstr "la funció varargs no pot ser inline"
+
+#: integrate.c:173
+msgid "function using alloca cannot be inline"
+msgstr "la funció que usa alloca no pot ser inline"
+
+#: integrate.c:176
+#, fuzzy
+msgid "function using longjmp cannot be inline"
+msgstr "la funció que usa setjmp no pot ser inline"
+
+#: integrate.c:179
+msgid "function using setjmp cannot be inline"
+msgstr "la funció que usa setjmp no pot ser inline"
+
+#: integrate.c:182
+msgid "function uses __builtin_eh_return"
+msgstr "la funció usa __builtin_eh_return"
+
+#: integrate.c:185
+msgid "function with nested functions cannot be inline"
+msgstr "una funció amb funcions niades no pot ser inline"
+
+#: integrate.c:189
+msgid "function with label addresses used in initializers cannot inline"
+msgstr "una funció amb adreces d'etiquetes usada en iniciadors no pot ser inline"
+
+#: integrate.c:196 integrate.c:240
+msgid "function too large to be inline"
+msgstr "la funció és massa gran per a ser inline"
+
+#: integrate.c:206
+msgid "no prototype, and parameter address used; cannot be inline"
+msgstr "no hi ha prototip, i s'usen adreces de paràmetre; no pot ser inline"
+
+#: integrate.c:213 integrate.c:258
+msgid "inline functions not supported for this return value type"
+msgstr "no es dóna suport a funcions inline per a aquest tipus de valor de retorn"
+
+#: integrate.c:218
+msgid "function with varying-size return value cannot be inline"
+msgstr "una funció amb valor de retorn de grandària variable no pot ser inline"
+
+#: integrate.c:225
+msgid "function with varying-size parameter cannot be inline"
+msgstr "una funció amb paràmetre de grandària variable no pot ser inline"
+
+#: integrate.c:228
+msgid "function with transparent unit parameter cannot be inline"
+msgstr "una funció amb paràmetre d'unitat transparent no pot ser inline"
+
+#: integrate.c:247
+msgid "function with computed jump cannot inline"
+msgstr "una funció amb salt calculat no pot ser inline"
+
+#: integrate.c:251
+msgid "function with nonlocal goto cannot be inline"
+msgstr "una funció amb goto no local no pot ser inline"
+
+#: integrate.c:265
+msgid "function with target specific attribute(s) cannot be inlined"
+msgstr "una funció amb atribut(s) específic(s) de l'objectiu no pot ser inline"
+
+#: jump.c:1896
+#, fuzzy
+msgid "%Hwill never be executed"
+msgstr "la cridada %2d mai s'executa\n"
+
+#: line-map.c:202
+#, c-format
+msgid "In file included from %s:%u"
+msgstr "En el fitxer inclòs dès de %s:%u"
+
+#. Translators note: this message is used in conjunction
+#. with "In file included from %s:%ld" and some other
+#. tricks. We want something like this:
+#.
+#. | In file included from sys/select.h:123,
+#. | from sys/types.h:234,
+#. | from userfile.c:31:
+#. | bits/select.h:45: <error message here>
+#.
+#. with all the "from"s lined up.
+#. The trailing comma is at the beginning of this message,
+#. and the trailing colon is not translated.
+#: line-map.c:220
+#, c-format
+msgid ""
+",\n"
+" from %s:%u"
+msgstr ""
+",\n"
+" dès de %s:%u"
+
+#. What to print when a switch has no documentation.
+#: opts.c:149
+msgid "This switch lacks documentation"
+msgstr ""
+
+#. Eventually this should become a hard error IMO.
+#: opts.c:318
+#, fuzzy, c-format
+msgid "command line option \"%s\" is valid for %s but not for %s"
+msgstr "\"-%c%s%s\" és vàlida per a %s però no per a %s"
+
+#: opts.c:406
+#, fuzzy, c-format
+msgid "missing argument to \"%s\""
+msgstr "Falten arguments per a \"-%s\""
+
+#: opts.c:416
+#, fuzzy, c-format
+msgid "argument to \"%s\" should be a non-negative integer"
+msgstr "l'argument per a \"%s\" deu ser una literal sense signe de 2-bit"
+
+#: opts.c:463
+#, fuzzy, c-format
+msgid "unrecognized command line option \"%s\""
+msgstr "ignorant l'opció de línia de comanda \"%s\""
+
+#: opts.c:646
+msgid "-Wuninitialized is not supported without -O"
+msgstr "-Wuninitialized no té suport sense -O"
+
+#: opts.c:1354
+#, fuzzy, c-format
+msgid "unrecognized register name \"%s\""
+msgstr "no es reconeix el nom de registre \"%s\""
+
+#: opts.c:1398
+#, fuzzy, c-format
+msgid "unknown tls-model \"%s\""
+msgstr "\"%s\": opció tls-model desconeguda"
+
+#: opts.c:1454
+#, fuzzy
+msgid "-fwritable-strings is deprecated; see documentation for details"
+msgstr "el switch \"%s\" és obsolet, per favor vegi la documentació per a més detalls"
+
+#: opts.c:1538
+#, c-format
+msgid "%s: --param arguments should be of the form NAME=VALUE"
+msgstr ""
+
+#: opts.c:1543
+#, fuzzy, c-format
+msgid "invalid --param value `%s'"
+msgstr "valor de paràmetre \"%s\" invàlid"
+
+#: opts.c:1639
+#, fuzzy
+msgid "target system does not support debug output"
+msgstr "el format objectiu no té suport per a infinit"
+
+#: opts.c:1646
+#, fuzzy, c-format
+msgid "debug format \"%s\" conflicts with prior selection"
+msgstr "l'àrea de dades de \"%s\" en conflicte amb una declaració prèvia"
+
+#: opts.c:1662
+#, fuzzy, c-format
+msgid "unrecognised debug output level \"%s\""
+msgstr "no es reconeix el nom de secció \"%s\""
+
+#: opts.c:1664
+#, c-format
+msgid "debug output level %s is too high"
+msgstr ""
+
+#: opts.c:1683
+msgid "The following options are language-independent:\n"
+msgstr ""
+
+#: opts.c:1690
+#, c-format
+msgid ""
+"The %s front end recognizes the following options:\n"
+"\n"
+msgstr ""
+
+#: opts.c:1704
+msgid "The --param option recognizes the following as parameters:\n"
+msgstr ""
+
+#. If we didn't find this parameter, issue an error message.
+#: params.c:76
+#, c-format
+msgid "invalid parameter `%s'"
+msgstr "el paràmetre \"%s\" és invàlid"
+
+#: profile.c:288
+msgid "corrupted profile info: run_max * runs < sum_max"
+msgstr ""
+
+#: profile.c:294
+msgid "corrupted profile info: sum_all is smaller than sum_max"
+msgstr ""
+
+#: profile.c:336
+#, fuzzy, c-format
+msgid "corrupted profile info: edge from %i to %i exceeds maximal count"
+msgstr "informació de profil corrupta: prob per a %d-%d pensa ser %d"
+
+#: profile.c:499
+#, fuzzy, c-format
+msgid "corrupted profile info: number of iterations for basic block %d thought to be %i"
+msgstr "informació de profil corrupta: prob per a %d-%d pensa ser %d"
+
+#: profile.c:526
+#, fuzzy, c-format
+msgid "corrupted profile info: number of executions for edge %d-%d thought to be %i"
+msgstr "informació de profil corrupta: prob per a %d-%d pensa ser %d"
+
+#: protoize.c:534
+#, c-format
+msgid "%s: internal abort\n"
+msgstr "%s: abandó intern\n"
+
+#: protoize.c:592
+#, c-format
+msgid "%s: error writing file `%s': %s\n"
+msgstr "%s: error a l'escriure al fitxer \"%s\": %s\n"
+
+#: protoize.c:636
+#, c-format
+msgid "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n"
+msgstr "%s: ùs \"%s [ -VqfnkN ] [ -i <icadena> ] [ nom_fitxer ... ]\"\n"
+
+#: protoize.c:639
+#, c-format
+msgid "%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n"
+msgstr "%s: ùs \"%s [ -VqfnkNlgC ] [ -B <nom_directori> ] [ nom_fitxer ... ]\"\n"
+
+#: protoize.c:745
+#, c-format
+msgid "%s: warning: no read access for file `%s'\n"
+msgstr "%s: avís: no hi ha accés de lectura per al fitxer \"%s\"\n"
+
+#: protoize.c:753
+#, c-format
+msgid "%s: warning: no write access for file `%s'\n"
+msgstr "%s: avís: no hi ha accés d'escriptura per al fitxer \"%s\"\n"
+
+#: protoize.c:761
+#, c-format
+msgid "%s: warning: no write access for dir containing `%s'\n"
+msgstr "%s: avís: no hi ha accés d'escriptura per al directori que conté a \"%s\"\n"
+
+#. Catch cases like /.. where we try to backup to a
+#. point above the absolute root of the logical file
+#. system.
+#: protoize.c:1148
+#, c-format
+msgid "%s: invalid file name: %s\n"
+msgstr "%s: nom de fitxer invàlid: %s\n"
+
+#: protoize.c:1296
+#, c-format
+msgid "%s: %s: can't get status: %s\n"
+msgstr "%s: %s: no es pot obtenir l'estat: %s\n"
+
+#: protoize.c:1317
+#, c-format
+msgid ""
+"\n"
+"%s: fatal error: aux info file corrupted at line %d\n"
+msgstr ""
+"\n"
+"%s: error fatal: fitxer d'informació auxiliar corrupte en la línia %d\n"
+
+#: protoize.c:1646
+#, c-format
+msgid "%s:%d: declaration of function `%s' takes different forms\n"
+msgstr "%s:%d: la declaració de la funció `%s' pren formes diferents\n"
+
+#: protoize.c:1901
+#, c-format
+msgid "%s: compiling `%s'\n"
+msgstr "%s: compilant `%s'\n"
+
+#: protoize.c:1924
+#, c-format
+msgid "%s: wait: %s\n"
+msgstr "%s: esperar: %s\n"
+
+#: protoize.c:1929
+#, c-format
+msgid "%s: subprocess got fatal signal %d\n"
+msgstr "%s: el subproces va rebre el senyal fatal %d\n"
+
+#: protoize.c:1937
+#, c-format
+msgid "%s: %s exited with status %d\n"
+msgstr "%s: %s va acabar amb estat %d\n"
+
+#: protoize.c:1986
+#, c-format
+msgid "%s: warning: missing SYSCALLS file `%s'\n"
+msgstr "%s: avís: falta el fitxer SYSCALLS \"%s\"\n"
+
+#: protoize.c:1995 protoize.c:2024
+#, c-format
+msgid "%s: can't read aux info file `%s': %s\n"
+msgstr "%s: no es pot llegir el fitxer d'informació auxiliar \"%s\": %s\n"
+
+#: protoize.c:2040 protoize.c:2068
+#, c-format
+msgid "%s: can't get status of aux info file `%s': %s\n"
+msgstr "%s: no es pot obtenir l'estat del fitxer d'informació auxiliar \"%s\": %s\n"
+
+#: protoize.c:2096
+#, c-format
+msgid "%s: can't open aux info file `%s' for reading: %s\n"
+msgstr "%s: no es pot obrir el fitxer d'informació auxiliar \"%s\" per a lectura: %s\n"
+
+#: protoize.c:2114
+#, c-format
+msgid "%s: error reading aux info file `%s': %s\n"
+msgstr "%s: error al llegir el fitxer d'informació auxiliar \"%s\": %s\n"
+
+#: protoize.c:2127
+#, c-format
+msgid "%s: error closing aux info file `%s': %s\n"
+msgstr "%s: error al tancar el fitxer d'informació auxiliar \"%s\": %s\n"
+
+#: protoize.c:2143
+#, c-format
+msgid "%s: can't delete aux info file `%s': %s\n"
+msgstr "%s: no es pot esborrar el fitxer d'informació auxiliar \"%s\": %s\n"
+
+#: protoize.c:2225 protoize.c:4195
+#, c-format
+msgid "%s: can't delete file `%s': %s\n"
+msgstr "%s: no es pot esborrar el fitxer \"%s\": %s\n"
+
+#: protoize.c:2303
+#, c-format
+msgid "%s: warning: can't rename file `%s' to `%s': %s\n"
+msgstr "%s: avís: no es pot renomenar el fitxer \"%s\" a \"%s\": %s\n"
+
+#: protoize.c:2425
+#, c-format
+msgid "%s: conflicting extern definitions of '%s'\n"
+msgstr "%s: definicions externes de \"%s\" en conflicte\n"
+
+#: protoize.c:2429
+#, c-format
+msgid "%s: declarations of '%s' will not be converted\n"
+msgstr "%s: les declaracions de \"%s\" no es convertiran\n"
+
+#: protoize.c:2431
+#, c-format
+msgid "%s: conflict list for '%s' follows:\n"
+msgstr "%s: llistes de conflictes per a \"%s\" a continuació:\n"
+
+#: protoize.c:2464
+#, c-format
+msgid "%s: warning: using formals list from %s(%d) for function `%s'\n"
+msgstr "%s: avís: usant llistes formals de %s(%d) per a la funció \"%s\"\n"
+
+#: protoize.c:2504
+#, c-format
+msgid "%s: %d: `%s' used but missing from SYSCALLS\n"
+msgstr "%s: %d: s'usa \"%s\" però falta en SYSCALLS\n"
+
+#: protoize.c:2510
+#, c-format
+msgid "%s: %d: warning: no extern definition for `%s'\n"
+msgstr "%s: %d: avís: no hi ha definició extern per a \"%s\"\n"
+
+#: protoize.c:2540
+#, c-format
+msgid "%s: warning: no static definition for `%s' in file `%s'\n"
+msgstr "%s: avís: no hi ha definició static per a \"%s\" en el fitxer \"%s\"\n"
+
+#: protoize.c:2546
+#, c-format
+msgid "%s: multiple static defs of `%s' in file `%s'\n"
+msgstr "%s: definicions static múltiples de \"%s\" en el fitxer \"%s\"\n"
+
+#: protoize.c:2716 protoize.c:2719
+#, c-format
+msgid "%s: %d: warning: source too confusing\n"
+msgstr "%s: %d: avís: codi font massa confús\n"
+
+#: protoize.c:2915
+#, c-format
+msgid "%s: %d: warning: varargs function declaration not converted\n"
+msgstr "%s: %d: avís: no es va convertir la declaració de la funció varargs\n"
+
+#: protoize.c:2930
+#, c-format
+msgid "%s: declaration of function `%s' not converted\n"
+msgstr "%s: no es va convertir la declaració de la funció \"%s\"\n"
+
+#: protoize.c:3053
+#, c-format
+msgid "%s: warning: too many parameter lists in declaration of `%s'\n"
+msgstr "%s: avís: massa llistes de paràmetres en la declaració de \"%s\"\n"
+
+#: protoize.c:3074
+#, c-format
+msgid ""
+"\n"
+"%s: warning: too few parameter lists in declaration of `%s'\n"
+msgstr ""
+"\n"
+"%s: avís: molt poques llistes de paràmetres en la declaració de \"%s\"\n"
+
+#: protoize.c:3170
+#, c-format
+msgid "%s: %d: warning: found `%s' but expected `%s'\n"
+msgstr "%s: %d: avís: es va trobar \"%s\" però s'esperava \"%s\"\n"
+
+#: protoize.c:3345
+#, c-format
+msgid "%s: local declaration for function `%s' not inserted\n"
+msgstr "%s: no es va inserir la declaració local per a la funció \"%s\"\n"
+
+#: protoize.c:3372
+#, c-format
+msgid ""
+"\n"
+"%s: %d: warning: can't add declaration of `%s' into macro call\n"
+msgstr ""
+"\n"
+"%s: %d: avís: no es pot afegir la declaració per a\"%s\" en la cridada de macro\n"
+
+#: protoize.c:3444
+#, c-format
+msgid "%s: global declarations for file `%s' not inserted\n"
+msgstr "%s: no es van inserir les declaracions globals per al fitxer \"%s\"\n"
+
+#: protoize.c:3533 protoize.c:3563
+#, c-format
+msgid "%s: definition of function `%s' not converted\n"
+msgstr "%s: no es va convertir la definició de la funció \"%s\"\n"
+
+#: protoize.c:3552
+#, c-format
+msgid "%s: %d: warning: definition of %s not converted\n"
+msgstr "%s: %d: avís: no es va convertir la definició de %s\n"
+
+#: protoize.c:3878
+#, c-format
+msgid "%s: found definition of `%s' at %s(%d)\n"
+msgstr "%s: es va trobar la definició de \"%s\" en %s(%d)\n"
+
+#. If we make it here, then we did not know about this
+#. function definition.
+#: protoize.c:3894
+#, c-format
+msgid "%s: %d: warning: `%s' excluded by preprocessing\n"
+msgstr "%s: %d: avís: \"%s\" va ser exclòs pel preprocessament\n"
+
+#: protoize.c:3897
+#, c-format
+msgid "%s: function definition not converted\n"
+msgstr "%s: no es va convertir la definició de la funció\n"
+
+#: protoize.c:3955
+#, c-format
+msgid "%s: `%s' not converted\n"
+msgstr "%s: no es va convertir \"%s\"\n"
+
+#: protoize.c:3963
+#, c-format
+msgid "%s: would convert file `%s'\n"
+msgstr "%s: es podria convertir el fitxer \"%s\"\n"
+
+#: protoize.c:3966
+#, c-format
+msgid "%s: converting file `%s'\n"
+msgstr "%s: convertint el fitxer \"%s\"\n"
+
+#: protoize.c:3976
+#, c-format
+msgid "%s: can't get status for file `%s': %s\n"
+msgstr "%s: no es pot obtenir l'estat del fitxer \"%s\": %s\n"
+
+#: protoize.c:4018
+#, c-format
+msgid "%s: can't open file `%s' for reading: %s\n"
+msgstr "%s: no es pot obrir el fitxer \"%s\" per a lectura: %s\n"
+
+#: protoize.c:4033
+#, c-format
+msgid ""
+"\n"
+"%s: error reading input file `%s': %s\n"
+msgstr ""
+"\n"
+"%s: error al llegint el fitxer d'entrada \"%s\": %s\n"
+
+#: protoize.c:4067
+#, c-format
+msgid "%s: can't create/open clean file `%s': %s\n"
+msgstr "%s: no es pot crear/obrir el fitxer net \"%s\": %s\n"
+
+#: protoize.c:4172
+#, c-format
+msgid "%s: warning: file `%s' already saved in `%s'\n"
+msgstr "%s: avís: el fitxer \"%s\" ja havia estat guardat en \"%s\"\n"
+
+#: protoize.c:4180
+#, c-format
+msgid "%s: can't link file `%s' to `%s': %s\n"
+msgstr "%s: no es pot enllaçar el fitxer \"%s\" a \"%s\": %s\n"
+
+#: protoize.c:4210
+#, c-format
+msgid "%s: can't create/open output file `%s': %s\n"
+msgstr "%s: no es pot crear/obrir el fitxer de sortida \"%s\": %s\n"
+
+#: protoize.c:4243
+#, c-format
+msgid "%s: can't change mode of file `%s': %s\n"
+msgstr "%s: no es pot canviar la manera del fitxer \"%s\": %s\n"
+
+#: protoize.c:4416
+#, c-format
+msgid "%s: cannot get working directory: %s\n"
+msgstr "%s: no es pot obtenir el directori de treball: %s\n"
+
+#: protoize.c:4514
+#, c-format
+msgid "%s: input file names must have .c suffixes: %s\n"
+msgstr "%s: els noms de fitxer d'entrada deuen tenir sufixos .c: %s\n"
+
+#: ra.c:750
+msgid "Didn't find a coloring.\n"
+msgstr ""
+
+#: reg-stack.c:665
+#, c-format
+msgid "output constraint %d must specify a single register"
+msgstr "la restricció de sortida %d deu especificar un sol registre"
+
+#: reg-stack.c:675
+#, c-format
+msgid "output constraint %d cannot be specified together with \"%s\" clobber"
+msgstr "la restricció de sortida %d no es pot especificar amb el clobber \"%s\""
+
+#: reg-stack.c:698
+msgid "output regs must be grouped at top of stack"
+msgstr "els registres de sortida deuen ser agrupats en la part superior de la pila"
+
+#: reg-stack.c:735
+msgid "implicitly popped regs must be grouped at top of stack"
+msgstr "els registres extrets implícitament deuen ser agrupats en la part superior de la pila"
+
+#: reg-stack.c:754
+#, c-format
+msgid "output operand %d must use `&' constraint"
+msgstr "l'operant de sortida %d deu usar la restricció \"&\""
+
+#: regclass.c:743
+#, c-format
+msgid "can't use '%s' as a %s register"
+msgstr "no es pot usar \"%s\" com un registre %s"
+
+#: regclass.c:758 config/ia64/ia64.c:4657 config/ia64/ia64.c:4664
+#, c-format
+msgid "unknown register name: %s"
+msgstr "nom de registre desconegut: %s"
+
+#: regclass.c:768
+msgid "global register variable follows a function definition"
+msgstr "la variable de registre global segueix a una definició de funció"
+
+#: regclass.c:772
+msgid "register used for two global register variables"
+msgstr "nom de registre usat per dues variables de registre globals"
+
+#: regclass.c:777
+msgid "call-clobbered register used for global register variable"
+msgstr "registre de cridada alterada usat per a una variable de registre global"
+
+#: regrename.c:1846
+#, c-format
+msgid "validate_value_data: [%u] Bad next_regno for empty chain (%u)"
+msgstr "validate_value_data: [%u] next_regno erroni per a la cadena buida (%u)"
+
+#: regrename.c:1858
+#, c-format
+msgid "validate_value_data: Loop in regno chain (%u)"
+msgstr "validate_value_data: Cicle en la cadena regno (%u)"
+
+#: regrename.c:1861
+#, c-format
+msgid "validate_value_data: [%u] Bad oldest_regno (%u)"
+msgstr "validate_value_data: [%u] oldest_regno erroni (%u)"
+
+#: regrename.c:1873
+#, c-format
+msgid "validate_value_data: [%u] Non-empty reg in chain (%s %u %i)"
+msgstr "validate_value_data: [%u] Registre no buit en la cadena (%s %u %i)"
+
+#: reload.c:1254
+msgid "cannot reload integer constant operand in `asm'"
+msgstr "no es pot recarregar operants constants enters en \"asm\""
+
+#: reload.c:1276
+msgid "impossible register constraint in `asm'"
+msgstr "restricció de registres impossible en \"asm\""
+
+#: reload.c:3504
+msgid "`&' constraint used with no register class"
+msgstr "es va usar la restricció \"&\" sense classe de registre"
+
+#: reload.c:3672
+msgid "unable to generate reloads for:"
+msgstr " no es poden generar recarregues per a:"
+
+#: reload.c:3673 reload.c:3887
+msgid "inconsistent operand constraints in an `asm'"
+msgstr "restriccions de operants inconsistents en un \"asm\""
+
+#: reload1.c:1212
+msgid "frame size too large for reliable stack checking"
+msgstr "la grandària del marc és massa gran per a una revisió fiable de la pila"
+
+#: reload1.c:1215
+msgid "try reducing the number of local variables"
+msgstr "intenti reduir el nombre de variables locals"
+
+#: reload1.c:1868
+#, c-format
+msgid "can't find a register in class `%s' while reloading `asm'"
+msgstr "no es pot trobar un registre en la classe \"%s\" mentre es recarrega \"asm\"."
+
+#: reload1.c:1872
+#, c-format
+msgid "unable to find a register to spill in class `%s'"
+msgstr "no es pot trobar un registre per a buidar la classe \"%s\"."
+
+#: reload1.c:1874
+msgid "this is the insn:"
+msgstr "això és el insn:"
+
+#: reload1.c:3871
+msgid "`asm' operand requires impossible reload"
+msgstr "l'operant \"asm\" requereix una recarrega impossible"
+
+#. It's the compiler's fault.
+#: reload1.c:4963
+msgid "could not find a spill register"
+msgstr "no es pot trobar un registre de buidat "
+
+#: reload1.c:4968
+msgid "`asm' operand constraint incompatible with operand size"
+msgstr "la restricció de l'operant \"asm\" és incompatible amb la grandària de l'operant"
+
+#. It's the compiler's fault.
+#: reload1.c:6590
+msgid "VOIDmode on an output"
+msgstr "VOIDmode en una sortida"
+
+#: reload1.c:6591
+msgid "output operand is constant in `asm'"
+msgstr "l'operant de sortida és constant en \"asm\""
+
+#: rtl-error.c:124
+msgid "unrecognizable insn:"
+msgstr "insn no recognoscible:"
+
+#: rtl-error.c:126
+msgid "insn does not satisfy its constraints:"
+msgstr "insn no satisfà les seves restriccions:"
+
+#: rtl.c:477
+#, c-format
+msgid "RTL check: access of elt %d of `%s' with last elt %d in %s, at %s:%d"
+msgstr "revisió RTL: accés de elt %d de \"%s\" amb l'últim elt %d en %s, en %s:%d"
+
+#: rtl.c:487
+#, c-format
+msgid "RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d"
+msgstr "revisió RTL: s'esperava el tipus elt %d \"%c\", es té \"%c\" (rtx %s) en %s, en %s:%d"
+
+#: rtl.c:497
+#, c-format
+msgid "RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d"
+msgstr "revisió RTL: s'esperava el tipus elt %d \"%c\" o \"%c\", es té \"%c\" (rtx %s) en %s, en %s:%d"
+
+#: rtl.c:506
+#, c-format
+msgid "RTL check: expected code `%s', have `%s' in %s, at %s:%d"
+msgstr "Revisió RTL: s'esperava el codi \"%s\", es té \"%s\" en %s, en %s:%d"
+
+#: rtl.c:516
+#, c-format
+msgid "RTL check: expected code `%s' or `%s', have `%s' in %s, at %s:%d"
+msgstr "Revisió RTL: s'esperava el codi \"%s\" o \"%s\", es té \"%s\" en %s, en %s:%d"
+
+#: rtl.c:527
+#, c-format
+msgid "RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d"
+msgstr "Revisió RTL: accés de elt %d de vector amb l'últim elt %d en %s, en %s:%d"
+
+#: rtl.c:538
+#, c-format
+msgid "RTL flag check: %s used with unexpected rtx code `%s' in %s, at %s:%d"
+msgstr "Revisió RTL: es va usar %s amb el codi rtx inesperat \"%s\" en %s, en %s:%d"
+
+#: stmt.c:750
+#, c-format
+msgid "jump to `%s' invalidly jumps into binding contour"
+msgstr "el salt a \"%s\" salta de forma invàlida a un contorn d'unió"
+
+#: stmt.c:977 stmt.c:3793
+#, fuzzy
+msgid "%Jlabel '%D' used before containing binding contour"
+msgstr "es va usar abans l'etiqueta \"%s\" que contenia un contorn d'unió"
+
+#: stmt.c:1156
+msgid "output operand constraint lacks `='"
+msgstr "la restricció d'operant de sortida manca de \"=\""
+
+#: stmt.c:1171
+#, c-format
+msgid "output constraint `%c' for operand %d is not at the beginning"
+msgstr "la restricció de sortida \"%c\" per a l'operant %d no està al principi"
+
+#: stmt.c:1193
+msgid "operand constraint contains incorrectly positioned '+' or '='"
+msgstr "la restricció d'operant conté \"+\" o \"=\" mal posicionat"
+
+#: stmt.c:1199 stmt.c:1301
+#, c-format
+msgid "`%%' constraint used with last operand"
+msgstr "restricció \"%%\" utilitzada amd l'últim operant"
+
+#: stmt.c:1218
+msgid "matching constraint not valid in output operand"
+msgstr "la restricció coincident no és vàlida en l'operant de sortida"
+
+#: stmt.c:1260
+#, fuzzy
+msgid "read-write constraint does not allow a register"
+msgstr "l'adreça de pre-increment no és un registre"
+
+#: stmt.c:1292
+#, c-format
+msgid "input operand constraint contains `%c'"
+msgstr "la restricció d'operant d'entrada conté \"%c\""
+
+#: stmt.c:1334
+msgid "matching constraint references invalid operand number"
+msgstr "la restricció de coincidència fa referència a un nombre d'operant no vàlid"
+
+#: stmt.c:1372
+#, c-format
+msgid "invalid punctuation `%c' in constraint"
+msgstr "puntuació invàlida \"%c\" en la restricció"
+
+#: stmt.c:1396
+#, fuzzy
+msgid "matching constraint does not allow a register"
+msgstr "la restricció coincident no és vàlida en l'operant de sortida"
+
+#: stmt.c:1424
+#, c-format
+msgid "asm-specifier for variable `%s' conflicts with asm clobber list"
+msgstr "els qualificadors asm per a la variable \"%s\" generen conflicte amb la lista d'agrupació asm"
+
+#: stmt.c:1514
+#, c-format
+msgid "unknown register name `%s' in `asm'"
+msgstr "nom de registre desconegut \"%s\" en \"asm\""
+
+#: stmt.c:1522
+#, fuzzy, c-format
+msgid "PIC register `%s' clobbered in `asm'"
+msgstr "nom de registre desconegut \"%s\" en \"asm\""
+
+#: stmt.c:1571
+#, c-format
+msgid "more than %d operands in `asm'"
+msgstr "més de %d operants en \"asm\""
+
+#: stmt.c:1633
+#, c-format
+msgid "output number %d not directly addressable"
+msgstr "el nombre de sortida %d no és directament dirrectionable"
+
+#: stmt.c:1711
+#, c-format
+msgid "asm operand %d probably doesn't match constraints"
+msgstr "l'operant asm %d probablement no coincideix amb les restriccions"
+
+#: stmt.c:1721
+#, c-format
+msgid "use of memory input without lvalue in asm operand %d is deprecated"
+msgstr ""
+
+#: stmt.c:1875
+msgid "asm clobber conflict with output operand"
+msgstr "l'agrupació asm causa conflictes amb l'operant de sortida"
+
+#: stmt.c:1880
+msgid "asm clobber conflict with input operand"
+msgstr "l'agrupació asm causa conflictes amb l'operant d'entrada"
+
+#: stmt.c:1914
+msgid "too many alternatives in `asm'"
+msgstr "massa alternatives en \"asm\""
+
+#: stmt.c:1926
+msgid "operand constraints for `asm' differ in number of alternatives"
+msgstr "les restriccions d'operants per a \"asm\" difereixen en el nombre d'alternatives"
+
+#: stmt.c:1978
+#, c-format
+msgid "duplicate asm operand name '%s'"
+msgstr "nom d'operant asm \"%s\" duplicat"
+
+#: stmt.c:2076
+msgid "missing close brace for named operand"
+msgstr "falta la clau final per a l'operant nomenat"
+
+#: stmt.c:2104
+#, c-format
+msgid "undefined named operand '%s'"
+msgstr "operant nomenat no definit \"%s\""
+
+#: stmt.c:2161
+msgid "%Hstatement with no effect"
+msgstr ""
+
+#: stmt.c:2317
+#, fuzzy
+msgid "%Hvalue computed is not used"
+msgstr "l'autòmat \"%s\" no s'utilitza"
+
+#: stmt.c:3733
+#, fuzzy
+msgid "%Junused variable '%D'"
+msgstr "variable \"%s\" sense ús"
+
+#: stmt.c:4508
+msgid "%Hunreachable code at beginning of %s"
+msgstr ""
+
+#: stmt.c:5136
+#, c-format
+msgid "enumeration value `%s' not handled in switch"
+msgstr "el valor d'enumeració \"%s\" no es maneja en un switch"
+
+#: stmt.c:5161 stmt.c:5181
+#, c-format
+msgid "case value `%ld' not in enumerated type"
+msgstr "el valor de casi \"%ld\" no és un tipus enumerat"
+
+#: stmt.c:5164 stmt.c:5184
+#, c-format
+msgid "case value `%ld' not in enumerated type `%s'"
+msgstr "el valor de casi \"%ld\" no és un tipus enumerat \"%s\""
+
+#: stmt.c:5401
+msgid "switch missing default case"
+msgstr "mancada el casi per defecte per a un switch"
+
+#: stor-layout.c:183
+msgid "type size can't be explicitly evaluated"
+msgstr "la grandària del tipus no pot ser avaluat explícitament"
+
+#: stor-layout.c:185
+msgid "variable-size type declared outside of any function"
+msgstr "tipus de grandària variable declarat fora de qualsevol funció"
+
+#: stor-layout.c:515
+#, fuzzy
+msgid "%Jsize of '%D' is %d bytes"
+msgstr "la grandària de \"%s\" és de %d octets"
+
+#: stor-layout.c:517
+#, fuzzy
+msgid "%Jsize of '%D' is larger than %d bytes"
+msgstr "la grandària de \"%s\" és major que %d octets"
+
+#: stor-layout.c:883
+#, fuzzy
+msgid "%Jpacked attribute causes inefficient alignment for '%D'"
+msgstr "l'atribut packed causa una alineació ineficient per a \"%s\""
+
+#: stor-layout.c:886
+#, fuzzy
+msgid "%Jpacked attribute is unnecessary for '%D'"
+msgstr "no és necessari l'atribut packed per a \"%s\""
+
+#: stor-layout.c:902
+#, fuzzy
+msgid "%Jpadding struct to align '%D'"
+msgstr "estructura de farcit per a alinear \"%s\""
+
+#: stor-layout.c:1245
+msgid "padding struct size to alignment boundary"
+msgstr "grandària de l'estructura de farcit per als límits d'alineació"
+
+#: stor-layout.c:1275
+#, c-format
+msgid "packed attribute causes inefficient alignment for `%s'"
+msgstr "l'atribut packed causa una alineació ineficient per a \"%s\""
+
+#: stor-layout.c:1277
+#, c-format
+msgid "packed attribute is unnecessary for `%s'"
+msgstr "no és necessari l'atribut packed per a \"%s\""
+
+#: stor-layout.c:1282
+msgid "packed attribute causes inefficient alignment"
+msgstr "l'atribut packed causa una alineació ineficient"
+
+#: stor-layout.c:1284
+msgid "packed attribute is unnecessary"
+msgstr "no és necessari l'atribut packed"
+
+#: targhooks.c:162
+msgid "__builtin_saveregs not supported by this target"
+msgstr "no es dona suport a _builtin_saveregs en aquest objectiu"
+
+#: timevar.c:314
+#, c-format
+msgid "cannot timevar_pop '%s' when top of timevars stack is '%s'"
+msgstr ""
+
+#: timevar.c:440
+msgid ""
+"\n"
+"Execution times (seconds)\n"
+msgstr ""
+"\n"
+"Temps d'execució (segons)\n"
+
+#. Print total time.
+#: timevar.c:490
+msgid " TOTAL :"
+msgstr " TOTAL :"
+
+#: timevar.c:513
+#, c-format
+msgid "time in %s: %ld.%06ld (%ld%%)\n"
+msgstr "temps en %s: %ld.%06ld (%ld%%)\n"
+
+#: tlink.c:377
+#, c-format
+msgid "collect: reading %s\n"
+msgstr "collect: llegint %s\n"
+
+#: tlink.c:478
+#, c-format
+msgid "collect: recompiling %s\n"
+msgstr "collect: recompilant %s\n"
+
+#: tlink.c:654
+#, c-format
+msgid "collect: tweaking %s in %s\n"
+msgstr "collect: alterant %s en %s\n"
+
+#: tlink.c:700
+msgid "collect: relinking\n"
+msgstr "collect: reenllaçant\n"
+
+#: tlink.c:709
+#, c-format
+msgid "ld returned %d exit status"
+msgstr "ld va retornar l'estat de sortida %d"
+
+#: toplev.c:1243
+#, c-format
+msgid "%s "
+msgstr "%s "
+
+#: toplev.c:1245
+#, c-format
+msgid " %s"
+msgstr " %s"
+
+#: toplev.c:1310
+#, fuzzy, c-format
+msgid "invalid option argument `%s'"
+msgstr "opció \"%s\" invàlida"
+
+#: toplev.c:1373
+#, c-format
+msgid "getting core file size maximum limit: %m"
+msgstr ""
+
+#: toplev.c:1376
+#, c-format
+msgid "setting core file size limit to maximum: %m"
+msgstr ""
+
+#: toplev.c:1695
+#, fuzzy
+msgid "%J'%F' used but never defined"
+msgstr "\"%s\" utilitzat però mai definit"
+
+#: toplev.c:1697
+#, fuzzy
+msgid "%J'%F' declared `static' but never defined"
+msgstr "\"%s\" declarat \"static\" però mai definit"
+
+#: toplev.c:1722
+#, fuzzy
+msgid "%J'%D' defined but not used"
+msgstr "\"%s\" definit però no utilitzat"
+
+#: toplev.c:1743 toplev.c:1760
+#, c-format
+msgid "`%s' is deprecated (declared at %s:%d)"
+msgstr "\"%s\" és depreciat (declarat a %s:%d)"
+
+#: toplev.c:1763
+#, c-format
+msgid "`%s' is deprecated"
+msgstr "\"%s\" és depreciat"
+
+#: toplev.c:1766
+#, c-format
+msgid "type is deprecated (declared at %s:%d)"
+msgstr "type és depreciat (declarat a %s:%d)"
+
+#: toplev.c:1769
+msgid "type is deprecated"
+msgstr "type és depreciat"
+
+#: toplev.c:1973
+#, c-format
+msgid "invalid register name `%s' for register variable"
+msgstr "el nom de registre \"%s\" no és vàlid per a variable de registre"
+
+#: toplev.c:3546
+msgid "branch target register load optimization is not intended to be run twice"
+msgstr ""
+
+#: toplev.c:3713
+msgid ""
+"\n"
+"Target specific options:\n"
+msgstr ""
+"\n"
+"Opcions específiques de l'objectiu:\n"
+
+#: toplev.c:3727 toplev.c:3746
+#, fuzzy, c-format
+msgid " -m%-23s [undocumented]\n"
+msgstr " -m%-23.23s [sense documentar]\n"
+
+#: toplev.c:3755
+msgid ""
+"\n"
+"There are undocumented target specific options as well.\n"
+msgstr ""
+"\n"
+"A més hi ha opcions específiques de l'objectiu sense documentar.\n"
+
+#: toplev.c:3757
+msgid " They exist, but they are not documented.\n"
+msgstr " Existeixen, però no estan documentades.\n"
+
+#: toplev.c:3812
+#, c-format
+msgid "unrecognized gcc debugging option: %c"
+msgstr "opció de depuració de gcc no reconeguda: %c"
+
+#: toplev.c:3874 config/rs6000/rs6000.c:907
+#, c-format
+msgid "invalid option `%s'"
+msgstr "opció \"%s\" invàlida"
+
+#: toplev.c:3889
+#, c-format
+msgid ""
+"%s%s%s version %s (%s)\n"
+"%s\tcompiled by GNU C version %s.\n"
+"%s%s%s version %s (%s) compiled by CC.\n"
+msgstr ""
+"%s%s%s versió %s (%s)\n"
+"%s\tcompilat amb GNU C versió %s.\n"
+"%s%s%s versió %s (%s) compilada per a CC.\n"
+
+#: toplev.c:3896
+#, c-format
+msgid "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n"
+msgstr ""
+
+#: toplev.c:3948
+msgid "options passed: "
+msgstr "opcions passades: "
+
+#: toplev.c:3977
+msgid "options enabled: "
+msgstr "options activades: "
+
+#: toplev.c:4035 java/jcf-write.c:3422
+#, fuzzy, c-format
+msgid "can't open %s for writing: %m"
+msgstr "no es pot obrir obrir %s per a escriptura"
+
+#: toplev.c:4118 config/sh/sh.c:6883
+msgid "created and used with different settings of -fpic"
+msgstr ""
+
+#: toplev.c:4120 config/sh/sh.c:6885
+msgid "created and used with different settings of -fpie"
+msgstr ""
+
+#: toplev.c:4171 config/sh/sh.c:6935
+#, c-format
+msgid "created and used with differing settings of `-m%s'"
+msgstr ""
+
+#: toplev.c:4174 config/sh/sh.c:6938
+msgid "out of memory"
+msgstr ""
+
+#: toplev.c:4355
+msgid "instruction scheduling not supported on this target machine"
+msgstr "no es dóna suport a la planificació d'instruccions en aquest objectiu"
+
+#: toplev.c:4359
+msgid "this target machine does not have delayed branches"
+msgstr "aquesta màquina objectiu no té ramificacions alentides"
+
+#: toplev.c:4373
+#, c-format
+msgid "-f%sleading-underscore not supported on this target machine"
+msgstr "no es dóna suport a -f%sleading-underscore en aquest objectiu"
+
+#: toplev.c:4422
+#, fuzzy, c-format
+msgid "target system does not support the \"%s\" debug format"
+msgstr "%s no té suport per al format \"%%%s%c\" %s"
+
+#: toplev.c:4439
+msgid "-ffunction-sections not supported for this target"
+msgstr "no es dóna suport a -ffunction-sections en aquest objectiu"
+
+#: toplev.c:4444
+msgid "-fdata-sections not supported for this target"
+msgstr "no es dóna suport a -fdata-sections en aquest objectiu"
+
+#: toplev.c:4451
+msgid "-ffunction-sections disabled; it makes profiling impossible"
+msgstr "-ffunction-sections desactivat; fa impossible l'anàlisi de perfil"
+
+#: toplev.c:4458
+msgid "-fprefetch-loop-arrays not supported for this target"
+msgstr "no es dóna suport a -fprefetch-loop-arrays en aquest objectiu"
+
+#: toplev.c:4464
+msgid "-fprefetch-loop-arrays not supported for this target (try -march switches)"
+msgstr "no es dóna suport a -fprefetch-loop-arrays en aquest objectiu (prova switches -march)"
+
+#: toplev.c:4473
+msgid "-fprefetch-loop-arrays is not supported with -Os"
+msgstr "no es dóna suport a -fprefetch-loop-arrays amb -Os"
+
+#: toplev.c:4479
+msgid "-ffunction-sections may affect debugging on some targets"
+msgstr "-ffunction-sections podria afectar la depuració en alguns objectius"
+
+#: toplev.c:4581
+#, fuzzy, c-format
+msgid "error writing to %s: %m"
+msgstr "error a l'escriure a %s"
+
+#: toplev.c:4583 java/jcf-parse.c:902 java/jcf-write.c:3429
+#, fuzzy, c-format
+msgid "error closing %s: %m"
+msgstr "error al tancar %s"
+
+#: tree-dump.c:692
+#, c-format
+msgid "could not open dump file `%s'"
+msgstr "no es pot obrir el fitxer de dump \"%s\""
+
+#: tree-dump.c:763
+#, fuzzy, c-format
+msgid "ignoring unknown option `%.*s' in `-fdump-%s'"
+msgstr "ignorant l'opció desconeguda \"%.*s\" dintre \"-f%s\""
+
+#: tree-inline.c:1016
+msgid "%Jfunction '%F' can never be inlined because it uses alloca (override using the always_inline attribute)"
+msgstr ""
+
+#: tree-inline.c:1029
+msgid "%Jfunction '%F' can never be inlined because it uses setjmp"
+msgstr ""
+
+#: tree-inline.c:1044
+msgid "%Jfunction '%F' can never be inlined because it uses variable argument lists"
+msgstr ""
+
+#: tree-inline.c:1060
+msgid "%Jfunction '%F' can never be inlined because it uses setjmp-longjmp exception handling"
+msgstr ""
+
+#: tree-inline.c:1078
+msgid "%Jfunction '%F' can never be inlined because it contains a nested function"
+msgstr ""
+
+#: tree-inline.c:1095
+msgid "%Jfunction '%F' can never be inlined because it contains a computed goto"
+msgstr ""
+
+#: tree-inline.c:1105
+msgid "%Jfunction '%F' can never be inlined because it contains a nonlocal goto"
+msgstr ""
+
+#: tree-inline.c:1128
+msgid "%Jfunction '%F' can never be inlined because it uses variable sized variables"
+msgstr ""
+
+#: tree-inline.c:1338 tree-inline.c:1345
+#, fuzzy
+msgid "%Jinlining failed in call to '%F': %s"
+msgstr "el \"inlining\" va fallar en la cridada a \"%s\""
+
+#: tree-optimize.c:190
+#, fuzzy
+msgid "%Jsize of return value of '%D' is %u bytes"
+msgstr "la grandària del valor de devolució de \"%s\" és de %u octets"
+
+#: tree-optimize.c:193
+#, fuzzy
+msgid "%Jsize of return value of '%D' is larger than %wd bytes"
+msgstr "la grandària del valor de devolució de \"%s\" és més gran que %d octets"
+
+#: tree.c:3800
+msgid "arrays of functions are not meaningful"
+msgstr "les matrius de funcions no tenen significat"
+
+#: tree.c:3855
+msgid "function return type cannot be function"
+msgstr "el tipus de devolució d'una funció no pot ser una funció"
+
+#: tree.c:4684
+msgid "invalid initializer for bit string"
+msgstr "assignador invàlid per a cadena de bits"
+
+#: tree.c:4736
+#, c-format
+msgid "tree check: expected %s, have %s in %s, at %s:%d"
+msgstr "revisió d'arbre: s'esperava %s, es té %s en %s, en %s:%d"
+
+#: tree.c:4749
+#, c-format
+msgid "tree check: expected class '%c', have '%c' (%s) in %s, at %s:%d"
+msgstr "revisió d'arbre: s'esperava classa \"%c\", es té \"%c\" (%s) en %s, en %s:%d"
+
+#: tree.c:4762
+#, c-format
+msgid "tree check: accessed elt %d of tree_vec with %d elts in %s, at %s:%d"
+msgstr "revisió d'arbre: accés de *elt %d de tree_vec amb %d elts en %s, en %s:%d"
+
+#: tree.c:4774
+#, fuzzy, c-format
+msgid "tree check: accessed operand %d of %s with %d operands in %s, at %s:%d"
+msgstr "revisió d'arbre: accés de *elt %d de tree_vec amb %d elts en %s, en %s:%d"
+
+#: varasm.c:434
+#, fuzzy
+msgid "%J%D causes a section type conflict"
+msgstr "%s causa un conflicte de tipus de secció"
+
+#: varasm.c:796
+#, fuzzy
+msgid "%Jregister name not specified for '%D'"
+msgstr "no s'especifica nom de registre per a \"%s\""
+
+#: varasm.c:798
+#, fuzzy
+msgid "%Jinvalid register name for '%D'"
+msgstr "nom de registre invàlid per a \"%s\""
+
+#: varasm.c:800
+#, fuzzy
+msgid "%Jdata type of '%D' isn't suitable for a register"
+msgstr "el tipus de dades de \"%s\" no és adequat per a un registre"
+
+#: varasm.c:803
+#, fuzzy
+msgid "%Jregister specified for '%D' isn't suitable for data type"
+msgstr "el registre especificat per \"%s\" no és adequat per al tipus de dades"
+
+#: varasm.c:813
+msgid "global register variable has initial value"
+msgstr "la variable de registre global té valor inicial"
+
+#: varasm.c:816
+msgid "volatile register variables don't work as you might wish"
+msgstr "les variables de registre volatile no funcionen com vostè volgués"
+
+#: varasm.c:848
+#, fuzzy
+msgid "%Jregister name given for non-register variable '%D'"
+msgstr "nom de registre donat per a una variable \"%s\" que no és registre"
+
+#: varasm.c:1380
+#, fuzzy
+msgid "%Jstorage size of `%D' isn't known"
+msgstr "no es coneix la grandària d'emmagatzematge de \"%D\""
+
+#: varasm.c:1434
+#, fuzzy
+msgid "%Jalignment of '%D' is greater than maximum object file alignment. Using %d"
+msgstr "l'alineació de \"%s\" és massa granda que l'alineació màxima del fitxer objecte. S'usa %d."
+
+#: varasm.c:1480
+msgid "thread-local COMMON data not implemented"
+msgstr ""
+
+#: varasm.c:1505
+#, fuzzy
+msgid "%Jrequested alignment for '%D' is greater than implemented alignment of %d"
+msgstr "l'alineació sol·licitada per a %s és massa granda que l'alineació implementada de %d"
+
+#: varasm.c:3789
+msgid "initializer for integer value is too complicated"
+msgstr "el assignador per a un valor enter és massa complicat"
+
+#: varasm.c:3794
+msgid "initializer for floating value is not a floating constant"
+msgstr "el assignador per a un valor de coma flotant no és una constant de coma flotant"
+
+#: varasm.c:3860
+msgid "unknown set constructor type"
+msgstr "conjunt de tipus constructor desconegut"
+
+#: varasm.c:4079
+#, c-format
+msgid "invalid initial value for member `%s'"
+msgstr "valor inicial invàlid per al membre \"%s\""
+
+#: varasm.c:4266 varasm.c:4310
+#, fuzzy
+msgid "%Jweak declaration of '%D' must precede definition"
+msgstr "la declaració feble de \"%s\" deu precedir a la definició"
+
+#: varasm.c:4274
+#, fuzzy
+msgid "%Jweak declaration of '%D' after first use results in unspecified behavior"
+msgstr "la declaració feble de \"%s\" després del primer ús resulta en una conducta no especificada"
+
+#: varasm.c:4308
+#, fuzzy
+msgid "%Jweak declaration of '%D' must be public"
+msgstr "la declaració feble de \"%s\" deu ser public"
+
+#: varasm.c:4317
+#, fuzzy
+msgid "%Jweak declaration of '%D' not supported"
+msgstr "no és dona suport a la declaració feble de \"%s\""
+
+#: varasm.c:4346 varasm.c:4436
+msgid "only weak aliases are supported in this configuration"
+msgstr "només els aliessis febles tenen suport en aquesta configuració"
+
+#: varasm.c:4439
+msgid "alias definitions not supported in this configuration; ignored"
+msgstr "les definicions d'alies no tenen suport en aquesta configuració; ignorades"
+
+#: varasm.c:4468
+msgid "visibility attribute not supported in this configuration; ignored"
+msgstr "els atributs de visibilitat no tenen suport en aquesta configuració; ignorats"
+
+#: varray.c:194
+#, c-format
+msgid "virtual array %s[%lu]: element %lu out of bounds in %s, at %s:%d"
+msgstr "matriu virtual %s[%lu]: l'element %lu està fora del límit en %s, en %s:%d"
+
+#: varray.c:204
+#, c-format
+msgid "underflowed virtual array %s in %s, at %s:%d"
+msgstr ""
+
+#. Print an error message for unrecognized stab codes.
+#: xcoffout.c:173
+#, c-format
+msgid "no sclass for %s stab (0x%x)\n"
+msgstr "no hi ha sclass per al stab %s (0x%x)\n"
+
+#.
+#. Local variables:
+#. mode:c
+#. End:
+#.
+#: diagnostic.def:1
+#, fuzzy
+msgid "fatal error: "
+msgstr "error intern: "
+
+#: diagnostic.def:2
+#, fuzzy
+msgid "internal compiler error: "
+msgstr "error intern: "
+
+#: diagnostic.def:3
+#, fuzzy
+msgid "error: "
+msgstr "error intern: "
+
+#: diagnostic.def:4
+#, fuzzy
+msgid "sorry, unimplemented: "
+msgstr "disculpi, no s'ha implementat: #pragma noalign NAME"
+
+#: diagnostic.def:6
+msgid "anachronism: "
+msgstr ""
+
+#: diagnostic.def:7
+#, fuzzy
+msgid "note: "
+msgstr "nota:"
+
+#: diagnostic.def:8
+msgid "debug: "
+msgstr ""
+
+#: params.def:53
+msgid "The maximum number of instructions in a single function eligible for inlining"
+msgstr "El nombre màxim d'instruccions en una sola funció elegible per a inlining"
+
+#: params.def:65
+msgid "The maximum number of instructions when automatically inlining"
+msgstr "El nombre màxim d'instruccions quan es fa inlining automàticament"
+
+#: params.def:75
+msgid "The maximum number of instructions for the RTL inliner"
+msgstr "El nombre màxim d'instruccions per al inliner de RTL"
+
+#: params.def:86
+msgid "The maximum number of instructions to consider to fill a delay slot"
+msgstr "El nombre màxim d'instruccions per a considerar l'omplert d'una ranura de retard"
+
+#: params.def:97
+msgid "The maximum number of instructions to consider to find accurate live register information"
+msgstr "El nombre màxim d'instruccions per a considerar la recerca d'informació de registres en viu exacta"
+
+#: params.def:107
+msgid "The maximum length of scheduling's pending operations list"
+msgstr "La longitud màxima de la llista d'operacions pendents del planificador de tasques"
+
+#: params.def:112
+msgid "The size of function body to be considered large"
+msgstr ""
+
+#: params.def:116
+msgid "Maximal growth due to inlining of large function (in percent)"
+msgstr ""
+
+#: params.def:120
+msgid "how much can given compilation unit grow because of the inlining (in percent)"
+msgstr ""
+
+#: params.def:127
+msgid "The maximum amount of memory to be allocated by GCSE"
+msgstr "La quantitat màxima de memòria a ser assignada per GCSE"
+
+#: params.def:132
+msgid "The maximum number of passes to make when doing GCSE"
+msgstr "El nombre màxim de passos a realitzar quan es fa GCSE"
+
+#: params.def:144
+msgid "The maximum number of instructions to consider to unroll in a loop"
+msgstr "El nombre màxim d'instruccions per a considerar el desenrotllo en un cicle"
+
+#: params.def:150
+#, fuzzy
+msgid "The maximum number of instructions to consider to unroll in a loop on average"
+msgstr "El nombre màxim d'instruccions per a considerar el desenrotllo en un cicle"
+
+#: params.def:155
+#, fuzzy
+msgid "The maximum number of unrollings of a single loop"
+msgstr "El nombre màxim d'instruccions per al inliner de RTL"
+
+#: params.def:160
+#, fuzzy
+msgid "The maximum number of insns of a peeled loop"
+msgstr "El nombre màxim d'instruccions per a considerar l'omplert d'una ranura de retard"
+
+#: params.def:165
+#, fuzzy
+msgid "The maximum number of peelings of a single loop"
+msgstr "El nombre màxim de passos a realitzar quan es fa GCSE"
+
+#: params.def:170
+#, fuzzy
+msgid "The maximum number of insns of a completely peeled loop"
+msgstr "El nombre màxim d'instruccions per a considerar el desenrotllo en un cicle"
+
+#: params.def:175
+#, fuzzy
+msgid "The maximum number of peelings of a single loop that is peeled completely"
+msgstr "El nombre màxim d'instruccions en una sola funció elegible per a inlining"
+
+#: params.def:180
+#, fuzzy
+msgid "The maximum number of insns of a peeled loop that rolls only once"
+msgstr "El nombre màxim d'instruccions per al inliner de RTL"
+
+#: params.def:186
+#, fuzzy
+msgid "The maximum number of insns of an unswitched loop"
+msgstr "El nombre màxim d'instruccions per a considerar el desenrotllo en un cicle"
+
+#: params.def:191
+#, fuzzy
+msgid "The maximum number of unswitchings in a single loop"
+msgstr "El nombre màxim d'instruccions en una sola funció elegible per a inlining"
+
+#: params.def:196
+msgid "Select fraction of the maximal count of repetitions of basic block in program given basic block needs to have to be considered hot"
+msgstr ""
+
+#: params.def:201
+msgid "Select fraction of the maximal frequency of executions of basic block in function given basic block needs to have to be considered hot"
+msgstr ""
+
+#: params.def:206
+msgid "The percentage of function, weighted by execution frequency, that must be covered by trace formation. Used when profile feedback is available"
+msgstr ""
+
+#: params.def:211
+msgid "The percentage of function, weighted by execution frequency, that must be covered by trace formation. Used when profile feedback is not available"
+msgstr ""
+
+#: params.def:216
+msgid "Maximal code growth caused by tail duplication (in percent)"
+msgstr ""
+
+#: params.def:220
+msgid "Stop reverse growth if the reverse probability of best edge is less than this threshold (in percent)"
+msgstr ""
+
+#: params.def:225
+msgid "Stop forward growth if the probability of best edge is less than this threshold (in percent). Used when profile feedback is available"
+msgstr ""
+
+#: params.def:230
+msgid "Stop forward growth if the probability of best edge is less than this threshold (in percent). Used when profile feedback is not available"
+msgstr ""
+
+#: params.def:237
+msgid "The maximum number of incoming edges to consider for crossjumping"
+msgstr "El nombre màxim de vores d'entrada per a considerar el salt creuat"
+
+#: params.def:243
+#, fuzzy
+msgid "The maximum length of path considered in cse"
+msgstr "La longitud màxima de la llista d'operacions pendents del planificador de tasques"
+
+#: params.def:248
+#, fuzzy
+msgid "The maximum memory locations recorded by cselib"
+msgstr "El nombre màxim d'instruccions per al inliner de RTL"
+
+#: params.def:261
+msgid "Minimum heap expansion to trigger garbage collection, as a percentage of the total size of the heap"
+msgstr ""
+
+#: params.def:267
+msgid "Minimum heap size before we start collecting garbage, in kilobytes"
+msgstr ""
+
+#: params.def:275
+#, fuzzy
+msgid "The maximum number of instructions to search backward when looking for equivalent reload"
+msgstr "El nombre màxim d'instruccions per a considerar el desenrotllo en un cicle"
+
+#: config/darwin-c.c:75
+msgid "too many #pragma options align=reset"
+msgstr "massa opcions #pragma align=reset"
+
+#: config/darwin-c.c:95 config/darwin-c.c:98 config/darwin-c.c:100
+#: config/darwin-c.c:102
+msgid "malformed '#pragma options', ignoring"
+msgstr "\"#pragma opcions\" malformat, ignorant"
+
+#: config/darwin-c.c:105
+msgid "junk at end of '#pragma options'"
+msgstr "escombraries al final de \"#pragma opcions\""
+
+#: config/darwin-c.c:115
+msgid "malformed '#pragma options align={mac68k|power|reset}', ignoring"
+msgstr "\"#pragma opcions align={mac68k|power|reset}\" malformat, ignorant"
+
+#: config/darwin-c.c:127
+msgid "missing '(' after '#pragma unused', ignoring"
+msgstr "\"(\" faltant després de '#pragma unused', ignorant"
+
+#: config/darwin-c.c:145
+msgid "missing ')' after '#pragma unused', ignoring"
+msgstr "\")\" faltant després de '#pragma unused', ignorant"
+
+#: config/darwin-c.c:148
+msgid "junk at end of '#pragma unused'"
+msgstr "escombraries al final de \"#pragma unused\""
+
+#: config/darwin.c:1347
+#, fuzzy
+msgid "internal and protected visibility attributes not supportedin this configuration; ignored"
+msgstr "els atributs de visibilitat no tenen suport en aquesta configuració; ignorats"
+
+#: config/lynx-ng.h:97 config/lynx.h:116 config/rs6000/lynx.h:73
+msgid "-msystem-v and -p are incompatible"
+msgstr "-msystem-v i -p són incompatibles"
+
+#: config/lynx-ng.h:99 config/lynx.h:118 config/rs6000/lynx.h:75
+msgid "-msystem-v and -mthreads are incompatible"
+msgstr "-msystem-v i -mthreads són incompatibles"
+
+#: config/windiss.h:37
+#, fuzzy
+msgid "profiler support for WindISS"
+msgstr "suport per a function_profiler per a MMIX"
+
+#: config/alpha/alpha.c:231
+#, c-format
+msgid "-f%s ignored for Unicos/Mk (not supported)"
+msgstr "s'ignora -f%s per a Unicos/Mk (no és dona suport)"
+
+#: config/alpha/alpha.c:255
+msgid "-mieee not supported on Unicos/Mk"
+msgstr "no és dona suport a -mieee en Unicos/Mk"
+
+#: config/alpha/alpha.c:266
+msgid "-mieee-with-inexact not supported on Unicos/Mk"
+msgstr "no és dona suport a -mieee-with-inexact en Unicos/Mk"
+
+#: config/alpha/alpha.c:283
+#, c-format
+msgid "bad value `%s' for -mtrap-precision switch"
+msgstr "valor erroni \"%s\" per a l'interruptor -mtrap-precision"
+
+#: config/alpha/alpha.c:297
+#, c-format
+msgid "bad value `%s' for -mfp-rounding-mode switch"
+msgstr "valor erroni \"%s\" per a l'interruptor -mfp-rounding-mode"
+
+#: config/alpha/alpha.c:312
+#, c-format
+msgid "bad value `%s' for -mfp-trap-mode switch"
+msgstr "valor erroni \"%s\" per a l'interruptor -mfp-trap-mode"
+
+#: config/alpha/alpha.c:324 config/rs6000/rs6000.c:1070
+#, c-format
+msgid "bad value `%s' for -mtls-size switch"
+msgstr "valor erroni \"%s\" per a l'interruptor -mtls-size"
+
+#: config/alpha/alpha.c:343 config/alpha/alpha.c:355
+#, c-format
+msgid "bad value `%s' for -mcpu switch"
+msgstr "valor erroni \"%s\" per a l'interruptor -mcpu"
+
+#: config/alpha/alpha.c:362
+msgid "trap mode not supported on Unicos/Mk"
+msgstr "no és dona suport al mode trap en Unicos/Mk"
+
+#: config/alpha/alpha.c:369
+msgid "fp software completion requires -mtrap-precision=i"
+msgstr "el completat per programari de fp requereix una opció -mtrap-precision=i"
+
+#: config/alpha/alpha.c:385
+msgid "rounding mode not supported for VAX floats"
+msgstr "la manera d'arrodoniment no té suport per a floats de VAX"
+
+#: config/alpha/alpha.c:390
+msgid "trap mode not supported for VAX floats"
+msgstr "la manera de captura no té suport per a valors de coma flotant VAX"
+
+#: config/alpha/alpha.c:394
+#, fuzzy
+msgid "128-bit long double not supported for VAX floats"
+msgstr "la manera de captura no té suport per a valors de coma flotant VAX"
+
+#: config/alpha/alpha.c:422
+#, c-format
+msgid "L%d cache latency unknown for %s"
+msgstr "latència de cau L%d desconeguda per a %s"
+
+#: config/alpha/alpha.c:437
+#, c-format
+msgid "bad value `%s' for -mmemory-latency"
+msgstr "valor erroni \"%s\" per a -mmemory-latency"
+
+#: config/alpha/alpha.c:5425
+#, c-format
+msgid "invalid %%H value"
+msgstr "valor %%H invàlid"
+
+#: config/alpha/alpha.c:5446
+#, c-format
+msgid "invalid %%J value"
+msgstr "valor %%J invàlid"
+
+#: config/alpha/alpha.c:5462 config/ia64/ia64.c:4260
+#, c-format
+msgid "invalid %%r value"
+msgstr "valor %%r invàlid"
+
+#: config/alpha/alpha.c:5472 config/rs6000/rs6000.c:9012
+#: config/xtensa/xtensa.c:2013
+#, c-format
+msgid "invalid %%R value"
+msgstr "valor %%R invàlid"
+
+#: config/alpha/alpha.c:5478 config/rs6000/rs6000.c:8931
+#: config/xtensa/xtensa.c:1980
+#, c-format
+msgid "invalid %%N value"
+msgstr "valor %%N invàlid"
+
+#: config/alpha/alpha.c:5486 config/rs6000/rs6000.c:8959
+#, c-format
+msgid "invalid %%P value"
+msgstr "valor %%P invàlid"
+
+#: config/alpha/alpha.c:5494
+#, c-format
+msgid "invalid %%h value"
+msgstr "valor %%h invalíd"
+
+#: config/alpha/alpha.c:5502 config/xtensa/xtensa.c:2006
+#, c-format
+msgid "invalid %%L value"
+msgstr "valor %%L invàlid"
+
+#: config/alpha/alpha.c:5541 config/rs6000/rs6000.c:8913
+#, c-format
+msgid "invalid %%m value"
+msgstr "valor %%m invàlid"
+
+#: config/alpha/alpha.c:5549 config/rs6000/rs6000.c:8921
+#, c-format
+msgid "invalid %%M value"
+msgstr "valor %%M invàlid"
+
+#: config/alpha/alpha.c:5593
+#, c-format
+msgid "invalid %%U value"
+msgstr "valor %%U invalíd"
+
+#: config/alpha/alpha.c:5605 config/alpha/alpha.c:5619
+#: config/rs6000/rs6000.c:9020
+#, c-format
+msgid "invalid %%s value"
+msgstr "valor %%s invalíd"
+
+#: config/alpha/alpha.c:5642
+#, c-format
+msgid "invalid %%C value"
+msgstr "valor %%C invàlid"
+
+#: config/alpha/alpha.c:5679 config/rs6000/rs6000.c:8770
+#, c-format
+msgid "invalid %%E value"
+msgstr "valor %%E invalíd"
+
+#: config/alpha/alpha.c:5704 config/alpha/alpha.c:5752
+msgid "unknown relocation unspec"
+msgstr "reubicació unspec desconeguda"
+
+#: config/alpha/alpha.c:5713 config/rs6000/rs6000.c:9333
+#, c-format
+msgid "invalid %%xn code"
+msgstr "codi %%xn invalíd"
+
+#: config/alpha/alpha.c:6657 config/alpha/alpha.c:6660 config/s390/s390.c:6575
+#: config/s390/s390.c:6578
+msgid "bad builtin fcode"
+msgstr ""
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/alpha/alpha.h:293 config/i386/i386.h:327 config/i386/i386.h:329
+#: config/i386/i386.h:331 config/ns32k/ns32k.h:140 config/s390/s390.h:124
+#: config/sparc/sparc.h:543 config/sparc/sparc.h:548
+msgid "Use hardware fp"
+msgstr "Usar fp de maquinari"
+
+#: config/alpha/alpha.h:294 config/i386/i386.h:328 config/i386/i386.h:330
+#: config/sparc/sparc.h:545 config/sparc/sparc.h:550
+msgid "Do not use hardware fp"
+msgstr "No usar fp de maquinari"
+
+#: config/alpha/alpha.h:295
+msgid "Use fp registers"
+msgstr "Usar registres fp"
+
+#: config/alpha/alpha.h:297
+msgid "Do not use fp registers"
+msgstr "No usar registres fp"
+
+#: config/alpha/alpha.h:298
+msgid "Do not assume GAS"
+msgstr "No assumir GAS"
+
+#: config/alpha/alpha.h:299
+msgid "Assume GAS"
+msgstr "Assumir GAS"
+
+#: config/alpha/alpha.h:301
+msgid "Request IEEE-conformant math library routines (OSF/1)"
+msgstr "Requerir rutines de biblioteca matemàtica que compleixin amb IEEE (OSF/1)"
+
+#: config/alpha/alpha.h:303
+msgid "Emit IEEE-conformant code, without inexact exceptions"
+msgstr "Emetre codi que compleixi amb IEEE, sense excepcionsinexactes"
+
+#: config/alpha/alpha.h:305
+msgid "Emit IEEE-conformant code, with inexact exceptions"
+msgstr "Emetre codi que compleixi amb IEEE, amb excepcions inexactes"
+
+#: config/alpha/alpha.h:307
+msgid "Do not emit complex integer constants to read-only memory"
+msgstr "No emetre constants enteres complexes a memòria de només lectura"
+
+#: config/alpha/alpha.h:308
+msgid "Use VAX fp"
+msgstr "Usar fp VAX"
+
+#: config/alpha/alpha.h:309
+msgid "Do not use VAX fp"
+msgstr "No usar fp VAX"
+
+#: config/alpha/alpha.h:310
+msgid "Emit code for the byte/word ISA extension"
+msgstr "Emetre codi per a l'extensió ISA octet/word"
+
+#: config/alpha/alpha.h:313
+msgid "Emit code for the motion video ISA extension"
+msgstr "Emetre codi per a l'extensió ISA de vídeo en moviment"
+
+#: config/alpha/alpha.h:316
+msgid "Emit code for the fp move and sqrt ISA extension"
+msgstr "Emetre codi per a l'extensió ISA de move i sqrt de fp"
+
+#: config/alpha/alpha.h:318
+msgid "Emit code for the counting ISA extension"
+msgstr "Emetre codi per a l'extensió ISA de compte"
+
+#: config/alpha/alpha.h:321
+msgid "Emit code using explicit relocation directives"
+msgstr "Emetre codi utilitzant directives explícites de reassignació"
+
+#: config/alpha/alpha.h:324
+msgid "Emit 16-bit relocations to the small data areas"
+msgstr "Emetre reassignació de 16 bits per a las àreas de dades petites"
+
+#: config/alpha/alpha.h:326
+msgid "Emit 32-bit relocations to the small data areas"
+msgstr "Emetre reassignació de 32 bits per a las àreas de dades petites"
+
+#: config/alpha/alpha.h:328
+#, fuzzy
+msgid "Emit direct branches to local functions"
+msgstr "Ometre el marc de referència per a les funcions fulles"
+
+#: config/alpha/alpha.h:331
+msgid "Emit rdval instead of rduniq for thread pointer"
+msgstr ""
+
+#: config/alpha/alpha.h:333
+#, fuzzy
+msgid "Use 128-bit long double"
+msgstr "Usar long doubles de 128 bits"
+
+#: config/alpha/alpha.h:335
+#, fuzzy
+msgid "Use 64-bit long double"
+msgstr "Usar long doubles de 64 bit"
+
+#. For -mcpu=
+#. For -mtune=
+#. For -mfp-rounding-mode=[n|m|c|d]
+#. For -mfp-trap-mode=[n|u|su|sui]
+#. For -mtrap-precision=[p|f|i]
+#. For -mmemory-latency=
+#. For -mtls-size=
+#: config/alpha/alpha.h:364
+msgid "Use features of and schedule given CPU"
+msgstr "Usar les característiques d'el i el planificador del CPU donat"
+
+#: config/alpha/alpha.h:366
+msgid "Schedule given CPU"
+msgstr "planificat per al CPU donat"
+
+#: config/alpha/alpha.h:368
+msgid "Control the generated fp rounding mode"
+msgstr "Controlar la manera d'arrodoniment generat de fp"
+
+#: config/alpha/alpha.h:370
+msgid "Control the IEEE trap mode"
+msgstr "Controlar la manera de captura IEEE"
+
+#: config/alpha/alpha.h:372
+msgid "Control the precision given to fp exceptions"
+msgstr "Controlar la precisió donada a les excepcions de fp"
+
+#: config/alpha/alpha.h:374
+msgid "Tune expected memory latency"
+msgstr "Ajustar la latència esperada de memòria"
+
+#: config/alpha/alpha.h:376 config/ia64/ia64.h:267 config/rs6000/sysv4.h:90
+msgid "Specify bit size of immediate TLS offsets"
+msgstr ""
+
+#: config/arc/arc.c:147
+#, c-format
+msgid "bad value (%s) for -mcpu switch"
+msgstr "valor erroni (%s) per a l'interruptor -mcpu"
+
+#: config/arc/arc.c:369
+#, c-format
+msgid "argument of `%s' attribute is not a string constant"
+msgstr "l'argument de l'atribut \"%s\" no és una cadena constant"
+
+#: config/arc/arc.c:376
+#, c-format
+msgid "argument of `%s' attribute is not \"ilink1\" or \"ilink2\""
+msgstr "l'argument de l'atribut \"%s\" no és \"ilink1\" o \"ilink2\""
+
+#: config/arc/arc.c:1714 config/m32r/m32r.c:2325
+#, c-format
+msgid "invalid operand to %%R code"
+msgstr "operant invàlid per al codi %%R"
+
+#: config/arc/arc.c:1746 config/m32r/m32r.c:2348
+#, c-format
+msgid "invalid operand to %%H/%%L code"
+msgstr "operant invàlid per al codi %%H/%%L"
+
+#: config/arc/arc.c:1769 config/m32r/m32r.c:2419
+#, c-format
+msgid "invalid operand to %%U code"
+msgstr "operant invàlid per al codi %%U"
+
+#: config/arc/arc.c:1780
+#, c-format
+msgid "invalid operand to %%V code"
+msgstr "operant invàlid per al codi %%V"
+
+#. Unknown flag.
+#: config/arc/arc.c:1787 config/m32r/m32r.c:2446 config/sparc/sparc.c:6985
+msgid "invalid operand output code"
+msgstr "operant invàlid per al codi de sortida"
+
+#: config/arm/arm.c:520
+#, c-format
+msgid "switch -mcpu=%s conflicts with -march= switch"
+msgstr "l'interruptor -mcpu=%s genera conflictes amb el switch -march="
+
+#: config/arm/arm.c:530 config/rs6000/rs6000.c:760 config/sparc/sparc.c:424
+#, c-format
+msgid "bad value (%s) for %s switch"
+msgstr "valor erroni (%s) per a l'interruptor %s"
+
+#: config/arm/arm.c:672
+msgid "target CPU does not support APCS-32"
+msgstr "el CPU objectiu no té suport per a APCS-32"
+
+#: config/arm/arm.c:677
+msgid "target CPU does not support APCS-26"
+msgstr "el CPU objectiu no té suport per a APCS-26"
+
+#: config/arm/arm.c:683
+msgid "target CPU does not support interworking"
+msgstr "el CPU objectiu no té suport per a treball intern"
+
+#: config/arm/arm.c:689
+msgid "target CPU does not support THUMB instructions"
+msgstr "el CPU objectiu no té suport les instruccions THUMB"
+
+#: config/arm/arm.c:694
+msgid "future releases of GCC will not support -mapcs-26"
+msgstr ""
+
+#: config/arm/arm.c:706
+msgid "enabling backtrace support is only meaningful when compiling for the Thumb"
+msgstr "habilitar el suport de rastrejo cap a endarrere només té significat quan es compila per al Thumb"
+
+#: config/arm/arm.c:709
+msgid "enabling callee interworking support is only meaningful when compiling for the Thumb"
+msgstr "habilitar el suport de treball intern de cridades només té significat quan es compila per al Thumb"
+
+#: config/arm/arm.c:712
+msgid "enabling caller interworking support is only meaningful when compiling for the Thumb"
+msgstr "habilitar el suport de treball intern de cridat només té significat quan es compila per al Thumb"
+
+#: config/arm/arm.c:718
+msgid "interworking forces APCS-32 to be used"
+msgstr "el treball intern força l'ús de APCS-32"
+
+#: config/arm/arm.c:724
+msgid "-mapcs-stack-check incompatible with -mno-apcs-frame"
+msgstr "-mapcs-stack-check és incompatible amb -mno-apcs-frame"
+
+#: config/arm/arm.c:732
+msgid "-fpic and -mapcs-reent are incompatible"
+msgstr "-fpic i -mapcs-reent són incompatibles"
+
+#: config/arm/arm.c:735
+msgid "APCS reentrant code not supported. Ignored"
+msgstr "no se suporta el codi APCS que es torna a introduir.Ignorat"
+
+#: config/arm/arm.c:743
+msgid "-g with -mno-apcs-frame may not give sensible debugging"
+msgstr "-g amb -mno-apcs-frame no permet una depuració sensible"
+
+#: config/arm/arm.c:751
+msgid "passing floating point arguments in fp regs not yet supported"
+msgstr "encara no se suporta passar arguments de nombre de coma flotant en registres fp"
+
+#: config/arm/arm.c:795
+#, c-format
+msgid "invalid floating point emulation option: -mfpe-%s"
+msgstr "opció d'emulació de coma flotant invàlida: -mfpe-%s"
+
+#: config/arm/arm.c:806
+msgid "-mfpe switch not supported by ep9312 target cpu - ignored."
+msgstr ""
+
+#: config/arm/arm.c:826
+msgid "structure size boundary can only be set to 8 or 32"
+msgstr "El límit de la grandària de l'estructura només pot establir-se a 8 o 32"
+
+#: config/arm/arm.c:834
+msgid "-mpic-register= is useless without -fpic"
+msgstr "-mpic-register= és inútil sense -fpic"
+
+#: config/arm/arm.c:841
+#, c-format
+msgid "unable to use '%s' for PIC register"
+msgstr "no es pot usar \"%s\" per a registre PIC"
+
+#: config/arm/arm.c:2249 config/arm/arm.c:2267 config/avr/avr.c:4558
+#: config/c4x/c4x.c:4447 config/h8300/h8300.c:4260 config/i386/i386.c:1580
+#: config/i386/i386.c:1626 config/ip2k/ip2k.c:3169
+#: config/m68hc11/m68hc11.c:1293 config/m68k/m68k.c:345
+#: config/mcore/mcore.c:3375 config/ns32k/ns32k.c:1064
+#: config/rs6000/rs6000.c:14624 config/sh/sh.c:6737 config/sh/sh.c:6758
+#: config/sh/sh.c:6793 config/stormy16/stormy16.c:2073 config/v850/v850.c:2173
+#, c-format
+msgid "`%s' attribute only applies to functions"
+msgstr "l'atribut \"%s\" nomès s'aplica a funcions"
+
+#: config/arm/arm.c:10576
+msgid "unable to compute real location of stacked parameter"
+msgstr "no es pot calcular la ubicació real del paràmetre apilat"
+
+#. @@@ better error message
+#: config/arm/arm.c:11204 config/arm/arm.c:11241
+msgid "selector must be an immediate"
+msgstr "el se-lector deu ser un immediat"
+
+#. @@@ better error message
+#: config/arm/arm.c:11284 config/i386/i386.c:14300 config/i386/i386.c:14334
+msgid "mask must be an immediate"
+msgstr "la màscara deu ser un immediat"
+
+#: config/arm/arm.c:11979
+msgid "no low registers available for popping high registers"
+msgstr "no hi ha registres inferiors disponibles per a emmagatzemar registres superiors"
+
+#: config/arm/arm.c:12229
+msgid "interrupt Service Routines cannot be coded in Thumb mode"
+msgstr "no es poden codificar les Rutines de Serveis d'Interrupció en la manera Thumb"
+
+#: config/arm/pe.c:170 config/mcore/mcore.c:3241
+#, fuzzy
+msgid "%Jinitialized variable '%D' is marked dllimport"
+msgstr "la variable iniciada \"%s\" està marcada com dllimport"
+
+#: config/arm/pe.c:179
+#, fuzzy
+msgid "%Jstatic variable '%D' is marked dllimport"
+msgstr "la variable estàtica \"%s\" està marcada com dllimport"
+
+#: config/arm/arm.h:451
+msgid "Generate APCS conformant stack frames"
+msgstr "Generar marcs de pila que compleixin amb APCS"
+
+#: config/arm/arm.h:454
+msgid "Store function names in object code"
+msgstr "Emmagatzemar noms de funció en el codi objecte"
+
+#: config/arm/arm.h:458
+msgid "Use the 32-bit version of the APCS"
+msgstr "Usar la versió 32-bit del APCS"
+
+#: config/arm/arm.h:463
+msgid "Pass FP arguments in FP registers"
+msgstr "Passar els arguments FP en els registres FP"
+
+#: config/arm/arm.h:466
+msgid "Generate re-entrant, PIC code"
+msgstr "Generar codi PIC que es torna a introduir"
+
+#: config/arm/arm.h:469
+msgid "The MMU will trap on unaligned accesses"
+msgstr "La MMU atraparà els accessos no alineats"
+
+#: config/arm/arm.h:472
+msgid "Use library calls to perform FP operations"
+msgstr "Usar cridades a biblioteques per a realitzar les operacions de FP"
+
+#: config/arm/arm.h:474 config/i960/i960.h:291
+msgid "Use hardware floating point instructions"
+msgstr "Usar instruccions de maquinari per a coma flotant"
+
+#: config/arm/arm.h:476
+msgid "Assume target CPU is configured as big endian"
+msgstr "Assumir que el CPU destinació està configurat com big endian"
+
+#: config/arm/arm.h:478
+msgid "Assume target CPU is configured as little endian"
+msgstr "Assumir que el CPU destinació està configurat com little endian"
+
+#: config/arm/arm.h:480
+msgid "Assume big endian bytes, little endian words"
+msgstr "Assumir octets big endian ,mots little endian"
+
+#: config/arm/arm.h:482
+msgid "Support calls between Thumb and ARM instruction sets"
+msgstr "Suport a cridades entre els conjunts d'instruccions Thumb i ARM"
+
+#: config/arm/arm.h:485
+msgid "Generate a call to abort if a noreturn function returns"
+msgstr "Generar una cridada a avortar si una funció noreturnretorna"
+
+#: config/arm/arm.h:488
+msgid "Do not move instructions into a function's prologue"
+msgstr "No moure les instruccions al pròleg d'una funció"
+
+#: config/arm/arm.h:491
+msgid "Do not load the PIC register in function prologues"
+msgstr "No carregar el registre PIC en els pròlegs de funció"
+
+#: config/arm/arm.h:494
+msgid "Generate call insns as indirect calls, if necessary"
+msgstr "Generar les cridades insns com cridades indirectes, si és necessari"
+
+#: config/arm/arm.h:497
+msgid "Compile for the Thumb not the ARM"
+msgstr "Compilar per al Thumb on per al ARM"
+
+#: config/arm/arm.h:501
+msgid "Thumb: Generate (non-leaf) stack frames even if not needed"
+msgstr "Thumb: Generar marcs de pila (no-fulles) encara si no és necessari"
+
+#: config/arm/arm.h:504
+msgid "Thumb: Generate (leaf) stack frames even if not needed"
+msgstr "Thumb: Generar marcs de pila (fulles) encara si no és necessari"
+
+#: config/arm/arm.h:507
+msgid "Thumb: Assume non-static functions may be called from ARM code"
+msgstr "Thumb: Assumir que les funcions no static poden ser cridades des de codi ARM"
+
+#: config/arm/arm.h:511
+msgid "Thumb: Assume function pointers may go to non-Thumb aware code"
+msgstr "Thumb: Assumir que els punters de funció poden anar a codi no informat sobre Thumb"
+
+#: config/arm/arm.h:515
+msgid "Cirrus: Place NOPs to avoid invalid instruction combinations"
+msgstr ""
+
+#: config/arm/arm.h:517
+msgid "Cirrus: Do not break up invalid instruction combinations with NOPs"
+msgstr ""
+
+#: config/arm/arm.h:525
+msgid "Specify the name of the target CPU"
+msgstr "Especificar el nom del CPU destinació"
+
+#: config/arm/arm.h:527
+msgid "Specify the name of the target architecture"
+msgstr "Especificar el nom de l'arquitectura destinació"
+
+#: config/arm/arm.h:531
+msgid "Specify the version of the floating point emulator"
+msgstr "Especifica la versió de l'emulador de nombre de coma flotant"
+
+#: config/arm/arm.h:533
+msgid "Specify the minimum bit alignment of structures"
+msgstr "Especificar l'alineació mínima de bit de les estructures"
+
+#: config/arm/arm.h:535
+msgid "Specify the register to be used for PIC addressing"
+msgstr "Especificar el registre a usar per al adreçament PIC"
+
+#: config/arm/pe.h:65
+msgid "Ignore dllimport attribute for functions"
+msgstr "Ignorar l'atribut dllimport per a les funcions"
+
+#: config/avr/avr.c:514
+#, c-format
+msgid "large frame pointer change (%d) with -mtiny-stack"
+msgstr "canvi de punter gran de marc (%d) amb -mtiny-stack"
+
+#: config/avr/avr.c:1101
+msgid "bad address, not (reg+disp):"
+msgstr "direcció errònia, no (reg+disp)"
+
+#: config/avr/avr.c:1109
+msgid "internal compiler error. Bad address:"
+msgstr "error intern del compilador. Direcció errònia:"
+
+#: config/avr/avr.c:1122
+msgid "internal compiler error. Unknown mode:"
+msgstr "error intern del compilador. Mode desconegut:"
+
+#: config/avr/avr.c:1744 config/avr/avr.c:2405
+msgid "invalid insn:"
+msgstr "insn invàlid:"
+
+#: config/avr/avr.c:1778 config/avr/avr.c:1861 config/avr/avr.c:1910
+#: config/avr/avr.c:1919 config/avr/avr.c:2014 config/avr/avr.c:2183
+#: config/avr/avr.c:2439 config/avr/avr.c:2547
+msgid "incorrect insn:"
+msgstr "insn incorrecte:"
+
+#: config/avr/avr.c:1938 config/avr/avr.c:2099 config/avr/avr.c:2254
+#: config/avr/avr.c:2591
+msgid "unknown move insn:"
+msgstr "desplaçament insn desconegut:"
+
+#: config/avr/avr.c:2814
+msgid "bad shift insn:"
+msgstr "desplaçament insn erròni:"
+
+#: config/avr/avr.c:2927 config/avr/avr.c:3348 config/avr/avr.c:3719
+msgid "internal compiler error. Incorrect shift:"
+msgstr "error intern del compilador. Direcció errònia:"
+
+#: config/avr/avr.c:4532 config/ip2k/ip2k.c:3144
+msgid "only initialized variables can be placed into program memory area"
+msgstr "Només les variables iniciades es poden ubicar en l'àrea de memòria del programa."
+
+#: config/avr/avr.c:4626
+msgid "only uninitialized variables can be placed in the .noinit section"
+msgstr "Només les variables sense inicialitzar es poden col·locar en la secció noinit"
+
+#: config/avr/avr.c:4640
+#, c-format
+msgid "MCU `%s' supported for assembler only"
+msgstr "MCU \"%s\" només té suport per a ensemblador"
+
+#: config/avr/avr.h:73
+msgid "Assume int to be 8 bit integer"
+msgstr "Assumir que int sigui enter de 8 bit"
+
+#: config/avr/avr.h:75
+msgid "Change the stack pointer without disabling interrupts"
+msgstr "Canviar el punter de la pila sense desactivar les interrupcions"
+
+#: config/avr/avr.h:77
+msgid "Use subroutines for function prologue/epilogue"
+msgstr "Usar subrutines per al pròleg/epíleg de funció"
+
+#: config/avr/avr.h:79
+msgid "Change only the low 8 bits of the stack pointer"
+msgstr "Canviar només els 8 bits baixos del punter de pila"
+
+#: config/avr/avr.h:81
+msgid "Do not generate tablejump insns"
+msgstr "No generar insns de salt de matriu"
+
+#: config/avr/avr.h:83
+msgid "Use rjmp/rcall (limited range) on >8K devices"
+msgstr ""
+
+#: config/avr/avr.h:85
+msgid "Output instruction sizes to the asm file"
+msgstr "Grandàries d'instrucció de sortida al fitxer asm"
+
+#: config/avr/avr.h:102
+msgid "Specify the initial stack address"
+msgstr "Especificar l'adreça inicial de la pila"
+
+#: config/avr/avr.h:103
+msgid "Specify the MCU name"
+msgstr "Especificar el nom MCU"
+
+#. `GIV_SORT_CRITERION(GIV1, GIV2)'
+#. In some cases, the strength reduction optimization pass can
+#. produce better code if this is defined. This macro controls the
+#. order that induction variables are combined. This macro is
+#. particularly useful if the target has limited addressing modes.
+#. For instance, the SH target has only positive offsets in
+#. addresses. Thus sorting to put the smallest address first allows
+#. the most combinations to be found.
+#: config/avr/avr.h:2268
+msgid "trampolines not supported"
+msgstr "els trampolins no tenen suport"
+
+#: config/c4x/c4x-c.c:71
+#, c-format
+msgid "missing '(' after '#pragma %s' - ignored"
+msgstr "\"(\" faltant desprès de \"#pragma %s\" - ignorat"
+
+#: config/c4x/c4x-c.c:74
+#, c-format
+msgid "missing function name in '#pragma %s' - ignored"
+msgstr "nom de funcció faltant en \"#pragma %s\" - ignorat"
+
+#: config/c4x/c4x-c.c:79
+#, c-format
+msgid "malformed '#pragma %s' - ignored"
+msgstr "\"#pragma %s\" malformat - ignorat"
+
+#: config/c4x/c4x-c.c:81
+#, c-format
+msgid "missing section name in '#pragma %s' - ignored"
+msgstr "nom de secció faltant en \"#pragma %s\" - ignorat"
+
+#: config/c4x/c4x-c.c:86
+#, c-format
+msgid "missing ')' for '#pragma %s' - ignored"
+msgstr "\")\" faltant per a \"#pragma %s\" - ignorat"
+
+#: config/c4x/c4x-c.c:89
+#, c-format
+msgid "junk at end of '#pragma %s'"
+msgstr "escombraries al final de \"#pragma %s\""
+
+#: config/c4x/c4x.c:300
+#, c-format
+msgid "unknown CPU version %d, using 40.\n"
+msgstr "versió desconeguda de CPU %d, usant 40.\n"
+
+#: config/c4x/c4x.c:850
+#, c-format
+msgid "ISR %s requires %d words of local vars, max is 32767"
+msgstr "El ISR %s requereix de %d words de variables locals,el màxim és 32767."
+
+#: config/c4x/c4x.c:1571
+msgid "using CONST_DOUBLE for address"
+msgstr "ùs de CONST_DOUBLE per a l'adreça"
+
+#: config/c4x/c4x.c:1709
+msgid "c4x_address_cost: Invalid addressing mode"
+msgstr "c4x_address_cost: Moda d'adreçament invàlid"
+
+#: config/c4x/c4x.c:1844
+#, c-format
+msgid "c4x_print_operand: %%L inconsistency"
+msgstr "c4x_print_operand: inconsistència %%L"
+
+#: config/c4x/c4x.c:1850
+#, c-format
+msgid "c4x_print_operand: %%N inconsistency"
+msgstr "c4x_print_operand: inconsistència %%N"
+
+#: config/c4x/c4x.c:1891
+#, c-format
+msgid "c4x_print_operand: %%O inconsistency"
+msgstr "c4x_print_operand: inconsistència %%O"
+
+#: config/c4x/c4x.c:1986
+msgid "c4x_print_operand: Bad operand case"
+msgstr "c4x_print_operand: Operant casi erroni"
+
+#: config/c4x/c4x.c:2027
+msgid "c4x_print_operand_address: Bad post_modify"
+msgstr "c4x_print_operand_address: post_modify erroni"
+
+#: config/c4x/c4x.c:2049
+msgid "c4x_print_operand_address: Bad pre_modify"
+msgstr "c4x_print_operand_address: pre_modify erroni"
+
+#: config/c4x/c4x.c:2097 config/c4x/c4x.c:2109 config/c4x/c4x.c:2124
+msgid "c4x_print_operand_address: Bad operand case"
+msgstr "c4x_print_operand_address: Operant casi erroni"
+
+#: config/c4x/c4x.c:2375
+msgid "c4x_rptb_insert: Cannot find start label"
+msgstr "c4x_rptb_insert: No es pot trobar l'etiqueta d'inici"
+
+#: config/c4x/c4x.c:3292 config/c4x/c4x.c:3310
+msgid "mode not QImode"
+msgstr "el moda no és QImode"
+
+#: config/c4x/c4x.c:3380
+msgid "invalid indirect memory address"
+msgstr "adreça indirecta de memòria invàlida"
+
+#: config/c4x/c4x.c:3469
+msgid "invalid indirect (S) memory address"
+msgstr "adreça indirecta de memòria (S) invàlida"
+
+#: config/c4x/c4x.c:3797
+msgid "c4x_valid_operands: Internal error"
+msgstr "c4x_valid_operands: error intern"
+
+#: config/c4x/c4x.c:4216
+msgid "c4x_operand_subword: invalid mode"
+msgstr "c4x_operand_subword: moda invàlid"
+
+#: config/c4x/c4x.c:4219
+msgid "c4x_operand_subword: invalid operand"
+msgstr "c4x_operand_subword: operant invàlid"
+
+#. We could handle these with some difficulty.
+#. e.g., *p-- => *(p-=2); *(p+1).
+#: config/c4x/c4x.c:4245
+msgid "c4x_operand_subword: invalid autoincrement"
+msgstr "c4x_operand_subword: autoincrement invàlid"
+
+#: config/c4x/c4x.c:4251
+msgid "c4x_operand_subword: invalid address"
+msgstr "c4x_operand_subword: adreça invàlid"
+
+#: config/c4x/c4x.c:4262
+msgid "c4x_operand_subword: address not offsettable"
+msgstr "c4x_operand_subword: adreça no desplaçabla"
+
+#: config/c4x/c4x.c:4472
+msgid "c4x_rptb_rpts_p: Repeat block top label moved\n"
+msgstr "c4x_rptb_rpts_p: etiqueta superiora de bloc de repetició desplaçada\n"
+
+#. ??? HACK. We shouldn't have flag_inline_trees at all.
+#. Name of the c4x assembler.
+#. Name of the c4x linker.
+#. Define assembler options.
+#. Define linker options.
+#. Specify the end file to link with.
+#. Target compilation option flags.
+#. Small memory model.
+#. Use 24-bit MPYI for C3x.
+#. Fast fixing of floats.
+#. Allow use of RPTS.
+#. Emit C3x code.
+#. Be compatible with TI assembler.
+#. Be paranoid about DP reg. in ISRs.
+#. Pass arguments on stack.
+#. Enable features under development.
+#. Enable repeat block.
+#. Use BK as general register.
+#. Use decrement and branch for C3x.
+#. Enable debugging of GCC.
+#. Force constants into registers.
+#. Allow unsigned loop counters.
+#. Force op0 and op1 to be same.
+#. Save all 40 bits for floats.
+#. Allow parallel insns.
+#. Allow MPY||ADD, MPY||SUB insns.
+#. Assume mem refs possibly aliased.
+#. Emit C30 code.
+#. Emit C31 code.
+#. Emit C32 code.
+#. Emit C33 code.
+#. Emit C40 code.
+#. Emit C44 code.
+#. Run-time compilation parameters selecting different hardware subsets.
+#.
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of triplets in braces,
+#. each pair being { "NAME", VALUE, "DESCRIPTION" }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/c4x/c4x.h:168
+msgid "Small memory model"
+msgstr "Model de memòria small"
+
+#: config/c4x/c4x.h:170
+msgid "Big memory model"
+msgstr "Model de memòria big"
+
+#: config/c4x/c4x.h:172
+msgid "Use MPYI instruction for C3x"
+msgstr "Usar instrucció MPYI per a C3x"
+
+#: config/c4x/c4x.h:174
+msgid "Do not use MPYI instruction for C3x"
+msgstr "No usar instrucció MPYI per a C3x"
+
+#: config/c4x/c4x.h:176
+msgid "Use fast but approximate float to integer conversion"
+msgstr "Usar conversió de coma flotant a enter ràpida però aproximada"
+
+#: config/c4x/c4x.h:178
+msgid "Use slow but accurate float to integer conversion"
+msgstr "Usar conversió de coma flotant a enter lenta però exacta"
+
+#: config/c4x/c4x.h:180
+msgid "Enable use of RTPS instruction"
+msgstr "Activar l'ús de la instrucció RTPS"
+
+#: config/c4x/c4x.h:182
+msgid "Disable use of RTPS instruction"
+msgstr "Desactivar l'ús de la instrucció RTPS"
+
+#: config/c4x/c4x.h:184
+msgid "Enable use of RTPB instruction"
+msgstr "Activar l'ús de la instrucció RTPB"
+
+#: config/c4x/c4x.h:186
+msgid "Disable use of RTPB instruction"
+msgstr "Desactivar l'ús de la instrucció RTPB"
+
+#: config/c4x/c4x.h:188
+msgid "Generate code for C30 CPU"
+msgstr "Generar codi per al CPU C30"
+
+#: config/c4x/c4x.h:190
+msgid "Generate code for C31 CPU"
+msgstr "Generar codi per al CPU C31"
+
+#: config/c4x/c4x.h:192
+msgid "Generate code for C32 CPU"
+msgstr "Generar codi per al CPU C32"
+
+#: config/c4x/c4x.h:194
+msgid "Generate code for C33 CPU"
+msgstr "Generar codi per al CPU C33"
+
+#: config/c4x/c4x.h:196
+msgid "Generate code for C40 CPU"
+msgstr "Generar codi per al CPU C40"
+
+#: config/c4x/c4x.h:198
+msgid "Generate code for C44 CPU"
+msgstr "Generar codi per al CPU C44"
+
+#: config/c4x/c4x.h:200
+msgid "Emit code compatible with TI tools"
+msgstr "Emetre codi compatible amb les eines TI"
+
+#: config/c4x/c4x.h:202
+msgid "Emit code to use GAS extensions"
+msgstr "Emetre codi per a usar les extensions de GAS"
+
+#: config/c4x/c4x.h:204 config/c4x/c4x.h:208
+msgid "Save DP across ISR in small memory model"
+msgstr "Guardar DP entre ISR en el model de memòria small"
+
+#: config/c4x/c4x.h:206 config/c4x/c4x.h:210
+msgid "Don't save DP across ISR in small memory model"
+msgstr "No guardar DP entre ISR en el model de memòria small"
+
+#: config/c4x/c4x.h:212
+msgid "Pass arguments on the stack"
+msgstr "Passar els arguments en la pila"
+
+#: config/c4x/c4x.h:214
+msgid "Pass arguments in registers"
+msgstr "Passar els arguments en els registres"
+
+#: config/c4x/c4x.h:216
+msgid "Enable new features under development"
+msgstr "Activar noves característiques en desenvolupament"
+
+#: config/c4x/c4x.h:218
+msgid "Disable new features under development"
+msgstr "Desactivar noves característiques en desenvolupament"
+
+#: config/c4x/c4x.h:220
+msgid "Use the BK register as a general purpose register"
+msgstr "Usar el registre BK com un registre de propòsit general"
+
+#: config/c4x/c4x.h:222
+msgid "Do not allocate BK register"
+msgstr "No assignar el registre BK"
+
+#: config/c4x/c4x.h:224
+msgid "Enable use of DB instruction"
+msgstr "Activar l'ús de la instrucció DB"
+
+#: config/c4x/c4x.h:226
+msgid "Disable use of DB instruction"
+msgstr "Desactivar l'ús de la instrucció DB"
+
+#: config/c4x/c4x.h:228
+msgid "Enable debugging"
+msgstr "Activar la depuració"
+
+#: config/c4x/c4x.h:230
+msgid "Disable debugging"
+msgstr "Desactivar la depuració"
+
+#: config/c4x/c4x.h:232
+msgid "Force constants into registers to improve hoisting"
+msgstr "Forçar les constants dintre de registres per a millorar l'aixecament"
+
+#: config/c4x/c4x.h:234
+msgid "Don't force constants into registers"
+msgstr "No forçar les constants en els registres"
+
+#: config/c4x/c4x.h:236
+msgid "Force RTL generation to emit valid 3 operand insns"
+msgstr "Forçar que la generació de RTL emeti 3 operandes insns vàlids"
+
+#: config/c4x/c4x.h:238
+msgid "Allow RTL generation to emit invalid 3 operand insns"
+msgstr "Permetre que la generació de RTL emeti 3 operandes insns invàlids"
+
+#: config/c4x/c4x.h:240
+msgid "Allow unsigned iteration counts for RPTB/DB"
+msgstr "Permetre comptes de iteracions unsigned per a RPTB/DB"
+
+#: config/c4x/c4x.h:242
+msgid "Disallow unsigned iteration counts for RPTB/DB"
+msgstr "No permetre comptes de iteracions unsigned per a RPTB/DB"
+
+#: config/c4x/c4x.h:244
+msgid "Preserve all 40 bits of FP reg across call"
+msgstr "Preservar els 40 bits del registre FP entre cridades"
+
+#: config/c4x/c4x.h:246
+msgid "Only preserve 32 bits of FP reg across call"
+msgstr "Només preservar 32 bits del registre FP entre cridades"
+
+#: config/c4x/c4x.h:248
+msgid "Enable parallel instructions"
+msgstr "Activar les funcions paral·leles"
+
+#: config/c4x/c4x.h:250
+msgid "Disable parallel instructions"
+msgstr "Desactivar les funcions paral·leles"
+
+#: config/c4x/c4x.h:252
+msgid "Enable MPY||ADD and MPY||SUB instructions"
+msgstr "Activar les instruccions MPY||ADD i MPY||SUB"
+
+#: config/c4x/c4x.h:254
+msgid "Disable MPY||ADD and MPY||SUB instructions"
+msgstr "Desactivar les instruccions MPY||ADD i MPY||SUB"
+
+#: config/c4x/c4x.h:256
+msgid "Assume that pointers may be aliased"
+msgstr "Assumir que es poden fer alies dels punters"
+
+#: config/c4x/c4x.h:258
+msgid "Assume that pointers not aliased"
+msgstr "Assumir que els punters no tenen alies"
+
+#: config/c4x/c4x.h:331
+msgid "Specify maximum number of iterations for RPTS"
+msgstr "Especificar el nombre màxim de iteracions per a RPTS"
+
+#: config/c4x/c4x.h:333
+msgid "Select CPU to generate code for"
+msgstr "Seleccionar el CPU per al qual es genera codi"
+
+#: config/cris/cris.c:604
+msgid "unexpected index-type in cris_print_index"
+msgstr "index-type inesperat en cris_print_index"
+
+#: config/cris/cris.c:618
+msgid "unexpected base-type in cris_print_base"
+msgstr "base-type inesperat en cris_print_base"
+
+#: config/cris/cris.c:911
+#, c-format
+msgid "stackframe too big: %d bytes"
+msgstr "marc de pila massa grand: %d bytes"
+
+#: config/cris/cris.c:1222
+msgid "allocated but unused delay list in epilogue"
+msgstr "llista d'alenteixo assignada però sense ús en l'epíleg"
+
+#: config/cris/cris.c:1232
+msgid "unexpected function type needing stack adjustment for __builtin_eh_return"
+msgstr "el tipus de funció inesperat necessita un ajustament de pila per a _builtin_eh_return"
+
+#: config/cris/cris.c:1308
+msgid "invalid operand for 'b' modifier"
+msgstr "operant invàlid per al modificador \"b\""
+
+#: config/cris/cris.c:1321
+msgid "invalid operand for 'v' modifier"
+msgstr "operant invàlid per al modificador \"v\""
+
+#: config/cris/cris.c:1331
+msgid "invalid operand for 'P' modifier"
+msgstr "operant invàlid per al modificador \"P\""
+
+#: config/cris/cris.c:1338
+msgid "invalid operand for 'p' modifier"
+msgstr "operant invàlid per al modificador \"p\""
+
+#: config/cris/cris.c:1377
+msgid "invalid operand for 'z' modifier"
+msgstr "operant invàlid per al modificador \"z\""
+
+#: config/cris/cris.c:1425 config/cris/cris.c:1455
+msgid "invalid operand for 'H' modifier"
+msgstr "operant invàlid per al modificador \"H\""
+
+#: config/cris/cris.c:1431
+msgid "bad register"
+msgstr "registre erroni"
+
+#: config/cris/cris.c:1469
+msgid "invalid operand for 'e' modifier"
+msgstr "operant invàlid per al modificador \"e\""
+
+#: config/cris/cris.c:1486
+msgid "invalid operand for 'm' modifier"
+msgstr "operant invàlid per al modificador \"m\""
+
+#: config/cris/cris.c:1511
+msgid "invalid operand for 'A' modifier"
+msgstr "operant invàlid per al modificador \"A\""
+
+#: config/cris/cris.c:1519
+msgid "invalid operand for 'D' modifier"
+msgstr "operant invàlid per al modificador \"D\""
+
+#: config/cris/cris.c:1533
+msgid "invalid operand for 'T' modifier"
+msgstr "operant invàlid per al modificador \"T\""
+
+#: config/cris/cris.c:1542
+msgid "invalid operand modifier letter"
+msgstr "lletra de modificador d'operant invàlid"
+
+#: config/cris/cris.c:1550
+#, c-format
+msgid "internal error: bad register: %d"
+msgstr "error intern: registre erroni: %d"
+
+#: config/cris/cris.c:1598
+msgid "unexpected multiplicative operand"
+msgstr "operant multiplicatiu inesperat"
+
+#: config/cris/cris.c:1618
+msgid "unexpected operand"
+msgstr "operant inesperat"
+
+#: config/cris/cris.c:1651 config/cris/cris.c:1661
+msgid "unrecognized address"
+msgstr "adreça no reconeguda"
+
+#: config/cris/cris.c:2011
+msgid "internal error: sideeffect-insn affecting main effect"
+msgstr "error intern: sideeffect-insn afectant el efecte principal"
+
+#. If we get here, the caller got its initial tests wrong.
+#: config/cris/cris.c:2404
+msgid "internal error: cris_side_effect_mode_ok with bad operands"
+msgstr "error intern: cris_side_effect_mode_ok amb operants erronis"
+
+#: config/cris/cris.c:2481 config/cris/cris.c:2543
+msgid "unrecognized supposed constant"
+msgstr "suposada constant no reconeguda"
+
+#: config/cris/cris.c:2588
+msgid "unrecognized supposed constant in cris_global_pic_symbol"
+msgstr "suposada constant no reconeguda en cris_global_pic_symbol"
+
+#: config/cris/cris.c:2607
+#, c-format
+msgid "-max-stackframe=%d is not usable, not between 0 and %d"
+msgstr "no es pot usar -max-stackframe=%d, no està entre 0 i %d"
+
+#: config/cris/cris.c:2635
+#, c-format
+msgid "unknown CRIS version specification in -march= or -mcpu= : %s"
+msgstr "especificació de versió CRIS desconeguda en -march= o -mcpu= : %s"
+
+#: config/cris/cris.c:2671
+#, c-format
+msgid "unknown CRIS cpu version specification in -mtune= : %s"
+msgstr "especificació de versió de cpu de CRIS desconeguda en -mtune= : %s"
+
+#: config/cris/cris.c:2689
+msgid "-fPIC and -fpic are not supported in this configuration"
+msgstr "no és dona suport a -fPIC i -fpic en aquesta configuració"
+
+#: config/cris/cris.c:2705
+msgid "that particular -g option is invalid with -maout and -melinux"
+msgstr "aquesta opció particular -g és invàlid amb -maout i -melinux"
+
+#: config/cris/cris.c:2960 config/cris/cris.c:3005
+msgid "unexpected side-effects in address"
+msgstr "effecte de vora inesperat en l'adreça"
+
+#. Labels are never marked as global symbols.
+#: config/cris/cris.c:3100 config/cris/cris.c:3131
+msgid "unexpected PIC symbol"
+msgstr "símbol PIC inesperat"
+
+#: config/cris/cris.c:3104
+msgid "PIC register isn't set up"
+msgstr "el registre PIC no està preparat"
+
+#: config/cris/cris.c:3117 config/cris/cris.c:3200
+msgid "unexpected address expression"
+msgstr "expressió d'adreça inesperada"
+
+#: config/cris/cris.c:3135
+msgid "emitting PIC operand, but PIC register isn't set up"
+msgstr "emetant un operant PIC, però el registre PIC no està preparat"
+
+#: config/cris/cris.c:3144
+msgid "unexpected NOTE as addr_const:"
+msgstr "NOTE com a addr_const inesperat:"
+
+#: config/cris/aout.h:108
+msgid "Compile for the MMU-less Etrax 100-based elinux system"
+msgstr "Compilar per al sistema elinux Etrax basat en 100 sense MMU"
+
+#: config/cris/aout.h:115
+msgid "For elinux, request a specified stack-size for this program"
+msgstr "Per a elinux, sol·licitar una grandària de pila especificada per a aquest programa"
+
+#: config/cris/cris.h:362
+#, fuzzy
+msgid "Work around bug in multiplication instruction"
+msgstr "No usar instruccions de fp per a multiplicar-acumular"
+
+#. No "no-etrax" as it does not really imply any model. On the other hand, "etrax" implies the common (and large) subset matching all models.
+#: config/cris/cris.h:368
+msgid "Compile for ETRAX 4 (CRIS v3)"
+msgstr "Compilar per a ETRAX 4 (CRIS v3)"
+
+#: config/cris/cris.h:373
+msgid "Compile for ETRAX 100 (CRIS v8)"
+msgstr "Compilar per a ETRAX 100 (CRIS v8)"
+
+#: config/cris/cris.h:377
+msgid "Emit verbose debug information in assembly code"
+msgstr "Emetre informació de depuració detallada en el codi assemblador"
+
+#: config/cris/cris.h:380
+msgid "Do not use condition codes from normal instructions"
+msgstr "No usar codis de condició per a les instruccions normals"
+
+#: config/cris/cris.h:384
+msgid "Do not emit addressing modes with side-effect assignment"
+msgstr "No emetre maneres d'adreçament amb assignacions col·laterals"
+
+#: config/cris/cris.h:387
+msgid "Do not tune stack alignment"
+msgstr "No ajustar l'alineació de la pila"
+
+#: config/cris/cris.h:390
+msgid "Do not tune writable data alignment"
+msgstr "No ajustar l'alineació de les dades modificables"
+
+#: config/cris/cris.h:393
+msgid "Do not tune code and read-only data alignment"
+msgstr "No ajustar l'alineació del codi i de dades només de lectura"
+
+#: config/cris/cris.h:402
+msgid "Align code and data to 32 bits"
+msgstr "Alinear codi i dades a 32 bits"
+
+#: config/cris/cris.h:415
+msgid "Don't align items in code or data"
+msgstr "No alinear elements en el codi o les dades"
+
+#: config/cris/cris.h:418
+msgid "Do not emit function prologue or epilogue"
+msgstr "No emetre pròleg o epíleg de funcions"
+
+#. We have to handle this m-option here since we can't wash it off in both CC1_SPEC and CC1PLUS_SPEC.
+#: config/cris/cris.h:422
+msgid "Use the most feature-enabling options allowed by other options"
+msgstr "Usar la major quantitat de característiques permeses per altres opcions"
+
+#. We must call it "override-" since calling it "no-" will cause gcc.c to forget it, if there's a "later" -mbest-lib-options. Kludgy, but needed for some multilibbed files.
+#: config/cris/cris.h:428
+msgid "Override -mbest-lib-options"
+msgstr "Anular -mbest-lib-options"
+
+#: config/cris/cris.h:460
+msgid "Generate code for the specified chip or CPU version"
+msgstr "Generar codi per al xip especificat o la versió de CPU"
+
+#: config/cris/cris.h:462
+msgid "Tune alignment for the specified chip or CPU version"
+msgstr "Ajustar alineació per al xip especificat o la versió de CPU"
+
+#: config/cris/cris.h:464
+msgid "Warn when a stackframe is larger than the specified size"
+msgstr "Avisar quan un marc de pila sigui més gran que la grandària especificada"
+
+#. Node: Profiling
+#: config/cris/cris.h:1050
+msgid "no FUNCTION_PROFILER for CRIS"
+msgstr "no FUNCTION_PROFILER per a CRIS"
+
+#: config/cris/linux.h:69
+msgid "Together with -fpic and -fPIC, do not use GOTPLT references"
+msgstr "Juntament amb -fpic i -fPIC, no utilitzar referències GOTPLT"
+
+#: config/d30v/d30v.c:218
+#, c-format
+msgid "bad modes_tieable_p for register %s, mode1 %s, mode2 %s"
+msgstr "modes_tieable_p erroni per al registre %s, manera1 %s, manera2 %s"
+
+#: config/d30v/d30v.c:2678
+msgid "bad insn to d30v_print_operand_address:"
+msgstr "insn erronia per a d30v_print_operand_address:"
+
+#: config/d30v/d30v.c:2695 config/d30v/d30v.c:2756 config/d30v/d30v.c:2777
+#: config/d30v/d30v.c:2795
+msgid "bad insn to d30v_print_operand_memory_reference:"
+msgstr "insn erroni per a d30v_print_operand_memory_reference:"
+
+#: config/d30v/d30v.c:2863
+msgid "bad insn to d30v_print_operand, 'f' modifier:"
+msgstr "insn erroni per a d30v_print_operand, modificador \"f\":"
+
+#: config/d30v/d30v.c:2872
+msgid "bad insn to d30v_print_operand, 'A' modifier:"
+msgstr "insn erroni per a d30v_print_operand, modificador \"A\":"
+
+#: config/d30v/d30v.c:2879
+msgid "bad insn to d30v_print_operand, 'M' modifier:"
+msgstr "insn erroni per a d30v_print_operand, modificador \"M\":"
+
+#: config/d30v/d30v.c:2933
+msgid "bad insn to print_operand, 'F' or 'T' modifier:"
+msgstr "insn erroni per a print_operand, modificador \"F\" o \"T\":"
+
+#: config/d30v/d30v.c:2944
+msgid "bad insn to print_operand, 'B' modifier:"
+msgstr "insn erroni per a print_operand, modificador \"B\":"
+
+#: config/d30v/d30v.c:2951
+msgid "bad insn to print_operand, 'E' modifier:"
+msgstr "insn erroni per a print_operand, modificador \"E\":"
+
+#: config/d30v/d30v.c:2969
+msgid "bad insn to print_operand, 'R' modifier:"
+msgstr "insn erroni per a print_operand, modificador \"R\":"
+
+#: config/d30v/d30v.c:2978 config/d30v/d30v.c:2986
+msgid "bad insn to print_operand, 's' modifier:"
+msgstr "insn erroni per a print_operand, modificador \"s\":"
+
+#: config/d30v/d30v.c:3015
+msgid "bad insn in d30v_print_operand, 0 case"
+msgstr "insn erroni per a d30v_print_operand, casi 0"
+
+#: config/d30v/d30v.c:3313
+msgid "d30v_emit_comparison"
+msgstr "d30v_emit_comparison"
+
+#: config/d30v/d30v.c:3357
+msgid "bad call to d30v_move_2words"
+msgstr "cirdada ad30v_move_2words errònia"
+
+#: config/d30v/d30v.h:111
+msgid "Enable use of conditional move instructions"
+msgstr "Activar l'ús de les instruccions condicionals move"
+
+#: config/d30v/d30v.h:114
+msgid "Disable use of conditional move instructions"
+msgstr "Desactivar l'ús de les instruccions condicionals move"
+
+#: config/d30v/d30v.h:117
+msgid "Debug argument support in compiler"
+msgstr "Suport per a depuració d'arguments en el compilador"
+
+#: config/d30v/d30v.h:120
+msgid "Debug stack support in compiler"
+msgstr "Suport per a depuració de pila en el compilador"
+
+#: config/d30v/d30v.h:123
+msgid "Debug memory address support in compiler"
+msgstr "Suport per a depuració d'adreces de memòria en el compilador"
+
+#: config/d30v/d30v.h:126
+msgid "Make adjacent short instructions parallel if possible"
+msgstr "Fer paral·leles les instruccions adjacents talles siés possible."
+
+#: config/d30v/d30v.h:129
+msgid "Do not make adjacent short instructions parallel"
+msgstr "No fer paral·leles les instruccions adjacents."
+
+#: config/d30v/d30v.h:132 config/d30v/d30v.h:135
+msgid "Link programs/data to be in external memory by default"
+msgstr "Enllaçar programes/dades per a estar en la memòria externa per omissió"
+
+#: config/d30v/d30v.h:138
+msgid "Link programs/data to be in onchip memory by default"
+msgstr "Enllaçar programes/dades per a estar en la memòria del xip per omissió"
+
+#: config/d30v/d30v.h:146
+msgid "Change the branch costs within the compiler"
+msgstr "Canviar els costos de ramificació dintre del compilador"
+
+#: config/d30v/d30v.h:149
+msgid "Change the threshold for conversion to conditional execution"
+msgstr "Canviar el llindar per a la conversió a execució condicional"
+
+#: config/dsp16xx/dsp16xx.c:1463 config/dsp16xx/dsp16xx.c:1486
+msgid "stack size > 32k"
+msgstr "Grandària de la pila > 32k"
+
+#: config/dsp16xx/dsp16xx.c:1695
+msgid "invalid addressing mode"
+msgstr "manera d'adreçar invàlida"
+
+#: config/dsp16xx/dsp16xx.c:1838
+msgid "bad register extension code"
+msgstr "codi d'extensió de registre erroni"
+
+#: config/dsp16xx/dsp16xx.c:1938
+msgid "invalid offset in ybase addressing"
+msgstr "desplaçament invàlid en el adreçament de ybase"
+
+#: config/dsp16xx/dsp16xx.c:1941
+msgid "invalid register in ybase addressing"
+msgstr "registre invàlid en el adreçament de ybase"
+
+#: config/dsp16xx/dsp16xx.c:2116
+msgid "invalid shift operator in emit_1600_core_shift"
+msgstr "operador de desplaçament invàlid en emit_1600_core_shift"
+
+#: config/dsp16xx/dsp16xx.c:2406
+msgid "invalid mode for gen_tst_reg"
+msgstr "mode invàlid per a gen_tst_reg"
+
+#: config/dsp16xx/dsp16xx.c:2478
+msgid "invalid mode for integer comparison in gen_compare_reg"
+msgstr "mode invàlid per a la comparança entera en gen_compari_reg"
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/dsp16xx/dsp16xx.h:230
+msgid "Pass parameters in registers (default)"
+msgstr "Passar els paràmetres en els registres (per omissió)"
+
+#: config/dsp16xx/dsp16xx.h:232
+msgid "Don't pass parameters in registers"
+msgstr "No passar els paràmetres en els registres"
+
+#: config/dsp16xx/dsp16xx.h:234
+msgid "Generate code for near calls"
+msgstr "Generar codi per a cridades near"
+
+#: config/dsp16xx/dsp16xx.h:236
+msgid "Don't generate code for near calls"
+msgstr "No generar codi per a cridades near"
+
+#: config/dsp16xx/dsp16xx.h:238
+msgid "Generate code for near jumps"
+msgstr "Generar codi per a salts near"
+
+#: config/dsp16xx/dsp16xx.h:240
+msgid "Don't generate code for near jumps"
+msgstr "No generar codi per a salts near"
+
+#: config/dsp16xx/dsp16xx.h:242
+msgid "Generate code for a bit-manipulation unit"
+msgstr "Generar codi per a una unitat de manipulació de bits"
+
+#: config/dsp16xx/dsp16xx.h:244
+msgid "Don't generate code for a bit-manipulation unit"
+msgstr "No generar codi per a una unitat de manipulació de bits"
+
+#: config/dsp16xx/dsp16xx.h:246
+msgid "Generate code for memory map1"
+msgstr "Generar codi per a memory map1"
+
+#: config/dsp16xx/dsp16xx.h:248
+msgid "Generate code for memory map2"
+msgstr "Generar codi per a memory map2"
+
+#: config/dsp16xx/dsp16xx.h:250
+msgid "Generate code for memory map3"
+msgstr "Generar codi per a memory map3"
+
+#: config/dsp16xx/dsp16xx.h:252
+msgid "Generate code for memory map4"
+msgstr "Generar codi per a memory map4"
+
+#: config/dsp16xx/dsp16xx.h:254
+msgid "Ouput extra code for initialized data"
+msgstr "Generar codi extra per a dades inicialitzades"
+
+#: config/dsp16xx/dsp16xx.h:256
+msgid "Don't let reg. allocator use ybase registers"
+msgstr "No permetre que el assignador de registres usi registres ybase"
+
+#: config/dsp16xx/dsp16xx.h:258
+msgid "Output extra debug info in Luxworks environment"
+msgstr "Generar informació extra de depuració en l'ambit Luxworks"
+
+#: config/dsp16xx/dsp16xx.h:260
+msgid "Save temp. files in Luxworks environment"
+msgstr "Guardar els fitxers temporals en l'ambit Luxworks"
+
+#: config/dsp16xx/dsp16xx.h:272
+msgid "Specify alternate name for text section"
+msgstr "Especificar un nom alternatiu per a la secció de text"
+
+#: config/dsp16xx/dsp16xx.h:274
+msgid "Specify alternate name for data section"
+msgstr "Especificar un nom alternatiu per a la secció de dades"
+
+#: config/dsp16xx/dsp16xx.h:276
+msgid "Specify alternate name for bss section"
+msgstr "Especificar un nom alternatiu per a la secció bss"
+
+#: config/dsp16xx/dsp16xx.h:278
+msgid "Specify alternate name for constant section"
+msgstr "Especificar un nom alternatiu per a la secció constant"
+
+#: config/dsp16xx/dsp16xx.h:280
+msgid "Specify alternate name for dsp16xx chip"
+msgstr "Especificar un nom alternatiu per a el xip dsp16xx"
+
+#. Output assembler code to FILE to increment profiler label # LABELNO
+#. for profiling a function entry.
+#: config/dsp16xx/dsp16xx.h:1217 config/dsp16xx/dsp16xx.h:1668
+#: config/dsp16xx/dsp16xx.h:1673
+msgid "profiling not implemented yet"
+msgstr "no s'ha implementat encara profiling"
+
+#. Emit RTL insns to initialize the variable parts of a trampoline.
+#. FNADDR is an RTX for the address of the function's pure code.
+#. CXT is an RTX for the static chain value for the function.
+#: config/dsp16xx/dsp16xx.h:1227 config/dsp16xx/dsp16xx.h:1239
+msgid "trampolines not yet implemented"
+msgstr "no s'han implementat encara trampolin"
+
+#: config/fr30/fr30.c:451
+msgid "fr30_print_operand_address: unhandled address"
+msgstr "fr30_print_operand_address: adreça sense manejar"
+
+#: config/fr30/fr30.c:475
+#, c-format
+msgid "fr30_print_operand: unrecognized %%p code"
+msgstr "fr30_print_operand_address: no es reconeix el codi %%p"
+
+#: config/fr30/fr30.c:495
+#, c-format
+msgid "fr30_print_operand: unrecognized %%b code"
+msgstr "fr30_print_operand_address: no es reconeix el codi %%b"
+
+#: config/fr30/fr30.c:516
+#, c-format
+msgid "fr30_print_operand: unrecognized %%B code"
+msgstr "fr30_print_operand_address: no es reconeix el codi %%B"
+
+#: config/fr30/fr30.c:524
+#, c-format
+msgid "fr30_print_operand: invalid operand to %%A code"
+msgstr "fr30_print_operand: operant invàlid per al codi %%A"
+
+#: config/fr30/fr30.c:541
+#, c-format
+msgid "fr30_print_operand: invalid %%x code"
+msgstr "fr30_print_operand: codi %%x invàlid"
+
+#: config/fr30/fr30.c:548
+#, c-format
+msgid "fr30_print_operand: invalid %%F code"
+msgstr "fr30_print_operand: codi %%F invàlid"
+
+#: config/fr30/fr30.c:565
+msgid "fr30_print_operand: unknown code"
+msgstr "fr30_print_operand: codi desconegut"
+
+#: config/fr30/fr30.c:594 config/fr30/fr30.c:603 config/fr30/fr30.c:614
+#: config/fr30/fr30.c:627
+msgid "fr30_print_operand: unhandled MEM"
+msgstr "fr30_print_operand: MEM sense manejar"
+
+#: config/fr30/fr30.h:63
+msgid "Assume small address space"
+msgstr "Assumint espai d'adreces petit"
+
+#: config/frv/frv.c:392 config/frv/frv.c:410
+#, c-format
+msgid "Unknown cpu: -mcpu=%s"
+msgstr ""
+
+#: config/frv/frv.c:433
+msgid "-fpic and -gdwarf are incompatible (-fpic and -g/-gdwarf-2 are fine)"
+msgstr ""
+
+#: config/frv/frv.c:2397
+msgid "Bad insn to frv_print_operand_address:"
+msgstr "insn erroni per a frv_print_operand_address:"
+
+#: config/frv/frv.c:2408
+msgid "Bad register to frv_print_operand_memory_reference_reg:"
+msgstr "insn erroni per a frv_print_operand_memory_reference_reg:"
+
+#: config/frv/frv.c:2446 config/frv/frv.c:2456 config/frv/frv.c:2465
+#: config/frv/frv.c:2493 config/frv/frv.c:2506 config/frv/frv.c:2510
+msgid "Bad insn to frv_print_operand_memory_reference:"
+msgstr "insn erroni per a frv_print_operand_memory_reference:"
+
+#: config/frv/frv.c:2648
+msgid "Bad insn in frv_print_operand, bad const_double"
+msgstr "insn erroni per a frv_print_operand,·bad·const_double"
+
+#: config/frv/frv.c:2693
+msgid "Bad insn to frv_print_operand, 'C' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"C\":"
+
+#: config/frv/frv.c:2716
+msgid "Bad insn to frv_print_operand, 'c' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"c\":"
+
+#: config/frv/frv.c:2741
+msgid "Bad insn to frv_print_operand, 'e' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"e\":"
+
+#: config/frv/frv.c:2749
+msgid "Bad insn to frv_print_operand, 'F' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"F\":"
+
+#: config/frv/frv.c:2765
+msgid "Bad insn to frv_print_operand, 'f' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"f\":"
+
+#: config/frv/frv.c:2818
+msgid "Bad insn to frv_print_operand, 'L' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"L\":"
+
+#: config/frv/frv.c:2831
+msgid "Bad insn to frv_print_operand, 'M/N' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"M/N\":"
+
+#: config/frv/frv.c:2852
+msgid "Bad insn to frv_print_operand, 'O' modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"O\":"
+
+#: config/frv/frv.c:2870
+msgid "Bad insn to frv_print_operand, P modifier:"
+msgstr "insn erroni per a frv_print_operand, modificador \"P\":"
+
+#: config/frv/frv.c:2890
+msgid "Bad insn in frv_print_operand, z case"
+msgstr "insn erroni per a frv_print_operand, casi z"
+
+#: config/frv/frv.c:2918
+msgid "Bad insn in frv_print_operand, 0 case"
+msgstr "insn erroni per a frv_print_operand, casi 0"
+
+#: config/frv/frv.c:2923
+msgid "frv_print_operand: unknown code"
+msgstr "frv_print_operand: codi desconegut"
+
+#: config/frv/frv.c:5474
+msgid "Bad output_move_single operand"
+msgstr "Operant output_move_single erroni"
+
+#: config/frv/frv.c:5601
+msgid "Bad output_move_double operand"
+msgstr ""
+
+#: config/frv/frv.c:5743
+msgid "Bad output_condmove_single operand"
+msgstr "Operant output_condmove_single erroni"
+
+#: config/frv/frv.c:8031
+msgid "frv_registers_update"
+msgstr ""
+
+#: config/frv/frv.c:8188
+msgid "frv_registers_used_p"
+msgstr ""
+
+#: config/frv/frv.c:8314
+msgid "frv_registers_set_p"
+msgstr ""
+
+#: config/frv/frv.c:8910
+msgid "accumulator is not a constant integer"
+msgstr "el acumulador no és una constant sentera"
+
+#: config/frv/frv.c:8915
+msgid "accumulator number is out of bounds"
+msgstr ""
+
+#: config/frv/frv.c:8926
+#, c-format
+msgid "inappropriate accumulator for `%s'"
+msgstr "acumulador inadequat per a \"%s\""
+
+#: config/frv/frv.c:8986
+#, c-format
+msgid "`%s' expects a constant argument"
+msgstr "l'atribut \"%s\" espera una constant com argument"
+
+#: config/frv/frv.c:8991
+#, c-format
+msgid "constant argument out of range for `%s'"
+msgstr "l'argument constant està fora de rang per a \"%s\""
+
+#: config/frv/frv.c:9338
+msgid "media functions are not available unless -mmedia is used"
+msgstr ""
+
+#: config/frv/frv.c:9350
+msgid "this media function is only available on the fr500"
+msgstr ""
+
+#: config/frv/frv.c:9378
+msgid "this media function is only available on the fr400"
+msgstr ""
+
+#. This macro is a C statement to print on `stderr' a string describing the
+#. particular machine description choice. Every machine description should
+#. define `TARGET_VERSION'. For example:
+#.
+#. #ifdef MOTOROLA
+#. #define TARGET_VERSION fprintf (stderr, " (68k, Motorola syntax)");
+#. #else
+#. #define TARGET_VERSION fprintf (stderr, " (68k, MIT syntax)");
+#. #endif
+#: config/frv/frv.h:506
+msgid " (frv)"
+msgstr ""
+
+#: config/h8300/h8300.c:288
+msgid "-ms2600 is used without -ms"
+msgstr "es va usar -ms2600 sense -ms"
+
+#: config/h8300/h8300.c:294
+msgid "-mn is used without -mh or -ms"
+msgstr "es va usar -mn sense -mh o -ms"
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/h8300/h8300.h:145
+msgid "Generate H8S code"
+msgstr "Generar codi H8S"
+
+#: config/h8300/h8300.h:146
+msgid "Do not generate H8S code"
+msgstr "No generar codi H8S"
+
+#: config/h8300/h8300.h:147
+msgid "Generate H8S/2600 code"
+msgstr "Generar codi H8S/2600"
+
+#: config/h8300/h8300.h:148
+msgid "Do not generate H8S/2600 code"
+msgstr "No generar codi H8S/2600"
+
+#: config/h8300/h8300.h:149
+msgid "Make integers 32 bits wide"
+msgstr "Fer enters de 32 bits d'amplària"
+
+#: config/h8300/h8300.h:152
+msgid "Use registers for argument passing"
+msgstr "Usar registres per a pas de paràmetres"
+
+#: config/h8300/h8300.h:154
+msgid "Do not use registers for argument passing"
+msgstr "No usar registres per a pas de paràmetres"
+
+#: config/h8300/h8300.h:156
+msgid "Consider access to byte sized memory slow"
+msgstr "Considerar lent l'accés a la memòria de grandària octet"
+
+#: config/h8300/h8300.h:157
+msgid "Enable linker relaxing"
+msgstr "Activar la relaxació del enllaçador"
+
+#: config/h8300/h8300.h:158
+msgid "Generate H8/300H code"
+msgstr "Generar codi H8/300H"
+
+#: config/h8300/h8300.h:159
+msgid "Enable the normal mode"
+msgstr ""
+
+#: config/h8300/h8300.h:160
+msgid "Do not generate H8/300H code"
+msgstr "No generar codi H8/300H"
+
+#: config/h8300/h8300.h:161
+msgid "Use H8/300 alignment rules"
+msgstr "Usar regles d'alineació H8/300"
+
+#: config/i370/i370-c.c:55
+msgid "junk at end of #pragma map"
+msgstr "escombraries al final de #pragma map"
+
+#: config/i370/i370-c.c:61
+msgid "malformed #pragma map, ignored"
+msgstr "#pragma map malformat, ignorat"
+
+#: config/i370/i370.c:784
+msgid "real name is too long - alias ignored"
+msgstr "el nom real és massa llargària - s'ignora l'alies"
+
+#: config/i370/i370.c:789
+msgid "alias name is too long - alias ignored"
+msgstr "el nom d'alies és massa llargària - s'ignora l'alies"
+
+#: config/i370/i370.c:1060
+msgid "internal error--no jump follows compare:"
+msgstr "error intern--no hi ha salts a continuació de la comparança:"
+
+#. Macro to define tables used to set the flags. This is a list in braces
+#. of pairs in braces, each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/i370/i370.h:75
+msgid "Generate char instructions"
+msgstr "Generar instruccions char"
+
+#: config/i370/i370.h:76
+msgid "Do not generate char instructions"
+msgstr "No generar instruccions char"
+
+#: config/i386/i386.c:1170
+#, c-format
+msgid "code model %s not supported in PIC mode"
+msgstr "el model de codi %s no té suport en el mode PIC"
+
+#: config/i386/i386.c:1180 config/sparc/sparc.c:387
+#, c-format
+msgid "bad value (%s) for -mcmodel= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mcmodel="
+
+#: config/i386/i386.c:1195
+#, c-format
+msgid "bad value (%s) for -masm= switch"
+msgstr "valor erroni (%s) per a l'interruptor -masm="
+
+#: config/i386/i386.c:1198
+#, c-format
+msgid "code model `%s' not supported in the %s bit mode"
+msgstr "el model de codi %s no té suport en el mode %s bit"
+
+#: config/i386/i386.c:1201
+msgid "code model `large' not supported yet"
+msgstr "el model de codi \"large\" not té suport"
+
+#: config/i386/i386.c:1203
+#, c-format
+msgid "%i-bit mode not compiled in"
+msgstr "no està compilat el mode %i-bit"
+
+#: config/i386/i386.c:1230 config/i386/i386.c:1242
+#, fuzzy
+msgid "CPU you selected does not support x86-64 instruction set"
+msgstr "el CPU objectiu no té suport les instruccions THUMB"
+
+#: config/i386/i386.c:1235 config/iq2000/iq2000.c:1840
+#, c-format
+msgid "bad value (%s) for -march= switch"
+msgstr "valor erroni (%s) per a l'interruptor -march="
+
+#: config/i386/i386.c:1248
+#, fuzzy, c-format
+msgid "bad value (%s) for -mtune= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mcpu="
+
+#: config/i386/i386.c:1265
+#, c-format
+msgid "-mregparm=%d is not between 0 and %d"
+msgstr "-mregparm=%d no està entre 0 i %d"
+
+#: config/i386/i386.c:1278
+msgid "-malign-loops is obsolete, use -falign-loops"
+msgstr "-malign-loops és obsolet, usi -falign-loops"
+
+#: config/i386/i386.c:1283 config/i386/i386.c:1296 config/i386/i386.c:1309
+#, c-format
+msgid "-malign-loops=%d is not between 0 and %d"
+msgstr "-malign-loops=%d no està entre 0 i %d"
+
+#: config/i386/i386.c:1291
+msgid "-malign-jumps is obsolete, use -falign-jumps"
+msgstr "-malign-jumps és obsolet, usi -falign-jumps"
+
+#: config/i386/i386.c:1304
+msgid "-malign-functions is obsolete, use -falign-functions"
+msgstr "-malign-functions és obsolet, usi -falign-functions"
+
+#: config/i386/i386.c:1342
+#, c-format
+msgid "-mpreferred-stack-boundary=%d is not between %d and 12"
+msgstr "-mpreferred-stack-boundary=%d no està entre %d i 12"
+
+#: config/i386/i386.c:1354
+#, c-format
+msgid "-mbranch-cost=%d is not between 0 and 5"
+msgstr "-mbranch-cost=%d no està entre 0 i 5"
+
+#: config/i386/i386.c:1366
+#, c-format
+msgid "bad value (%s) for -mtls-dialect= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mtls-dialect="
+
+#: config/i386/i386.c:1395
+msgid "-malign-double makes no sense in the 64bit mode"
+msgstr "-malign-double no té sentit en el mode 64 bit"
+
+#: config/i386/i386.c:1397
+msgid "-mrtd calling convention not supported in the 64bit mode"
+msgstr "la convenció de cridades -mrtd no té suport en el mode 64 bit"
+
+#: config/i386/i386.c:1419 config/i386/i386.c:1430
+msgid "SSE instruction set disabled, using 387 arithmetics"
+msgstr "el conjunt d'instruccions SSE està desactivat, usant l'aritmètica 387"
+
+#: config/i386/i386.c:1435
+msgid "387 instruction set disabled, using SSE arithmetics"
+msgstr "el conjunt d'instruccions 387 està desactivat, usant l'aritmètica SSE"
+
+#: config/i386/i386.c:1442
+#, c-format
+msgid "bad value (%s) for -mfpmath= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mfpmath="
+
+#: config/i386/i386.c:1590 config/i386/i386.c:1601
+#, fuzzy
+msgid "fastcall and stdcall attributes are not compatible"
+msgstr "-f%s i -msdata=%s són incompatibles"
+
+#: config/i386/i386.c:1594 config/i386/i386.c:1650
+#, fuzzy
+msgid "fastcall and regparm attributes are not compatible"
+msgstr "-f%s i -msdata=%s són incompatibles"
+
+#: config/i386/i386.c:1637
+#, c-format
+msgid "`%s' attribute requires an integer constant argument"
+msgstr "l'atribut \"%s\" requereix una constant entera com argument"
+
+#: config/i386/i386.c:1643
+#, c-format
+msgid "argument to `%s' attribute larger than %d"
+msgstr "l'argument per a l'atribut \"%s\" és més gran que %d"
+
+#: config/i386/i386.c:2605
+msgid "SSE vector argument without SSE enabled changes the ABI"
+msgstr ""
+
+#: config/i386/i386.c:2621
+msgid "MMX vector argument without MMX enabled changes the ABI"
+msgstr ""
+
+#: config/i386/i386.c:2849
+msgid "SSE vector return without SSE enabled changes the ABI"
+msgstr ""
+
+#: config/i386/i386.c:6823
+msgid "invalid UNSPEC as operand"
+msgstr "UNSPEC invàlid com operant"
+
+#: config/i386/i386.c:7081
+msgid "extended registers have no high halves"
+msgstr "els registres estesos no tenen meitats superiors"
+
+#: config/i386/i386.c:7096
+msgid "unsupported operand size for extended register"
+msgstr "grandària d'operant sense suport per al registre estès"
+
+#: config/i386/i386.c:7411
+msgid "operand is neither a constant nor a condition code, invalid operand code 'c'"
+msgstr "l'operant no és una constant ni un codi de condició, codi d'operant \"c\" invàlid"
+
+#: config/i386/i386.c:7457
+#, c-format
+msgid "invalid operand code `%c'"
+msgstr "codi d'operant \"%c\" invàlid"
+
+#: config/i386/i386.c:7500
+msgid "invalid constraints for operand"
+msgstr "restriccions invàlides per a l'operant"
+
+#: config/i386/i386.c:12014
+msgid "unknown insn mode"
+msgstr "mode insn desconegut"
+
+#: config/i386/i386.c:14102 config/i386/i386.c:14138
+#, c-format
+msgid "selector must be an integer constant in the range 0..%i"
+msgstr ""
+
+#: config/i386/i386.c:14366
+msgid "shift must be an immediate"
+msgstr "el desplaçament deu ser un immediat"
+
+#: config/i386/i386.c:15389
+#, fuzzy, c-format
+msgid "`%s' incompatible attribute ignored"
+msgstr "s'ignora l'atribut \"%s\""
+
+#: config/i386/winnt.c:104
+#, fuzzy
+msgid "%Jfunction `%D' definition is marked dllimport."
+msgstr "la definició de la funció \"%s\" està marcada com dllimport"
+
+#: config/i386/winnt.c:112
+#, fuzzy
+msgid "%Jvariable `%D' definition is marked dllimport."
+msgstr "la variable \"%s\" està marcada com dllimport"
+
+#: config/i386/winnt.c:132
+msgid "%Jexternal linkage required for symbol '%D' because of '%s' attribute."
+msgstr ""
+
+#: config/i386/winnt.c:149
+#, c-format
+msgid "`%s' attribute only applies to variables"
+msgstr "l'atribut \"%s\" solament aplica a variables"
+
+#: config/i386/winnt.c:248
+#, fuzzy
+msgid "%Jfunction '%D' is defined after prior declaration as dllimport: attribute ignored"
+msgstr "la funció inline \"%s\" està declarada com dllimport: s'ignora l'atribut."
+
+#: config/i386/winnt.c:259
+#, fuzzy
+msgid "%Jinline function '%D' is declared as dllimport: attribute ignored."
+msgstr "la funció inline \"%s\" està declarada com dllimport: s'ignora l'atribut."
+
+#: config/i386/winnt.c:271
+msgid "%Jdefinition of static data member '%D' of dllimport'd class."
+msgstr ""
+
+#: config/i386/winnt.c:330
+msgid "%Jinconsistent dll linkage for '%D', dllexport assumed."
+msgstr ""
+
+#: config/i386/winnt.c:372
+#, c-format
+msgid "`%s' declared as both exported to and imported from a DLL"
+msgstr "\"%s\" és declarat com exportat a i importat d'una DLLal mateix temps"
+
+#: config/i386/winnt.c:381
+msgid "%Jfailure in redeclaration of '%D': dllimport'd symbol lacks external linkage."
+msgstr ""
+
+#: config/i386/winnt.c:530
+msgid "%J'%D' defined locally after being referenced with dllimport linkage"
+msgstr ""
+
+#: config/i386/winnt.c:533
+msgid "%J'%D' redeclared without dllimport attribute after being referenced with dllimport linkage"
+msgstr ""
+
+#: config/i386/winnt.c:702
+#, fuzzy
+msgid "%J'%D' causes a section type conflict"
+msgstr "%s causa un conflicte de tipus de secció"
+
+#: config/i386/cygming.h:40
+msgid "Use the Cygwin interface"
+msgstr "Usar la interfície Cygwin"
+
+#: config/i386/cygming.h:41
+msgid "Use the Mingw32 interface"
+msgstr "Usar la interfície Mingw32"
+
+#: config/i386/cygming.h:42
+msgid "Create GUI application"
+msgstr "Crear una aplicació amb interfície gràfica d'usuari (GUI)"
+
+#: config/i386/cygming.h:43
+msgid "Don't set Windows defines"
+msgstr "No establir les definicions de Windows"
+
+#: config/i386/cygming.h:44
+msgid "Set Windows defines"
+msgstr "Establir les definicions de Windows"
+
+#: config/i386/cygming.h:45
+msgid "Create console application"
+msgstr "Crear una aplicació de consola"
+
+#: config/i386/cygming.h:46
+msgid "Generate code for a DLL"
+msgstr "Generar codi per a una DLL"
+
+#: config/i386/cygming.h:48
+msgid "Ignore dllimport for functions"
+msgstr "Ignorar dllimport per a funcions"
+
+#: config/i386/cygming.h:50
+msgid "Use Mingw-specific thread support"
+msgstr "Usar suport de fils específic de Mingw"
+
+#: config/i386/cygming.h:169
+#, c-format
+msgid "-f%s ignored for target (all code is position independent)"
+msgstr "s'ignora -f%s per a l'objectiu (tot el codi és independent de posició)"
+
+#: config/i386/djgpp.h:191
+msgid "-mbnu210 is ignored (option is obsolete)"
+msgstr "s'ignora -mbnu210 (l'opció és obsoleta)."
+
+#: config/i386/i386-interix.h:256
+#, fuzzy
+msgid "ms-bitfields not supported for objc"
+msgstr "-f%s no té suport: ignorat"
+
+#. Deprecated.
+#. Deprecated.
+#. Deprecated.
+#. Deprecated.
+#. Deprecated.
+#. Deprecated.
+#. Deprecated.
+#. Deprecated.
+#: config/i386/i386.h:341
+msgid "Alternate calling convention"
+msgstr "Convenció de cridada alternativa"
+
+#: config/i386/i386.h:343 config/m68k/m68k.h:344 config/ns32k/ns32k.h:144
+msgid "Use normal calling convention"
+msgstr "Usar convenció de cridada normal"
+
+#: config/i386/i386.h:345
+msgid "Align some doubles on dword boundary"
+msgstr "Alinear alguns dobles en límits de dword"
+
+#: config/i386/i386.h:347
+msgid "Align doubles on word boundary"
+msgstr "Alinear dobles en límits de word"
+
+#: config/i386/i386.h:349
+msgid "Uninitialized locals in .bss"
+msgstr "Locals sense valors inicials en .bss"
+
+#: config/i386/i386.h:351
+msgid "Uninitialized locals in .data"
+msgstr "Locals sense valors inicials en .data"
+
+#: config/i386/i386.h:353 config/m68k/linux.h:35 config/ns32k/ns32k.h:167
+msgid "Use IEEE math for fp comparisons"
+msgstr "Usar matemàtica IEEE per a comparances fp"
+
+#: config/i386/i386.h:355 config/ns32k/ns32k.h:169
+msgid "Do not use IEEE math for fp comparisons"
+msgstr "No usar matemàtica IEEE per a comparances fp"
+
+#: config/i386/i386.h:357
+msgid "Return values of functions in FPU registers"
+msgstr "Retornar valors de funcions en registres FPU"
+
+#: config/i386/i386.h:359
+msgid "Do not return values of functions in FPU registers"
+msgstr "No retornar valors de funcions en registres FPU"
+
+#: config/i386/i386.h:361
+msgid "Do not generate sin, cos, sqrt for FPU"
+msgstr "No generar sin, cos, sqrt per a FPU"
+
+#: config/i386/i386.h:363
+msgid "Generate sin, cos, sqrt for FPU"
+msgstr "Generar sin, cos, sqrt per a FPU"
+
+#: config/i386/i386.h:365
+msgid "Omit the frame pointer in leaf functions"
+msgstr "Ometre el marc de referència per a les funcions fulles"
+
+#: config/i386/i386.h:368
+msgid "Enable stack probing"
+msgstr "Habilitar la prova de la pila"
+
+#. undocumented
+#. undocumented
+#: config/i386/i386.h:373
+msgid "Align destination of the string operations"
+msgstr "Alinear destinació de les operacions de cadenes"
+
+#: config/i386/i386.h:375
+msgid "Do not align destination of the string operations"
+msgstr "No alinear destinació de les operacions de cadenes"
+
+#: config/i386/i386.h:377
+msgid "Inline all known string operations"
+msgstr "Convertir a inline totes les operacions de cadenes conegudes"
+
+#: config/i386/i386.h:379
+msgid "Do not inline all known string operations"
+msgstr "No convertir a inline totes les operacions de cadenes conegudes"
+
+#: config/i386/i386.h:381 config/i386/i386.h:385
+msgid "Use push instructions to save outgoing arguments"
+msgstr "Usar instruccions push per a guardar els arguments de sortida"
+
+#: config/i386/i386.h:383 config/i386/i386.h:387
+msgid "Do not use push instructions to save outgoing arguments"
+msgstr "No usar instruccions push per a guardar els arguments de sortida"
+
+#: config/i386/i386.h:389
+msgid "Support MMX built-in functions"
+msgstr "Donar suport per a funcions internes MMX"
+
+#: config/i386/i386.h:391
+msgid "Do not support MMX built-in functions"
+msgstr "No donar suport per a funcions internes MMX"
+
+#: config/i386/i386.h:393
+msgid "Support 3DNow! built-in functions"
+msgstr "Donar suport per a funcions internes 3DNow!"
+
+#: config/i386/i386.h:395
+msgid "Do not support 3DNow! built-in functions"
+msgstr "No donar suport per a funcions internes 3DNow!"
+
+#: config/i386/i386.h:397
+msgid "Support MMX and SSE built-in functions and code generation"
+msgstr "Donar suport per a funcions internes MMX i SSE"
+
+#: config/i386/i386.h:399
+msgid "Do not support MMX and SSE built-in functions and code generation"
+msgstr "No donar suport per a funcions internes MMX i SSE"
+
+#: config/i386/i386.h:401
+msgid "Support MMX, SSE and SSE2 built-in functions and code generation"
+msgstr "Donar suport per a funcions internes MMX, SSE i SSE2"
+
+#: config/i386/i386.h:403
+msgid "Do not support MMX, SSE and SSE2 built-in functions and code generation"
+msgstr "No donar suport per a funcions internes MMX, SSE i SSE2"
+
+#: config/i386/i386.h:405
+#, fuzzy
+msgid "Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation"
+msgstr "Donar suport per a funcions internes MMX, SSE i SSE2"
+
+#: config/i386/i386.h:407
+#, fuzzy
+msgid "Do not support MMX, SSE, SSE2 and SSE3 built-in functions and code generation"
+msgstr "No donar suport per a funcions internes MMX, SSE i SSE2"
+
+#: config/i386/i386.h:409
+msgid "sizeof(long double) is 16"
+msgstr "sizeof(long double) és 16."
+
+#: config/i386/i386.h:411
+msgid "sizeof(long double) is 12"
+msgstr "sizeof(long double) és 12."
+
+#: config/i386/i386.h:413
+msgid "Generate 64bit x86-64 code"
+msgstr "Generar codi 64 bit per a x86-64"
+
+#: config/i386/i386.h:415
+msgid "Generate 32bit i386 code"
+msgstr "Generar codi 32 bit per a i386"
+
+#: config/i386/i386.h:417
+msgid "Use native (MS) bitfield layout"
+msgstr ""
+
+#: config/i386/i386.h:419
+msgid "Use gcc default bitfield layout"
+msgstr ""
+
+#: config/i386/i386.h:421
+msgid "Use red-zone in the x86-64 code"
+msgstr "Usar red-zone en el codi x86-64"
+
+#: config/i386/i386.h:423
+msgid "Do not use red-zone in the x86-64 code"
+msgstr "No usar red-zone en el codi x86-64"
+
+#: config/i386/i386.h:425
+#, c-format
+msgid "Use direct references against %gs when accessing tls data"
+msgstr ""
+
+#: config/i386/i386.h:427
+#, c-format
+msgid "Do not use direct references against %gs when accessing tls data"
+msgstr ""
+
+#. This macro is similar to `TARGET_SWITCHES' but defines names of
+#. command options that have values. Its definition is an
+#. initializer with a subgrouping for each command option.
+#.
+#. Each subgrouping contains a string constant, that defines the
+#. fixed part of the option name, and the address of a variable. The
+#. variable, type `char *', is set to the variable part of the given
+#. option if the fixed part matches. The actual option name is made
+#. by appending `-m' to the specified name.
+#: config/i386/i386.h:461 config/ia64/ia64.h:269 config/rs6000/rs6000.h:437
+#: config/s390/s390.h:146 config/sparc/sparc.h:656
+msgid "Schedule code for given CPU"
+msgstr "Codi de planificador per al CPU donat"
+
+#: config/i386/i386.h:463
+msgid "Generate floating point mathematics using given instruction set"
+msgstr "Generar matemàtiques de coma flotant usant el conjunt d'instruccions donat"
+
+#: config/i386/i386.h:465 config/s390/s390.h:148
+msgid "Generate code for given CPU"
+msgstr "Generar codi per al CPU donat"
+
+#: config/i386/i386.h:467
+msgid "Number of registers used to pass integer arguments"
+msgstr "Nombre de registres usats per a passar arguments enters"
+
+#. TARGET_DEFAULT is defined in m68k-none.h, netbsd.h, etc.
+#. This macro is similar to `TARGET_SWITCHES' but defines names of
+#. command options that have values. Its definition is an
+#. initializer with a subgrouping for each command option.
+#.
+#. Each subgrouping contains a string constant, that defines the
+#. fixed part of the option name, and the address of a variable. The
+#. variable, type `char *', is set to the variable part of the given
+#. option if the fixed part matches. The actual option name is made
+#. by appending `-m' to the specified name.
+#: config/i386/i386.h:469 config/m68k/m68k.h:360
+msgid "Loop code aligned to this power of 2"
+msgstr "El codi de cicle és alineat a aquesta potència de 2"
+
+#: config/i386/i386.h:471 config/m68k/m68k.h:362
+msgid "Jump targets are aligned to this power of 2"
+msgstr "Els objectius de salt són alineats a aquesta potència de 2"
+
+#: config/i386/i386.h:473 config/m68k/m68k.h:364
+msgid "Function starts are aligned to this power of 2"
+msgstr "Els inicis de les funcions són alineats a aquesta potència de 2"
+
+#: config/i386/i386.h:476
+msgid "Attempt to keep stack aligned to this power of 2"
+msgstr "Es tracta de mantenir la pila alineada a aquesta potència de 2"
+
+#: config/i386/i386.h:478
+msgid "Branches are this expensive (1-5, arbitrary units)"
+msgstr "Les ramificacions són així de cares (1-5, unitats arbitràries)"
+
+#: config/i386/i386.h:480
+msgid "Use given x86-64 code model"
+msgstr "Usar el mpdel de codi x86-64 donat"
+
+#. Undocumented.
+#. Undocumented.
+#: config/i386/i386.h:486
+msgid "Use given assembler dialect"
+msgstr "Usar el dialecte del ensemblador donat"
+
+#: config/i386/i386.h:488
+msgid "Use given thread-local storage dialect"
+msgstr "Usar el dialecte d'emmagatzematge thread-local donat"
+
+#: config/i386/sco5.h:292
+msgid "Generate ELF output"
+msgstr "Generar sortida ELF"
+
+#. If the environment variable DJDIR is not defined, then DJGPP is not installed correctly and GCC will quickly become confused with the default prefix settings. Report the problem now so the user doesn't receive deceptive "file not found" error messages later.
+#. DJDIR is automatically defined by the DJGPP environment config file pointed to by the environment variable DJGPP. Examine DJGPP to try and figure out what's wrong.
+#: config/i386/xm-djgpp.h:61
+msgid "environment variable DJGPP not defined"
+msgstr "no es va definir la variable d'ambient DJGPP"
+
+#: config/i386/xm-djgpp.h:63
+#, c-format
+msgid "environment variable DJGPP points to missing file '%s'"
+msgstr "la variable d'ambient DJGPP apunta al fitxer faltant\"%s\""
+
+#: config/i386/xm-djgpp.h:66
+#, c-format
+msgid "environment variable DJGPP points to corrupt file '%s'"
+msgstr "la variable d'ambient DJGPP apunta al fitxer corrupte \"%s\""
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/i860/i860.h:60
+#, fuzzy
+msgid "Generate code which uses the FPU"
+msgstr "Generar codi sense registre GP"
+
+#: config/i860/i860.h:61 config/i860/i860.h:62
+#, fuzzy
+msgid "Do not generate code which uses the FPU"
+msgstr "No generar codi per a un Sun FPA"
+
+#: config/i960/i960-c.c:68
+msgid "sorry, not implemented: #pragma align NAME=SIZE"
+msgstr "disculpi, no s'ha implementar: #pragma align NAME=SIZE"
+
+#: config/i960/i960-c.c:73
+msgid "malformed #pragma align - ignored"
+msgstr "#pragma align mal format - ignorat"
+
+#: config/i960/i960-c.c:111
+msgid "sorry, not implemented: #pragma noalign NAME"
+msgstr "disculpi, no s'ha implementat: #pragma noalign NAME"
+
+#: config/i960/i960.c:134 config/i960/i960.c:144
+msgid "conflicting architectures defined - using C series"
+msgstr "es van definir arquitectures en conflicte - usant les sèries C"
+
+#: config/i960/i960.c:139
+msgid "conflicting architectures defined - using K series"
+msgstr "es van definir arquitectures en conflicte - usant les sèries K"
+
+#: config/i960/i960.c:154
+msgid "iC2.0 and iC3.0 are incompatible - using iC3.0"
+msgstr "iC2.0 i iC3.0 són incompatibles - usant iC3.0"
+
+#: config/i960/i960.c:1456 config/m68k/m68k.c:600 config/rs6000/rs6000.c:11364
+msgid "stack limit expression is not supported"
+msgstr "no es dóna suport a l'expressió del límit de la pila"
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#. ??? Not all ten of these architecture variations actually exist, but I
+#. am not sure which are real and which aren't.
+#: config/i960/i960.h:250
+msgid "Generate SA code"
+msgstr "Generar codi SA"
+
+#: config/i960/i960.h:253
+msgid "Generate SB code"
+msgstr "Generar codi SB"
+
+#. {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR), N_("Generate SC code")},
+#: config/i960/i960.h:258
+msgid "Generate KA code"
+msgstr "Generar codi KA"
+
+#: config/i960/i960.h:261
+msgid "Generate KB code"
+msgstr "Generar codi KB"
+
+#. {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR), N_("Generate KC code")},
+#: config/i960/i960.h:266
+msgid "Generate JA code"
+msgstr "Generar codi JA"
+
+#: config/i960/i960.h:268
+msgid "Generate JD code"
+msgstr "Generar codi JD"
+
+#: config/i960/i960.h:271
+msgid "Generate JF code"
+msgstr "Generar codi JF"
+
+#: config/i960/i960.h:273
+msgid "generate RP code"
+msgstr "generar codi RP"
+
+#: config/i960/i960.h:276
+msgid "Generate MC code"
+msgstr "Generar codi MC"
+
+#: config/i960/i960.h:279
+msgid "Generate CA code"
+msgstr "Generar codi CA"
+
+#. {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES| TARGET_FLAG_BRANCH_PREDICT|TARGET_FLAG_CODE_ALIGN), N_("Generate CB code")}, {"cc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT| TARGET_FLAG_CODE_ALIGN), N_("Generate CC code")},
+#: config/i960/i960.h:289
+msgid "Generate CF code"
+msgstr "Generar codi CF"
+
+#: config/i960/i960.h:293 config/mips/mips.h:552 config/pa/pa.h:266
+msgid "Use software floating point"
+msgstr "Usar coma flotant de programari"
+
+#: config/i960/i960.h:295
+msgid "Use alternate leaf function entries"
+msgstr "Usar entrades de funció fulles alternades"
+
+#: config/i960/i960.h:297
+msgid "Do not use alternate leaf function entries"
+msgstr "No usar entrades de funció fulles alternades"
+
+#: config/i960/i960.h:299
+msgid "Perform tail call optimization"
+msgstr "Realitzar optimització de la cridada de l'extrem"
+
+#: config/i960/i960.h:301
+msgid "Do not perform tail call optimization"
+msgstr "No realitzar optimització de la cridada de l'extrem"
+
+#: config/i960/i960.h:303
+msgid "Use complex addressing modes"
+msgstr "Usar maneres de adreçament complexos"
+
+#: config/i960/i960.h:305
+msgid "Do not use complex addressing modes"
+msgstr "No usar maneres de adreçament complexos"
+
+#: config/i960/i960.h:307
+msgid "Align code to 8 byte boundary"
+msgstr "Alinear el codi a límits de 8 octet"
+
+#: config/i960/i960.h:309
+msgid "Do not align code to 8 byte boundary"
+msgstr "No alinear el codi a límits de 8 octet"
+
+#. {"clean-linkage", (TARGET_FLAG_CLEAN_LINKAGE), N_("Force use of prototypes")}, {"no-clean-linkage", -(TARGET_FLAG_CLEAN_LINKAGE), N_("Do not force use of prototypes")},
+#: config/i960/i960.h:315 config/i960/i960.h:317
+msgid "Enable compatibility with iC960 v2.0"
+msgstr "Activar la compatibilitat amb iC960 v2.0"
+
+#: config/i960/i960.h:319
+msgid "Enable compatibility with iC960 v3.0"
+msgstr "Activar la compatibilitat amb iC960 v3.0"
+
+#: config/i960/i960.h:321 config/i960/i960.h:323
+msgid "Enable compatibility with ic960 assembler"
+msgstr "Activar la compatibilitat amb el assemblador ic960"
+
+#: config/i960/i960.h:325
+msgid "Do not permit unaligned accesses"
+msgstr "No permetre accessos sense alinear"
+
+#: config/i960/i960.h:327
+msgid "Permit unaligned accesses"
+msgstr "Permetre accessos sense alinear"
+
+#: config/i960/i960.h:329
+msgid "Layout types like Intel's v1.3 gcc"
+msgstr "Presentar tipus com en el gcc v1.3 de Intel"
+
+#: config/i960/i960.h:331
+msgid "Do not layout types like Intel's v1.3 gcc"
+msgstr "No presentar tipus com en el gcc v1.3 de Intel"
+
+#: config/i960/i960.h:333 config/sparc/freebsd.h:80 config/sparc/linux.h:91
+#: config/sparc/linux64.h:103 config/sparc/netbsd-elf.h:215
+msgid "Use 64 bit long doubles"
+msgstr "Usar long doubles de 64 bit"
+
+#: config/i960/i960.h:335
+msgid "Enable linker relaxation"
+msgstr "Activar la relaxació del enllaçador"
+
+#: config/i960/i960.h:337
+msgid "Do not enable linker relaxation"
+msgstr "Desactivar la relaxació del enllaçador"
+
+#: config/ia64/ia64-c.c:52
+msgid "malformed #pragma builtin"
+msgstr "secció #pragma builtin malformada"
+
+#: config/ia64/ia64.c:1025 config/m32r/m32r.c:354
+#, c-format
+msgid "invalid argument of `%s' attribute"
+msgstr "invàlid argument per a l'atribut \"%s\""
+
+#: config/ia64/ia64.c:1037
+#, fuzzy
+msgid "%Jan address area attribute cannot be specified for local variables"
+msgstr "no es pot especificar un atribut d'àrea de dades per a variables locals"
+
+#: config/ia64/ia64.c:1044
+#, fuzzy
+msgid "%Jaddress area of '%s' conflicts with previous declaration"
+msgstr "l'àrea de dades de \"%s\" en conflicte amb una declaració prèvia"
+
+#: config/ia64/ia64.c:1051
+#, fuzzy
+msgid "%Jaddress area attribute cannot be specified for functions"
+msgstr "no es pot especificar un atribut d'àrea de dades per a variables locals"
+
+#: config/ia64/ia64.c:4305
+msgid "ia64_print_operand: unknown code"
+msgstr "ia64_print_operand: codi desconegut"
+
+#: config/ia64/ia64.c:4645
+msgid "value of -mfixed-range must have form REG1-REG2"
+msgstr "el valor de -mfixed-range deu ser de la forma REG1-REG2"
+
+#: config/ia64/ia64.c:4672
+#, c-format
+msgid "%s-%s is an empty range"
+msgstr "%s-%s és un rang buit"
+
+#: config/ia64/ia64.c:4720
+msgid "cannot optimize floating point division for both latency and throughput"
+msgstr "no es pot optimitzar la divisió de coma flotant per a latència i sortida al mateix temps"
+
+#: config/ia64/ia64.c:4726
+msgid "cannot optimize integer division for both latency and throughput"
+msgstr "no es pot optimitzar la divisió entera per a latència i sortida al mateix temps"
+
+#: config/ia64/ia64.c:4732
+#, fuzzy
+msgid "cannot optimize square root for both latency and throughput"
+msgstr "no es pot optimitzar la divisió entera per a latència i sortida al mateix temps"
+
+#: config/ia64/ia64.c:4738
+msgid "not yet implemented: latency-optimized inline square root"
+msgstr ""
+
+#: config/ia64/ia64.c:4750
+#, c-format
+msgid "bad value (%s) for -mtls-size= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mtls-size="
+
+#: config/ia64/ia64.c:4766
+#, fuzzy, c-format
+msgid "bad value (%s) for -tune= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mcpu="
+
+#. This macro defines names of command options to set and clear bits in
+#. `target_flags'. Its definition is an initializer with a subgrouping for
+#. each command option.
+#: config/ia64/ia64.h:172
+msgid "Generate big endian code"
+msgstr "Generar codi big endian"
+
+#: config/ia64/ia64.h:174 config/mcore/mcore.h:154
+msgid "Generate little endian code"
+msgstr "Generar codi little endian"
+
+#: config/ia64/ia64.h:176
+msgid "Generate code for GNU as"
+msgstr "Generar codi com de GNU"
+
+#: config/ia64/ia64.h:178
+msgid "Generate code for Intel as"
+msgstr "Generar codi com de Intel"
+
+#: config/ia64/ia64.h:180
+msgid "Generate code for GNU ld"
+msgstr "Generar codi per a ld de GNU"
+
+#: config/ia64/ia64.h:182
+msgid "Generate code for Intel ld"
+msgstr "Generar codi per a ld de Intel"
+
+#: config/ia64/ia64.h:184
+msgid "Generate code without GP reg"
+msgstr "Generar codi sense registre GP"
+
+#: config/ia64/ia64.h:186
+msgid "Emit stop bits before and after volatile extended asms"
+msgstr "Emetre bits de desocupada abans i després de asms estesos amb volatile"
+
+#: config/ia64/ia64.h:188
+msgid "Don't emit stop bits before and after volatile extended asms"
+msgstr "No emetre bits de desocupada abans i després de asmsestesos amb volatile"
+
+#: config/ia64/ia64.h:190
+msgid "Emit code for Itanium (TM) processor B step"
+msgstr "Emetre codi per a Itanium (TM) processador de pas B"
+
+#: config/ia64/ia64.h:192
+msgid "Use in/loc/out register names"
+msgstr "Usar noms de registre in/loc/out"
+
+#: config/ia64/ia64.h:194
+msgid "Disable use of sdata/scommon/sbss"
+msgstr "Desactivar l'ús de sdata/scommon/sbss"
+
+#: config/ia64/ia64.h:196
+msgid "Enable use of sdata/scommon/sbss"
+msgstr "Activar l'ús de sdata/scommon/sbss"
+
+#: config/ia64/ia64.h:198
+msgid "gp is constant (but save/restore gp on indirect calls)"
+msgstr "gp és constant (però hi ha save/restore de gp en cridades indirectes)"
+
+#: config/ia64/ia64.h:200
+msgid "Generate self-relocatable code"
+msgstr "Generar codi self-relocatable"
+
+#: config/ia64/ia64.h:202
+msgid "Generate inline floating point division, optimize for latency"
+msgstr "Generar divisió de coma flotant inline, optimitzada per a latència"
+
+#: config/ia64/ia64.h:204
+msgid "Generate inline floating point division, optimize for throughput"
+msgstr "Generar divisió de coma flotant inline, optimitzada per a sortida"
+
+#: config/ia64/ia64.h:206
+msgid "Generate inline integer division, optimize for latency"
+msgstr "Generar divisió entera inline, optimitzada per a latència"
+
+#: config/ia64/ia64.h:208
+msgid "Generate inline integer division, optimize for throughput"
+msgstr "Generar divisió entera inline, optimitzada per a sortida"
+
+#: config/ia64/ia64.h:210
+#, fuzzy
+msgid "Generate inline square root, optimize for latency"
+msgstr "Generar divisió entera inline, optimitzada per a latència"
+
+#: config/ia64/ia64.h:212
+#, fuzzy
+msgid "Generate inline square root, optimize for throughput"
+msgstr "Generar divisió entera inline, optimitzada per a sortida"
+
+#: config/ia64/ia64.h:214
+msgid "Enable Dwarf 2 line debug info via GNU as"
+msgstr "Activar la informació de la línia de depuració Dwarf2 a través com de GNU"
+
+#: config/ia64/ia64.h:216
+msgid "Disable Dwarf 2 line debug info via GNU as"
+msgstr "Desactivar la informació de la línia de depuració Dwarf 2 a través com de GNU"
+
+#: config/ia64/ia64.h:218
+msgid "Enable earlier placing stop bits for better scheduling"
+msgstr ""
+
+#: config/ia64/ia64.h:220
+#, fuzzy
+msgid "Disable earlier placing stop bits"
+msgstr "Desactivar les funcions paral·leles"
+
+#: config/ia64/ia64.h:265
+msgid "Specify range of registers to make fixed"
+msgstr "Especifica el rang de registres a convertir en fixos"
+
+#: config/ip2k/ip2k.c:1074
+msgid "bad operand"
+msgstr "operant invàlid"
+
+#: config/iq2000/iq2000.c:1816
+#, c-format
+msgid "bad value (%s) for -mcpu= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mcpu="
+
+#: config/iq2000/iq2000.c:1845
+#, fuzzy, c-format
+msgid "The compiler does not support -march=%s."
+msgstr "%s no té suport per a %s"
+
+#: config/iq2000/iq2000.c:2232
+#, fuzzy, c-format
+msgid "gp_offset (%ld) or end_offset (%ld) is less than zero."
+msgstr "gp_offset (%ld) o end_offset (%ld) és menor a zero"
+
+#: config/iq2000/iq2000.c:3023
+#, fuzzy, c-format
+msgid "argument `%d' is not a constant"
+msgstr "l'argument de \"asm\" no és una cadena constant"
+
+#: config/iq2000/iq2000.c:3314 config/xtensa/xtensa.c:2095
+msgid "PRINT_OPERAND_ADDRESS, null pointer"
+msgstr "PRINT_OPERAND_ADDRESS, punter nul"
+
+#: config/iq2000/iq2000.c:3469
+#, fuzzy, c-format
+msgid "PRINT_OPERAND: Unknown punctuation '%c'"
+msgstr "PRINT_OPERAND: puntuació desconeguda \"%c\""
+
+#: config/iq2000/iq2000.c:3478 config/mips/mips.c:5464
+#: config/xtensa/xtensa.c:1949
+msgid "PRINT_OPERAND null pointer"
+msgstr "PRINT_OPERAND punter nul"
+
+#: config/iq2000/iq2000.c:3547
+#, c-format
+msgid "invalid %%P operand"
+msgstr "operand invàlid per a %%P"
+
+#: config/iq2000/iq2000.c:3555 config/rs6000/rs6000.c:8949
+#, c-format
+msgid "invalid %%p value"
+msgstr "valor invàlid per a %%p"
+
+#: config/iq2000/iq2000.c:3619 config/mips/mips.c:5594
+#, c-format
+msgid "invalid use of %%d, %%x, or %%X"
+msgstr "ùs invàlid de %%d, %%x, o %%X"
+
+#: config/iq2000/iq2000.h:72 config/mn10300/mn10300.h:74
+msgid "No default crt0.o"
+msgstr "No està el crt0.o per omissió"
+
+#: config/iq2000/iq2000.h:74
+msgid "Use GP relative sdata/sbss sections"
+msgstr "Usar seccions sdata/sbss relatives a GP"
+
+#: config/iq2000/iq2000.h:76
+msgid "Don't use GP relative sdata/sbss sections"
+msgstr "No usar seccions sdata/sbss relatives a GP"
+
+#: config/iq2000/iq2000.h:78 config/mips/mips.h:576
+msgid "Use ROM instead of RAM"
+msgstr "Usar ROM enlloc de RAM"
+
+#: config/iq2000/iq2000.h:80 config/mips/mips.h:578
+msgid "Don't use ROM instead of RAM"
+msgstr "No usar ROM enlloc de RAM"
+
+#: config/iq2000/iq2000.h:82 config/mips/mips.h:580
+msgid "Put uninitialized constants in ROM (needs -membedded-data)"
+msgstr "Posar les constants sense inicialitzar en ROM (necessita -membedded-data)"
+
+#: config/iq2000/iq2000.h:84 config/mips/mips.h:582
+msgid "Don't put uninitialized constants in ROM"
+msgstr "No posar les constants sense inicialitzar en ROM"
+
+#: config/iq2000/iq2000.h:106 config/mips/mips.h:744 config/pa/pa.h:310
+msgid "Specify CPU for scheduling purposes"
+msgstr "Especificar el CPU per a propòsits de calendarització"
+
+#: config/iq2000/iq2000.h:108 config/mips/mips.h:746
+msgid "Specify CPU for code generation purposes"
+msgstr "Especificar el CPU per a propòsits de generació de codi"
+
+#: config/m32r/m32r.c:172
+#, c-format
+msgid "bad value (%s) for -mmodel switch"
+msgstr "valor erroni (%s) per a l'interruptor -mmodel"
+
+#: config/m32r/m32r.c:181
+#, c-format
+msgid "bad value (%s) for -msdata switch"
+msgstr "valor erroni (%s) per a l'interruptor -msdata"
+
+#: config/m32r/m32r.c:188
+#, fuzzy, c-format
+msgid "bad value (%s) for -flush-trap=n (0=<n<=15)"
+msgstr "valor erroni (%s) per a l'interruptor -msdata"
+
+#: config/m32r/m32r.c:2295
+#, c-format
+msgid "invalid operand to %%s code"
+msgstr "invàlid operand per al codi %%s"
+
+#: config/m32r/m32r.c:2302
+#, c-format
+msgid "invalid operand to %%p code"
+msgstr "invàlid operand per al codi %%p"
+
+#: config/m32r/m32r.c:2357
+msgid "bad insn for 'A'"
+msgstr "insn erroni per a \"A\""
+
+#: config/m32r/m32r.c:2404
+#, c-format
+msgid "invalid operand to %%T/%%B code"
+msgstr "invàlid operand per al codi %%T/%%B"
+
+#: config/m32r/m32r.c:2427
+#, c-format
+msgid "invalid operand to %%N code"
+msgstr "invàlid operand per al codi %%N"
+
+#: config/m32r/m32r.c:2460
+msgid "pre-increment address is not a register"
+msgstr "l'adreça de pre-increment no és un registre"
+
+#: config/m32r/m32r.c:2467
+msgid "pre-decrement address is not a register"
+msgstr "l'adreça de pre-decrement no és un registre"
+
+#: config/m32r/m32r.c:2474
+msgid "post-increment address is not a register"
+msgstr "l'adreça de post-increment no és un registre"
+
+#: config/m32r/m32r.c:2550 config/m32r/m32r.c:2566
+#: config/rs6000/rs6000.c:14821
+msgid "bad address"
+msgstr "adreça erroni"
+
+#: config/m32r/m32r.c:2571
+msgid "lo_sum not of register"
+msgstr "lo_sum no és un registre"
+
+#. { "relax", TARGET_RELAX_MASK, "" }, { "no-relax", -TARGET_RELAX_MASK, "" },
+#: config/m32r/m32r.h:279
+msgid "Display compile time statistics"
+msgstr "Mostrar estadístiques de tepms de compilació"
+
+#: config/m32r/m32r.h:281
+msgid "Align all loops to 32 byte boundary"
+msgstr "Alinear tots els cicles al límit de 32 octet"
+
+#: config/m32r/m32r.h:284
+msgid "Only issue one instruction per cycle"
+msgstr "Només executar una instrucció per cicle"
+
+#: config/m32r/m32r.h:287
+msgid "Prefer branches over conditional execution"
+msgstr "Preferir les branques sobre l'execució condicional"
+
+#: config/m32r/m32r.h:308
+msgid "Code size: small, medium or large"
+msgstr "Grandària del codi: small, medium o large"
+
+#: config/m32r/m32r.h:310
+msgid "Small data area: none, sdata, use"
+msgstr " Àrea de dades small: none, sdata, use"
+
+#: config/m32r/m32r.h:312 config/mips/mips.h:752
+msgid "Don't call any cache flush functions"
+msgstr "No cridar cap funció de neteja de memòria cau"
+
+#: config/m32r/m32r.h:314 config/mips/mips.h:754
+msgid "Specify cache flush function"
+msgstr "Especificar una funció de neteja de memòria cau"
+
+#: config/m32r/m32r.h:316
+#, fuzzy
+msgid "Don't call any cache flush trap"
+msgstr "No cridar cap funció de neteja de memòria cau"
+
+#: config/m32r/m32r.h:318
+#, fuzzy
+msgid "Specify cache flush trap number"
+msgstr "Especificar una funció de neteja de memòria cau"
+
+#: config/m68hc11/m68hc11.c:280
+#, c-format
+msgid "-f%s ignored for 68HC11/68HC12 (not supported)"
+msgstr "s'ignora -f%s per a 68HC11/68HC12 (sense suport)"
+
+#: config/m68hc11/m68hc11.c:1326
+msgid "`trap' and `far' attributes are not compatible, ignoring `far'"
+msgstr ""
+
+#: config/m68hc11/m68hc11.c:1332
+msgid "`trap' attribute is already used"
+msgstr "l'atribut \"trap\" ja està en ús"
+
+#. !!!! SCz wrong here.
+#: config/m68hc11/m68hc11.c:3305 config/m68hc11/m68hc11.c:3689
+msgid "move insn not handled"
+msgstr "no es maneja move insn"
+
+#: config/m68hc11/m68hc11.c:3537 config/m68hc11/m68hc11.c:3621
+#: config/m68hc11/m68hc11.c:3892
+msgid "invalid register in the move instruction"
+msgstr "registre invàlid en la instrucció move"
+
+#: config/m68hc11/m68hc11.c:3571
+msgid "invalid operand in the instruction"
+msgstr "operant invàlid en la instrucció"
+
+#: config/m68hc11/m68hc11.c:3866
+msgid "invalid register in the instruction"
+msgstr "registre invàlid en la instrucció"
+
+#: config/m68hc11/m68hc11.c:3899
+msgid "operand 1 must be a hard register"
+msgstr "l'operant 1 deu ser un registre fix"
+
+#: config/m68hc11/m68hc11.c:3913
+msgid "invalid rotate insn"
+msgstr "rotació de insn invàlida"
+
+#: config/m68hc11/m68hc11.c:4337
+msgid "registers IX, IY and Z used in the same INSN"
+msgstr "es van usar els registres IX, IY i Z en el mateix INSN"
+
+#: config/m68hc11/m68hc11.c:4674 config/m68hc11/m68hc11.c:4974
+msgid "cannot do z-register replacement"
+msgstr "no es pot reemplaçar el registre-z"
+
+#: config/m68hc11/m68hc11.c:5037
+msgid "invalid Z register replacement for insn"
+msgstr "reemplaçament de registre Z invàlid per al insn"
+
+#. Macro to define tables used to set the flags. This is a list in braces of
+#. pairs in braces, each pair being { "NAME", VALUE } where VALUE is the bits
+#. to set or minus the bits to clear. An empty string NAME is used to
+#. identify the default VALUE.
+#: config/m68hc11/m68hc11.h:177
+msgid "Compile with 16-bit integer mode"
+msgstr "Compilar amb el mode enter de 16-bit"
+
+#: config/m68hc11/m68hc11.h:179
+msgid "Compile with 32-bit integer mode"
+msgstr "Compilar amb el mode enter de 32-bit"
+
+#: config/m68hc11/m68hc11.h:181
+msgid "Auto pre/post decrement increment allowed"
+msgstr "Es permet el pre/post decrement increment automatic"
+
+#: config/m68hc11/m68hc11.h:183
+msgid "Auto pre/post decrement increment not allowed"
+msgstr "No es permet el pre/post decrement increment automatic"
+
+#: config/m68hc11/m68hc11.h:185
+msgid "Min/max instructions allowed"
+msgstr ""
+
+#: config/m68hc11/m68hc11.h:187
+msgid "Min/max instructions not allowed"
+msgstr ""
+
+#: config/m68hc11/m68hc11.h:189
+msgid "Use call and rtc for function calls and returns"
+msgstr "Usar call i rtc per a cridades i devolucions de funció"
+
+#: config/m68hc11/m68hc11.h:191
+msgid "Use jsr and rts for function calls and returns"
+msgstr "Usar jsr i rts per a cridades i devolucions de funció"
+
+#: config/m68hc11/m68hc11.h:193
+msgid "Do not use direct addressing mode for soft registers"
+msgstr "No usar el mode d'adreçament direct per a registres soft"
+
+#: config/m68hc11/m68hc11.h:195
+msgid "Use direct addressing mode for soft registers"
+msgstr "Usar el mode d'adreçament direct per a registres soft"
+
+#: config/m68hc11/m68hc11.h:197 config/m68hc11/m68hc11.h:203
+msgid "Compile for a 68HC11"
+msgstr "Compilar per a un 68HC11"
+
+#: config/m68hc11/m68hc11.h:199 config/m68hc11/m68hc11.h:205
+msgid "Compile for a 68HC12"
+msgstr "Compilar per a un 68HC12"
+
+#: config/m68hc11/m68hc11.h:201 config/m68hc11/m68hc11.h:207
+msgid "Compile for a 68HCS12"
+msgstr "Compilar per a un 68HCS12"
+
+#. This macro is similar to `TARGET_SWITCHES' but defines names of
+#. command options that have values. Its definition is an
+#. initializer with a subgrouping for each command option.
+#.
+#. Each subgrouping contains a string constant, that defines the
+#. fixed part of the option name, and the address of a variable. The
+#. variable, type `char *', is set to the variable part of the given
+#. option if the fixed part matches. The actual option name is made
+#. by appending `-m' to the specified name.
+#: config/m68hc11/m68hc11.h:221
+msgid "Specify the register allocation order"
+msgstr "Especificar l'ordre d'assignació de registres"
+
+#: config/m68hc11/m68hc11.h:223
+msgid "Indicate the number of soft registers available"
+msgstr "Indicar el nombre de registres suaus disponibles"
+
+#: config/m68k/m68k.c:239
+#, c-format
+msgid "-malign-loops=%d is not between 1 and %d"
+msgstr "-malign-loops=%d no és entre 1 i %d"
+
+#: config/m68k/m68k.c:250
+msgid "-mshared-library-id= specified without -mid-shared-library"
+msgstr ""
+
+#: config/m68k/m68k.c:253
+#, fuzzy, c-format
+msgid "-mshared-library-id=%d is not between 0 and %d"
+msgstr "-mregparm=%d no està entre 0 i %d"
+
+#: config/m68k/m68k.c:267
+msgid "cannot specify both -msep-data and -mid-shared-library"
+msgstr ""
+
+#: config/m68k/m68k.c:282
+#, c-format
+msgid "-malign-jumps=%d is not between 1 and %d"
+msgstr "-malign-jumps=%d no és entre 1 i %d"
+
+#: config/m68k/m68k.c:293
+#, c-format
+msgid "-malign-functions=%d is not between 1 and %d"
+msgstr "-malign-functions=%d no és entre 1 i %d"
+
+#: config/m68k/m68k.c:302
+msgid "-fPIC is not currently supported on the 68000 or 68010\n"
+msgstr " -fPIC actualment no té suport en el 68000 o 68010\n"
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/m68k/m68k.h:248 config/m68k/m68k.h:250
+msgid "Generate code for a 68020"
+msgstr "Generar codi per a un 68020"
+
+#: config/m68k/m68k.h:255 config/m68k/m68k.h:258
+msgid "Generate code for a 68000"
+msgstr "Generar codi per a un 68000"
+
+#: config/m68k/m68k.h:260
+msgid "Use the bit-field instructions"
+msgstr "Usar instruccions de camps de bit"
+
+#: config/m68k/m68k.h:262
+msgid "Do not use the bit-field instructions"
+msgstr "No usar instruccions de camps de bit"
+
+#: config/m68k/m68k.h:264
+msgid "Consider type `int' to be 16 bits wide"
+msgstr "Considerar que el tipus \"int\" és de 16 bits d'amplària"
+
+#: config/m68k/m68k.h:266
+msgid "Consider type `int' to be 32 bits wide"
+msgstr "Considerar que el tipus \"int\" és de 32 bits d'amplària"
+
+#: config/m68k/m68k.h:269
+msgid "Generate code with library calls for floating point"
+msgstr "Generar codi amb cridades a biblioteques per a coma flotant"
+
+#: config/m68k/m68k.h:271
+msgid "Generate code for a 68040, without any new instructions"
+msgstr "Generar codi per a un 68040, sense cap instrucció nova"
+
+#: config/m68k/m68k.h:274
+msgid "Generate code for a 68060, without any new instructions"
+msgstr "Generar codi per a un 68060, sense cap instrucció nova"
+
+#: config/m68k/m68k.h:278
+msgid "Generate code for a 68030"
+msgstr "Generar codi per a un 68030"
+
+#: config/m68k/m68k.h:281
+msgid "Generate code for a 68040"
+msgstr "Generar codi per a un 68040"
+
+#: config/m68k/m68k.h:285
+msgid "Generate code for a 68060"
+msgstr "Generar codi per a un 68060"
+
+#: config/m68k/m68k.h:290
+msgid "Generate code for a 520X"
+msgstr "Generar codi per a un 520X"
+
+#: config/m68k/m68k.h:294
+#, fuzzy
+msgid "Generate code for a 5206e"
+msgstr "Generar codi per a un 520X"
+
+#: config/m68k/m68k.h:298
+#, fuzzy
+msgid "Generate code for a 528x"
+msgstr "Generar codi per a un 520X"
+
+#: config/m68k/m68k.h:302
+#, fuzzy
+msgid "Generate code for a 5307"
+msgstr "Generar codi per a un 520X"
+
+#: config/m68k/m68k.h:306
+#, fuzzy
+msgid "Generate code for a 5407"
+msgstr "Generar codi per a un 520X"
+
+#: config/m68k/m68k.h:309
+msgid "Generate code for a 68851"
+msgstr "Generar codi per a un 68851"
+
+#: config/m68k/m68k.h:311
+msgid "Do no generate code for a 68851"
+msgstr "No generar codi per a un 68851"
+
+#: config/m68k/m68k.h:314
+msgid "Generate code for a 68302"
+msgstr "Generar codi per a un 68302"
+
+#: config/m68k/m68k.h:317
+msgid "Generate code for a 68332"
+msgstr "Generar codi per a un 68332"
+
+#: config/m68k/m68k.h:321
+msgid "Generate code for a cpu32"
+msgstr "Generar codi per a un cpu32"
+
+#: config/m68k/m68k.h:324
+msgid "Align variables on a 32-bit boundary"
+msgstr "Alinear les variables en un límit de 32-bit"
+
+#: config/m68k/m68k.h:326
+msgid "Align variables on a 16-bit boundary"
+msgstr "Alinear les variables en un límit de 16-bit"
+
+#: config/m68k/m68k.h:328
+msgid "Enable separate data segment"
+msgstr ""
+
+#: config/m68k/m68k.h:330
+msgid "Disable separate data segment"
+msgstr ""
+
+#: config/m68k/m68k.h:332
+msgid "Enable ID based shared library"
+msgstr ""
+
+#: config/m68k/m68k.h:334
+msgid "Disable ID based shared library"
+msgstr ""
+
+#: config/m68k/m68k.h:336
+msgid "Generate pc-relative code"
+msgstr "Generar codi relatiu al pc"
+
+#: config/m68k/m68k.h:338
+msgid "Do not use unaligned memory references"
+msgstr "No permetre referències a memòria sense alinear"
+
+#: config/m68k/m68k.h:340
+msgid "Use unaligned memory references"
+msgstr "Usar referències a memòria sense alinear"
+
+#: config/m68k/m68k.h:342
+msgid "Use different calling convention using 'rtd'"
+msgstr "Usar la convenció de cridada diferent usant 'rtd'"
+
+#: config/m68k/m68k.h:366
+msgid "ID of shared library to build"
+msgstr ""
+
+#: config/mcore/mcore.c:2973
+#, c-format
+msgid "invalid option `-mstack-increment=%s'"
+msgstr "opció invàlida \"-mstack-increment=%s\""
+
+#: config/mcore/mcore.h:121
+msgid "Inline constants if it can be done in 2 insns or less"
+msgstr "Constants inline si poden ser fetes en 2 insns o menys"
+
+#: config/mcore/mcore.h:123
+msgid "Inline constants if it only takes 1 instruction"
+msgstr "Constants inline si només prenen 1 instrucció"
+
+#: config/mcore/mcore.h:125
+msgid "Set maximum alignment to 4"
+msgstr "Establir l'alineació màxima a 4"
+
+#: config/mcore/mcore.h:127
+msgid "Set maximum alignment to 8"
+msgstr "Establir l'alineació màxima a 8"
+
+#: config/mcore/mcore.h:131
+msgid "Do not use the divide instruction"
+msgstr "No usar la instrucció divideix"
+
+#: config/mcore/mcore.h:135
+msgid "Do not arbitrary sized immediates in bit operations"
+msgstr "No intervenir en immediats de grandàries arbitràries en operacions de bit"
+
+#: config/mcore/mcore.h:137
+msgid "Always treat bit-field as int-sized"
+msgstr "Tractar sempre als camps de bit com de grandària int"
+
+#: config/mcore/mcore.h:141
+msgid "Force functions to be aligned to a 4 byte boundary"
+msgstr "Forçar que les funcions s'alineïn a un límit de 4 octet"
+
+#: config/mcore/mcore.h:143
+msgid "Force functions to be aligned to a 2 byte boundary"
+msgstr "Forçar que les funcions s'alineïn a un límit de 2 octet"
+
+#: config/mcore/mcore.h:145
+msgid "Emit call graph information"
+msgstr "Emetre informació de graf de cridades"
+
+#: config/mcore/mcore.h:149
+msgid "Prefer word accesses over byte accesses"
+msgstr "Preferir accessos word sobre accés octet"
+
+#: config/mcore/mcore.h:160
+msgid "Generate code for the M*Core M340"
+msgstr "Generar codi per a M*Core M340"
+
+#: config/mcore/mcore.h:173
+msgid "Maximum amount for a single stack increment operation"
+msgstr "Quantitat màxima per a una sola operació d'increment de pila"
+
+#: config/mips/mips.c:3122 config/xtensa/xtensa.c:1000
+#: config/xtensa/xtensa.c:1032 config/xtensa/xtensa.c:1041
+msgid "bad test"
+msgstr "prova errònia"
+
+#: config/mips/mips.c:4600
+#, c-format
+msgid "bad value (%s) for -mabi= switch"
+msgstr "valor erroni (%s) per a l'interruptor -mabi="
+
+#: config/mips/mips.c:4623
+#, c-format
+msgid "-mips%s conflicts with the other architecture options, which specify a MIPS%d processor"
+msgstr ""
+
+#: config/mips/mips.c:4642
+#, c-format
+msgid "-march=%s is not compatible with the selected ABI"
+msgstr ""
+
+#: config/mips/mips.c:4657
+msgid "-mgp64 used with a 32-bit processor"
+msgstr ""
+
+#: config/mips/mips.c:4659
+msgid "-mgp32 used with a 64-bit ABI"
+msgstr "s'utilitza -mgp32 amb una ABI de 64-bit"
+
+#: config/mips/mips.c:4661
+msgid "-mgp64 used with a 32-bit ABI"
+msgstr "s'utilitza -mgp64 amb una ABI de 32-bit"
+
+#: config/mips/mips.c:4679 config/mips/mips.c:4681 config/mips/mips.c:4683
+#: config/mips/mips.c:4811
+#, c-format
+msgid "unsupported combination: %s"
+msgstr "combinació sense suport: %s"
+
+#: config/mips/mips.c:4775
+#, fuzzy
+msgid "-g is only supported using GNU as,"
+msgstr "-g només té suport quan s'usa GAS en aquest processador,"
+
+#: config/mips/mips.c:4777
+#, fuzzy
+msgid "-g is only supported using GNU as with -mabi=32,"
+msgstr "-g només té suport quan s'usa GAS en aquest processador,"
+
+#: config/mips/mips.c:4778 config/pa/pa.c:353
+msgid "-g option disabled"
+msgstr "opció -g desactivada"
+
+#: config/mips/mips.c:4806
+msgid "generation of Branch Likely instructions enabled, but not supported by architecture"
+msgstr ""
+
+#: config/mips/mips.c:4823
+msgid "-G is incompatible with PIC code which is the default"
+msgstr "-G és incompatible amb el codi PIC el qual és per omissió"
+
+#: config/mips/mips.c:4851
+msgid "-membedded-pic and -mabicalls are incompatible"
+msgstr "-membedded-pic i -mabicalls són incompatibles"
+
+#: config/mips/mips.c:4854
+msgid "-G and -membedded-pic are incompatible"
+msgstr "-G i -membedded-pic són incompatibles"
+
+#: config/mips/mips.c:4886
+msgid "non-PIC n64 with explicit relocations"
+msgstr ""
+
+#: config/mips/mips.c:5274
+msgid "mips_debugger_offset called with non stack/frame/arg pointer"
+msgstr ""
+
+#: config/mips/mips.c:5401
+#, c-format
+msgid "internal error: %%) found without a %%( in assembler pattern"
+msgstr "error intern: es va trobar %%) sense un %%( en el patró del ensemblador"
+
+#: config/mips/mips.c:5415
+#, c-format
+msgid "internal error: %%] found without a %%[ in assembler pattern"
+msgstr "error intern: es va trobar %%] sense un %%[ en el patró del ensemblador"
+
+#: config/mips/mips.c:5428
+#, c-format
+msgid "internal error: %%> found without a %%< in assembler pattern"
+msgstr "error intern: es va trobar %%> sense un %%< en el patró del ensemblador"
+
+#: config/mips/mips.c:5441
+#, c-format
+msgid "internal error: %%} found without a %%{ in assembler pattern"
+msgstr "error intern: es va trobar %%} sense un %%{ en el patró del ensemblador"
+
+#: config/mips/mips.c:5455
+#, c-format
+msgid "PRINT_OPERAND: unknown punctuation '%c'"
+msgstr "PRINT_OPERAND: puntuació desconeguda \"%c\""
+
+#: config/mips/mips.c:5484
+#, fuzzy, c-format
+msgid "PRINT_OPERAND, invalid insn for %%C"
+msgstr "PRINT_OPERAND punter nul"
+
+#: config/mips/mips.c:5501
+#, fuzzy, c-format
+msgid "PRINT_OPERAND, invalid insn for %%N"
+msgstr "PRINT_OPERAND punter nul"
+
+#: config/mips/mips.c:5510
+#, fuzzy, c-format
+msgid "PRINT_OPERAND, invalid insn for %%F"
+msgstr "PRINT_OPERAND punter nul"
+
+#: config/mips/mips.c:5519
+#, fuzzy, c-format
+msgid "PRINT_OPERAND, invalid insn for %%W"
+msgstr "PRINT_OPERAND punter nul"
+
+#: config/mips/mips.c:5625
+msgid "PRINT_OPERAND, invalid operand for relocation"
+msgstr ""
+
+#: config/mips/mips.c:8310
+#, c-format
+msgid "can not handle inconsistent calls to `%s'"
+msgstr "no es poden manejar cridades inconsistentes a \"%s\""
+
+#: config/mips/mips.c:9316
+msgid "the cpu name must be lower case"
+msgstr "el nom de cpu deu estar en minúscules"
+
+#: config/mips/mips.c:9338
+#, c-format
+msgid "bad value (%s) for %s"
+msgstr "valor erroni (%s) per a %s"
+
+#: config/mips/mips.c:9607
+#, fuzzy, c-format
+msgid "can't rewind temp file: %m"
+msgstr "no es pot rebobinar el fitxer temporal"
+
+#: config/mips/mips.c:9611
+#, fuzzy, c-format
+msgid "can't write to output file: %m"
+msgstr "no es pot escriure al fitxer de sortida"
+
+#: config/mips/mips.c:9614
+#, fuzzy, c-format
+msgid "can't read from temp file: %m"
+msgstr "no es pot llegir dès del fitxer temporal"
+
+#: config/mips/mips.c:9617
+#, fuzzy, c-format
+msgid "can't close temp file: %m"
+msgstr "no es pot tancar el fitxer temporal"
+
+#: config/mips/linux64.h:39
+msgid "Same as -mabi=32, just trickier"
+msgstr ""
+
+#. Target CPU builtins.
+#. We do this here because __mips is defined below and so we can't use builtin_define_std.
+#. Treat _R3000 and _R4000 like register-size defines, which is how they've historically been used.
+#. Macros dependent on the C dialect.
+#. Bizarre, but needed at least for Irix.
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/mips/mips.h:514
+msgid "Use 64-bit int type"
+msgstr "Usar tipus int de 64 bits"
+
+#: config/mips/mips.h:516
+msgid "Use 64-bit long type"
+msgstr "Usar tipus long de 64 bits"
+
+#: config/mips/mips.h:518
+msgid "Use 32-bit long type"
+msgstr "Usar tipus long de 32 bits"
+
+#: config/mips/mips.h:520
+msgid "Optimize lui/addiu address loads"
+msgstr "Optimitzar les càrregues de les adreces lui/addiu"
+
+#: config/mips/mips.h:522
+msgid "Don't optimize lui/addiu address loads"
+msgstr "No optimitzar les càrregues de les adreces lui/addiu"
+
+#: config/mips/mips.h:524
+msgid "Use MIPS as"
+msgstr "Usar l'as de MIPS"
+
+#: config/mips/mips.h:526
+msgid "Use GNU as"
+msgstr "Usar l'as de GNU"
+
+#: config/mips/mips.h:528
+msgid "Use symbolic register names"
+msgstr "Usar noms simbòlics de registre"
+
+#: config/mips/mips.h:530
+msgid "Don't use symbolic register names"
+msgstr "No usar noms simbòlics de registre"
+
+#: config/mips/mips.h:532 config/mips/mips.h:534
+#, fuzzy
+msgid "Use GP relative sdata/sbss sections (now ignored)"
+msgstr "Usar seccions sdata/sbss relatives a GP"
+
+#: config/mips/mips.h:536 config/mips/mips.h:538
+#, fuzzy
+msgid "Don't use GP relative sdata/sbss sections (now ignored)"
+msgstr "No usar seccions sdata/sbss relatives a GP"
+
+#: config/mips/mips.h:540
+#, fuzzy
+msgid "Output compiler statistics (now ignored)"
+msgstr "Mostrar la sortida d'estadístiques del compilador"
+
+#: config/mips/mips.h:542
+msgid "Don't output compiler statistics"
+msgstr "No mostrar la sortida d'estadístiques del compilador"
+
+#: config/mips/mips.h:544
+msgid "Don't optimize block moves"
+msgstr "No optimitzar els moviments de blocs"
+
+#: config/mips/mips.h:546
+msgid "Optimize block moves"
+msgstr "Optimitzar els moviments de blocs"
+
+#: config/mips/mips.h:548
+msgid "Use mips-tfile asm postpass"
+msgstr "Usar mips-tfile asm postpass"
+
+#: config/mips/mips.h:550
+msgid "Don't use mips-tfile asm postpass"
+msgstr "No usar mips-tfile asm postpass"
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of triplets in braces,
+#. each triplet being { "NAME", VALUE, DOC }
+#. where VALUE is the bits to set or minus the bits to clear and DOC
+#. is the documentation for --help (NULL if intentionally undocumented).
+#. An empty string NAME is used to identify the default VALUE.
+#: config/mips/mips.h:554 config/pdp11/pdp11.h:61 config/rs6000/rs6000.h:314
+msgid "Use hardware floating point"
+msgstr "Usar coma flotant de maquinari"
+
+#: config/mips/mips.h:556
+msgid "Use 64-bit FP registers"
+msgstr "Usar registres FP de 64 bits"
+
+#: config/mips/mips.h:558
+msgid "Use 32-bit FP registers"
+msgstr "Usar registres FP de 32 bits"
+
+#: config/mips/mips.h:560
+msgid "Use 64-bit general registers"
+msgstr "Usar registres generals de 64 bits"
+
+#: config/mips/mips.h:562
+msgid "Use 32-bit general registers"
+msgstr "Usar registres generals de 32 bits"
+
+#: config/mips/mips.h:564
+msgid "Use Irix PIC"
+msgstr "Usar PIC de Irix"
+
+#: config/mips/mips.h:566
+msgid "Don't use Irix PIC"
+msgstr "No usar PIC de Irix"
+
+#: config/mips/mips.h:568
+msgid "Use indirect calls"
+msgstr "Usar cridades indirectes"
+
+#: config/mips/mips.h:570
+msgid "Don't use indirect calls"
+msgstr "No usar cridades indirectes"
+
+#: config/mips/mips.h:572
+msgid "Use embedded PIC"
+msgstr "Usar el PIC incrustat"
+
+#: config/mips/mips.h:574
+msgid "Don't use embedded PIC"
+msgstr "No usar el PIC incrustat"
+
+#: config/mips/mips.h:584
+msgid "Use big-endian byte order"
+msgstr "Usar ordre de bit big-endian"
+
+#: config/mips/mips.h:586
+msgid "Use little-endian byte order"
+msgstr "Usar ordre de bit little-endian"
+
+#: config/mips/mips.h:588
+msgid "Use single (32-bit) FP only"
+msgstr "Usar únicament una sola FP (32-bit)"
+
+#: config/mips/mips.h:590
+msgid "Don't use single (32-bit) FP only"
+msgstr "No usar únicament una sola FP (32-bit)"
+
+#: config/mips/mips.h:592
+msgid "Use multiply accumulate"
+msgstr "Usar el acumulador de multiplicació"
+
+#: config/mips/mips.h:594
+msgid "Don't use multiply accumulate"
+msgstr "No usar el acumulador de multiplicació"
+
+#: config/mips/mips.h:596
+msgid "Don't generate fused multiply/add instructions"
+msgstr "No generar instruccions multiply/add de curt circuit"
+
+#: config/mips/mips.h:598 config/rs6000/rs6000.h:330
+msgid "Generate fused multiply/add instructions"
+msgstr "Generar instruccions multiply/add de curt circuit"
+
+#: config/mips/mips.h:600
+msgid "Work around early 4300 hardware bug"
+msgstr "Evitar el bug del primer maquinari 4300"
+
+#: config/mips/mips.h:602
+msgid "Don't work around early 4300 hardware bug"
+msgstr "No evitar el bug del primer maquinari 4300"
+
+#: config/mips/mips.h:604
+msgid "Work around errata for early SB-1 revision 2 cores"
+msgstr ""
+
+#: config/mips/mips.h:606
+msgid "Don't work around errata for early SB-1 revision 2 cores"
+msgstr ""
+
+#: config/mips/mips.h:608
+msgid "Trap on integer divide by zero"
+msgstr "Atrapar la divisió entera per zero"
+
+#: config/mips/mips.h:610
+msgid "Don't trap on integer divide by zero"
+msgstr "No atrapar la divisió entera per zero"
+
+#: config/mips/mips.h:612
+msgid "Use Branch Likely instructions, overriding default for arch"
+msgstr ""
+
+#: config/mips/mips.h:614
+msgid "Don't use Branch Likely instructions, overriding default for arch"
+msgstr ""
+
+#: config/mips/mips.h:616
+msgid "Use NewABI-style %reloc() assembly operators"
+msgstr ""
+
+#: config/mips/mips.h:618
+msgid "Use assembler macros instead of relocation operators"
+msgstr ""
+
+#: config/mips/mips.h:620
+#, fuzzy
+msgid "Generate mips16 code"
+msgstr "Generar codi SA"
+
+#: config/mips/mips.h:622
+#, fuzzy
+msgid "Generate normal-mode code"
+msgstr "Generar codi SA"
+
+#: config/mips/mips.h:624
+msgid "Lift restrictions on GOT size"
+msgstr ""
+
+#: config/mips/mips.h:626
+msgid "Do not lift restrictions on GOT size"
+msgstr ""
+
+#: config/mips/mips.h:748
+msgid "Specify an ABI"
+msgstr "Especificar un ABI"
+
+#: config/mips/mips.h:750
+msgid "Specify a Standard MIPS ISA"
+msgstr "Especificar el ISA de MIPS standard"
+
+#. Output assembler code to FILE to increment profiler label # LABELNO
+#. for profiling a function entry.
+#: config/mips/mips.h:2418
+msgid "mips16 function profiling"
+msgstr "anàlisi de perfil de les funcions mips16"
+
+#: config/mmix/mmix.c:207
+#, c-format
+msgid "-f%s not supported: ignored"
+msgstr "-f%s no té suport: ignorat"
+
+#: config/mmix/mmix.c:633
+#, c-format
+msgid "too large function value type, needs %d registers, have only %d registers for this"
+msgstr "el valor del tipus de la funció és massa gran, necessita %d registres, només es tenen %d registres per a això"
+
+#: config/mmix/mmix.c:803
+msgid "function_profiler support for MMIX"
+msgstr "suport per a function_profiler per a MMIX"
+
+#: config/mmix/mmix.c:823
+msgid "MMIX Internal: Last named vararg would not fit in a register"
+msgstr "MMIX intern: L'últim vararg nomenat no conté en un registre"
+
+#: config/mmix/mmix.c:1538 config/mmix/mmix.c:1668
+msgid "MMIX Internal: Expected a CONST_INT, not this"
+msgstr "MMIX intern: Esperant un CONS_INT, no això"
+
+#: config/mmix/mmix.c:1546 config/mmix/mmix.c:1570 config/mmix/mmix.c:1686
+#, c-format
+msgid "MMIX Internal: Bad register: %d"
+msgstr "MMIX intern: registre erroni: %d"
+
+#: config/mmix/mmix.c:1617
+msgid "MMIX Internal: Bad value for 'm', not a CONST_INT"
+msgstr "MMIX intern: valor erroni per a \"m\", no és un CONST_INT"
+
+#: config/mmix/mmix.c:1636
+msgid "MMIX Internal: Expected a register, not this"
+msgstr "MMIX intern: Esperant un registre, no això"
+
+#: config/mmix/mmix.c:1646
+msgid "MMIX Internal: Expected a constant, not this"
+msgstr "MMIX intern: Esperant una constant, no això"
+
+#. Presumably there's a missing case above if we get here.
+#: config/mmix/mmix.c:1678
+#, c-format
+msgid "MMIX Internal: Missing `%c' case in mmix_print_operand"
+msgstr "MMIX intern: \"%c\" faltant en mmix_print_operand"
+
+#. We need the original here.
+#: config/mmix/mmix.c:1730
+msgid "MMIX Internal: Cannot decode this operand"
+msgstr "MMIX intern: aquesta operant no es pot dexifrar"
+
+#: config/mmix/mmix.c:1787
+msgid "MMIX Internal: This is not a recognized address"
+msgstr "MMIX intern: adreça no reconeguda"
+
+#: config/mmix/mmix.c:1964
+#, c-format
+msgid "stack frame not a multiple of 8 bytes: %d"
+msgstr "el marc de pila no és un múltiple de 8 octets: %d"
+
+#: config/mmix/mmix.c:2203
+#, c-format
+msgid "stack frame not a multiple of octabyte: %d"
+msgstr "el marc de pila no és un múltiple de octabyte: %d"
+
+#: config/mmix/mmix.c:2677 config/mmix/mmix.c:2741
+#, c-format
+msgid "MMIX Internal: %s is not a shiftable int"
+msgstr "MMIX intern: %s no és un enter desplaçable"
+
+#: config/mmix/mmix.c:2857
+msgid "MMIX Internal: Trying to output invalidly reversed condition:"
+msgstr "MMIX intern: Intentant de mostrar una condició invertida de forma invàlida:"
+
+#: config/mmix/mmix.c:2864
+msgid "MMIX Internal: What's the CC of this?"
+msgstr "MMIX Internal: Quin és el CC per això"
+
+#: config/mmix/mmix.c:2868
+msgid "MMIX Internal: What is the CC of this?"
+msgstr "MMIX Internal: Quin és el CC per això"
+
+#: config/mmix/mmix.c:2938
+msgid "MMIX Internal: This is not a constant:"
+msgstr "MMIX Internal: Això no és una constant:"
+
+#. For these target macros, there is no generic documentation here. You
+#. should read `Using and Porting GCC' for that. Only comments specific
+#. to the MMIX target are here.
+#.
+#. There are however references to the specific texinfo node (comments
+#. with "Node:"), so there should be little or nothing amiss. Probably
+#. the opposite, since we don't have to care about old littering and
+#. soon outdated generic comments.
+#. Node: Driver
+#. User symbols are in the same name-space as built-in symbols, but we
+#. don't need the built-in symbols, so remove those and instead apply
+#. stricter operand checking. Don't warn when expanding insns.
+#. Pass on -mset-program-start=N and -mset-data-start=M to the linker.
+#. Provide default program start 0x100 unless -mno-set-program-start.
+#. Don't do this if linking relocatably, with -r. For a final link,
+#. produce mmo, unless ELF is requested or when linking relocatably.
+#. Put unused option values here.
+#: config/mmix/mmix.h:132
+msgid "Set start-address of the program"
+msgstr "Definir l'adreça d'inici del programa"
+
+#: config/mmix/mmix.h:134
+msgid "Set start-address of data"
+msgstr "Definir l'adreça d'inici de les dades"
+
+#. FIXME: Provide a way to *load* the epsilon register.
+#: config/mmix/mmix.h:198
+msgid "For intrinsics library: pass all parameters in registers"
+msgstr "Per a biblioteques intrínsecs: passar els parametres en registres"
+
+#: config/mmix/mmix.h:201
+msgid "Use register stack for parameters and return value"
+msgstr "Usar registres de pila per a parametres i valors de retorn"
+
+#: config/mmix/mmix.h:203
+msgid "Use call-clobbered registers for parameters and return value"
+msgstr "Usar registres maltractats per a parametres i valors de retorn"
+
+#: config/mmix/mmix.h:205
+msgid "Use epsilon-respecting floating point compare instructions"
+msgstr "Usar instuccions de comparança en coma flotant que respectent epsilon"
+
+#: config/mmix/mmix.h:208
+msgid "Use zero-extending memory loads, not sign-extending ones"
+msgstr "Usar càrregues de memòria d'extensió zero, no les d'extensió amb signe"
+
+#: config/mmix/mmix.h:211
+msgid "Generate divide results with reminder having the same sign as the divisor (not the dividend)"
+msgstr "Generar resultats de divisió amb residu que tingui el mateix signe que el divisor (no el del dividend)"
+
+#: config/mmix/mmix.h:215
+msgid "Prepend global symbols with \":\" (for use with PREFIX)"
+msgstr "Precedir als símbols globals amb \":\" (per a usar-se amb PREFIX)"
+
+#: config/mmix/mmix.h:217
+msgid "Do not provide a default start-address 0x100 of the program"
+msgstr "No proveir una adreça d'inici per omissió 0x100 del programa"
+
+#: config/mmix/mmix.h:219
+msgid "Link to emit program in ELF format (rather than mmo)"
+msgstr "Enllaçar per a emetre el programa en format ELF (en lloc de mmo)"
+
+#: config/mmix/mmix.h:221
+msgid "Use P-mnemonics for branches statically predicted as taken"
+msgstr "Usar Mnemónicos-P per a ramificacions predites estàticament com preses"
+
+#: config/mmix/mmix.h:223
+msgid "Don't use P-mnemonics for branches"
+msgstr "No usar Mnemónicos-P per a ramificacions"
+
+#: config/mmix/mmix.h:225
+msgid "Use addresses that allocate global registers"
+msgstr "Usar adreces que reservin registres globals"
+
+#: config/mmix/mmix.h:227
+msgid "Do not use addresses that allocate global registers"
+msgstr "No usar adreces que reservin registres globals"
+
+#: config/mmix/mmix.h:229
+msgid "Generate a single exit point for each function"
+msgstr "Generar només un punt de sortida per a cada funció"
+
+#: config/mmix/mmix.h:231
+msgid "Do not generate a single exit point for each function"
+msgstr "No generar només un punt de sortida per a cada funció"
+
+#: config/mn10300/linux.h:60 config/mn10300/mn10300.h:71
+msgid "Target the AM33 processor"
+msgstr "Apuntar al processador AM33"
+
+#: config/mn10300/linux.h:61 config/mn10300/mn10300.h:75
+#, fuzzy
+msgid "Target the AM33/2.0 processor"
+msgstr "Apuntar al processador AM33"
+
+#: config/mn10300/linux.h:62 config/mn10300/mn10300.h:78
+msgid "Enable linker relaxations"
+msgstr "Activar la relaxació del enllaçador"
+
+#: config/mn10300/mn10300.h:69
+msgid "Work around hardware multiply bug"
+msgstr "Evitar el error de multiplicació de maquinari"
+
+#: config/mn10300/mn10300.h:70
+msgid "Do not work around hardware multiply bug"
+msgstr "No evitar el error de multiplicació de maquinari"
+
+#: config/ns32k/ns32k.h:142 config/s390/s390.h:125
+msgid "Don't use hardware fp"
+msgstr "No usar el fp de maquinari"
+
+#: config/ns32k/ns32k.h:143
+msgid "Alternative calling convention"
+msgstr "Convenció de cridada alternativa"
+
+#: config/ns32k/ns32k.h:145
+msgid "Pass some arguments in registers"
+msgstr "Passar alguns arguments en registres"
+
+#: config/ns32k/ns32k.h:146
+msgid "Pass all arguments on stack"
+msgstr "Passar tots els arguments en la pila"
+
+#: config/ns32k/ns32k.h:147
+msgid "Optimize for 32532 cpu"
+msgstr "Optimitzar per al cpu 32532"
+
+#: config/ns32k/ns32k.h:148
+msgid "Optimize for 32332 cpu"
+msgstr "Optimitzar per al cpu 32332"
+
+#: config/ns32k/ns32k.h:150
+msgid "Optimize for 32032"
+msgstr "Optimitzar per a 32032"
+
+#: config/ns32k/ns32k.h:152
+msgid "Register sb is zero. Use for absolute addressing"
+msgstr "El registre sb és zero. S'usa per a adreçament absolut"
+
+#: config/ns32k/ns32k.h:153
+msgid "Do not use register sb"
+msgstr "No usar el registre sb"
+
+#: config/ns32k/ns32k.h:155
+msgid "Use bit-field instructions"
+msgstr "Usar instruccions de camps de bit"
+
+#: config/ns32k/ns32k.h:157
+msgid "Do not use bit-field instructions"
+msgstr "No usar instruccions de camps de bit"
+
+#: config/ns32k/ns32k.h:158
+msgid "Generate code for high memory"
+msgstr "Generar codi per a memòria alta"
+
+#: config/ns32k/ns32k.h:159
+msgid "Generate code for low memory"
+msgstr "Generar codi per a memòria baixa"
+
+#: config/ns32k/ns32k.h:160
+msgid "32381 fpu"
+msgstr "fpu 32381"
+
+#: config/ns32k/ns32k.h:162
+msgid "Use multiply-accumulate fp instructions"
+msgstr "Usar instruccions de fp per a multiplicar-acumular"
+
+#: config/ns32k/ns32k.h:164
+msgid "Do not use multiply-accumulate fp instructions"
+msgstr "No usar instruccions de fp per a multiplicar-acumular"
+
+#: config/ns32k/ns32k.h:165
+msgid "\"Small register classes\" kludge"
+msgstr "kludge de \"Classes de registre petites\""
+
+#: config/ns32k/ns32k.h:166
+msgid "No \"Small register classes\" kludge"
+msgstr "No kludge de \"Classes de registre petites\""
+
+#: config/pa/pa.c:304
+#, c-format
+msgid ""
+"unknown -mschedule= option (%s).\n"
+"Valid options are 700, 7100, 7100LC, 7200, 7300, and 8000\n"
+msgstr ""
+"opció -mschedule= desconeguda (%s).\n"
+"Les opcions vàlides són 700, 7100, 7100LC, 7200, 7300, i 8000\n"
+
+#: config/pa/pa.c:329
+#, c-format
+msgid ""
+"unknown -march= option (%s).\n"
+"Valid options are 1.0, 1.1, and 2.0\n"
+msgstr ""
+"opció -march= desconeguda (%s).\n"
+"Les opcions vàlides són 1.0, 1.1, i 2.0\n"
+
+#: config/pa/pa.c:342
+msgid "PIC code generation is not supported in the portable runtime model\n"
+msgstr "La generació de codi PIC no té suport en el model portable de temps d'execució\n"
+
+#: config/pa/pa.c:347
+msgid "PIC code generation is not compatible with fast indirect calls\n"
+msgstr "La generació de codi PIC no és compatible amb les cridades ràpides indirectes\n"
+
+#: config/pa/pa.c:352
+msgid "-g is only supported when using GAS on this processor,"
+msgstr "-g només té suport quan s'usa GAS en aquest processador,"
+
+#: config/pa/pa-hpux.h:91 config/pa/pa64-hpux.h:25
+msgid "Generate cpp defines for server IO"
+msgstr "Generar definicions cpp per a IO de servidor"
+
+#: config/pa/pa-hpux.h:92 config/pa/pa64-hpux.h:27
+msgid "Generate cpp defines for workstation IO"
+msgstr "Generar definicions cpp per a IO d'estació de treball"
+
+#. Macro to define tables used to set the flags. This is a
+#. list in braces of target switches with each switch being
+#. { "NAME", VALUE, "HELP_STRING" }. VALUE is the bits to set,
+#. or minus the bits to clear. An empty string NAME is used to
+#. identify the default VALUE. Do not mark empty strings for
+#. translation.
+#: config/pa/pa.h:232 config/pa/pa.h:238
+msgid "Generate PA1.1 code"
+msgstr "Generar codi PA1.1"
+
+#: config/pa/pa.h:234 config/pa/pa.h:236
+msgid "Generate PA1.0 code"
+msgstr "Generar codi PA1.0"
+
+#: config/pa/pa.h:240
+msgid "Generate PA2.0 code (requires binutils 2.10 or later)"
+msgstr ""
+
+#: config/pa/pa.h:242
+msgid "Disable FP regs"
+msgstr "Desactivar els registres FP"
+
+#: config/pa/pa.h:244
+msgid "Do not disable FP regs"
+msgstr "No desactivar registres FP"
+
+#: config/pa/pa.h:246
+msgid "Disable space regs"
+msgstr ""
+
+#: config/pa/pa.h:248
+msgid "Do not disable space regs"
+msgstr "No desactivar registres d'espai"
+
+#: config/pa/pa.h:250
+msgid "Put jumps in call delay slots"
+msgstr ""
+
+#: config/pa/pa.h:252
+msgid "Do not put jumps in call delay slots"
+msgstr ""
+
+#: config/pa/pa.h:254
+msgid "Disable indexed addressing"
+msgstr "Desactivar adreçament d'index"
+
+#: config/pa/pa.h:256
+msgid "Do not disable indexed addressing"
+msgstr "No desactivar adreçament indexat"
+
+#: config/pa/pa.h:258
+msgid "Use portable calling conventions"
+msgstr "Usar convencions de cridada portable"
+
+#: config/pa/pa.h:260
+msgid "Do not use portable calling conventions"
+msgstr "No usar convencions de cridada portable"
+
+#: config/pa/pa.h:262
+msgid "Assume code will be assembled by GAS"
+msgstr ""
+
+#: config/pa/pa.h:264
+msgid "Do not assume code will be assembled by GAS"
+msgstr ""
+
+#: config/pa/pa.h:268
+msgid "Do not use software floating point"
+msgstr "No usa coma flotant de programari"
+
+#: config/pa/pa.h:270
+msgid "Emit long load/store sequences"
+msgstr ""
+
+#: config/pa/pa.h:272
+msgid "Do not emit long load/store sequences"
+msgstr "No emetre seqüències load/store llarges"
+
+#: config/pa/pa.h:274
+msgid "Generate fast indirect calls"
+msgstr "Generar cridades indirectes ràpides"
+
+#: config/pa/pa.h:276
+msgid "Do not generate fast indirect calls"
+msgstr "No generar cridades indirectes ràpides"
+
+#: config/pa/pa.h:278
+msgid "Generate code for huge switch statements"
+msgstr "Generar codi per a declaracions switch grandes"
+
+#: config/pa/pa.h:280
+msgid "Do not generate code for huge switch statements"
+msgstr "No generar codi per a declaracions switch grandes"
+
+#: config/pa/pa.h:282
+msgid "Always generate long calls"
+msgstr "Generar sempre cridades llarges"
+
+#: config/pa/pa.h:284
+msgid "Generate long calls only when needed"
+msgstr ""
+
+#: config/pa/pa.h:286
+msgid "Enable linker optimizations"
+msgstr "Activar les optimitzacions del enllaçador"
+
+#: config/pa/pa.h:312
+msgid "Specify architecture for code generation. Values are 1.0, 1.1, and 2.0. 2.0 requires gas snapshot 19990413 or later."
+msgstr ""
+
+#: config/pa/pa64-hpux.h:29
+msgid "Assume code will be linked by GNU ld"
+msgstr ""
+
+#: config/pa/pa64-hpux.h:31
+msgid "Assume code will be linked by HP ld"
+msgstr ""
+
+#: config/pdp11/pdp11.h:62 config/rs6000/rs6000.h:316
+msgid "Do not use hardware floating point"
+msgstr "No usa coma flotant de maquinari"
+
+#. return float result in ac0
+#: config/pdp11/pdp11.h:64
+msgid "Return floating point results in ac0"
+msgstr "Devolució de resultats de coma flotant en ac0"
+
+#: config/pdp11/pdp11.h:65
+msgid "Return floating point results in memory"
+msgstr "Devolució de resultats de coma flotant en memoria"
+
+#. is 11/40
+#: config/pdp11/pdp11.h:67
+msgid "Generate code for an 11/40"
+msgstr "Generar codi per a un 11/40"
+
+#. is 11/45
+#: config/pdp11/pdp11.h:70
+msgid "Generate code for an 11/45"
+msgstr "5Generar codi per a un 11/45"
+
+#. is 11/10
+#: config/pdp11/pdp11.h:73
+msgid "Generate code for an 11/10"
+msgstr "Generar codi per a un 11/10"
+
+#. use movstrhi for bcopy
+#. use 32 bit for int
+#: config/pdp11/pdp11.h:78 config/pdp11/pdp11.h:79
+msgid "Use 32 bit int"
+msgstr "Usar int de 32 bits"
+
+#: config/pdp11/pdp11.h:80 config/pdp11/pdp11.h:81
+msgid "Use 16 bit int"
+msgstr "Usar int de 16 bits"
+
+#. use 32 bit for float
+#: config/pdp11/pdp11.h:83 config/pdp11/pdp11.h:84
+msgid "Use 32 bit float"
+msgstr "Usar float de 32 bits"
+
+#: config/pdp11/pdp11.h:85 config/pdp11/pdp11.h:86
+msgid "Use 64 bit float"
+msgstr "Usar float de 64 bits"
+
+#. allow abshi pattern? - can trigger "optimizations" which make code SLOW!
+#. is branching expensive - on a PDP, it's actually really cheap
+#. this is just to play around and check what code gcc generates
+#. split instruction and data memory?
+#: config/pdp11/pdp11.h:95
+msgid "Target has split I&D"
+msgstr "L'objectiu té un I&D dividit"
+
+#: config/pdp11/pdp11.h:96
+msgid "Target does not have split I&D"
+msgstr "L'objectiu no té un I&D dividit"
+
+#. UNIX assembler syntax?
+#: config/pdp11/pdp11.h:98
+msgid "Use UNIX assembler syntax"
+msgstr "Usar sintaxi de l'ensemblador UNIX"
+
+#: config/pdp11/pdp11.h:99
+msgid "Use DEC assembler syntax"
+msgstr "Usar sintaxi de l'ensemblador DEC"
+
+#: config/rs6000/host-darwin.c:52
+msgid "Segmentation Fault (code)"
+msgstr ""
+
+#: config/rs6000/host-darwin.c:83
+msgid "Out of stack space.\n"
+msgstr ""
+
+#: config/rs6000/host-darwin.c:104
+#, c-format
+msgid "Try running `%s' in the shell to raise its limit.\n"
+msgstr ""
+
+#: config/rs6000/host-darwin.c:117
+msgid "Segmentation Fault"
+msgstr ""
+
+#: config/rs6000/host-darwin.c:131
+#, c-format
+msgid "While setting up signal stack: %m"
+msgstr ""
+
+#: config/rs6000/host-darwin.c:137
+#, c-format
+msgid "While setting up signal handler: %m"
+msgstr ""
+
+#: config/rs6000/host-darwin.c:184
+#, c-format
+msgid "couldn't unmap pch_address_space: %m\n"
+msgstr ""
+
+#. Handle the machine specific pragma longcall. Its syntax is
+#.
+#. # pragma longcall ( TOGGLE )
+#.
+#. where TOGGLE is either 0 or 1.
+#.
+#. rs6000_default_long_calls is set to the value of TOGGLE, changing
+#. whether or not new function declarations receive a longcall
+#. attribute by default.
+#: config/rs6000/rs6000-c.c:46
+msgid "ignoring malformed #pragma longcall"
+msgstr "ignorant el #pragma longcall malformats"
+
+#: config/rs6000/rs6000-c.c:59
+msgid "missing open paren"
+msgstr "\"(\" faltant"
+
+#: config/rs6000/rs6000-c.c:61
+msgid "missing number"
+msgstr "falta valor"
+
+#: config/rs6000/rs6000-c.c:63
+msgid "missing close paren"
+msgstr "\")\" faltant"
+
+#: config/rs6000/rs6000-c.c:66
+msgid "number must be 0 or 1"
+msgstr ""
+
+#: config/rs6000/rs6000-c.c:69
+msgid "junk at end of #pragma longcall"
+msgstr "escombraries al final de #pragma longcall"
+
+#: config/rs6000/rs6000.c:784
+msgid "-mmultiple is not supported on little endian systems"
+msgstr "-mmultiple no té suport en sistemes little endian"
+
+#: config/rs6000/rs6000.c:791
+msgid "-mstring is not supported on little endian systems"
+msgstr "-mstringe no té suport en sistemes little endian"
+
+#: config/rs6000/rs6000.c:805
+#, c-format
+msgid "unknown -mdebug-%s switch"
+msgstr "interruptor -mdebug-%s desconegut"
+
+#: config/rs6000/rs6000.c:817
+#, c-format
+msgid "unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'"
+msgstr ""
+
+#: config/rs6000/rs6000.c:828
+#, c-format
+msgid "Unknown switch -mlong-double-%s"
+msgstr "interruptor -mlong-double-%s desconegut"
+
+#: config/rs6000/rs6000.c:1011
+#, fuzzy, c-format
+msgid "unknown -m%s= option specified: '%s'"
+msgstr "opció -misel= especificada desconeguda: \"%s\""
+
+#: config/rs6000/rs6000.c:1032
+#, c-format
+msgid "not configured for ABI: '%s'"
+msgstr ""
+
+#: config/rs6000/rs6000.c:1038
+#, c-format
+msgid "unknown ABI specified: '%s'"
+msgstr "ABI especificada desconeguda: \"%s\""
+
+#: config/rs6000/rs6000.c:1052
+#, fuzzy, c-format
+msgid "unknown -malign-XXXXX option specified: '%s'"
+msgstr "opció -misel= especificada desconeguda: \"%s\""
+
+#: config/rs6000/rs6000.c:3892
+msgid "Cannot return value in vector register because altivec instructions are disabled, use -maltivec to enable them."
+msgstr ""
+
+#: config/rs6000/rs6000.c:3991
+msgid "Cannot pass argument in vector register because altivec instructions are disabled, use -maltivec to enable them."
+msgstr ""
+
+#: config/rs6000/rs6000.c:5409
+msgid "argument 1 must be a 5-bit signed literal"
+msgstr "l'argument 1 deu ser una literal amb signe de 5-bit"
+
+#: config/rs6000/rs6000.c:5511 config/rs6000/rs6000.c:6134
+msgid "argument 2 must be a 5-bit unsigned literal"
+msgstr "l'argument 2 deu ser una literal sense signe de 5-bit"
+
+#: config/rs6000/rs6000.c:5551
+msgid "argument 1 of __builtin_altivec_predicate must be a constant"
+msgstr "l'argument 1 de _builtin_altivec_predicate deu ser una constant"
+
+#: config/rs6000/rs6000.c:5605
+msgid "argument 1 of __builtin_altivec_predicate is out of range"
+msgstr "l'argument 1 de _builtin_altivec_predicate es fora de rang"
+
+#: config/rs6000/rs6000.c:5733
+msgid "argument 3 must be a 4-bit unsigned literal"
+msgstr "l'argument 3 deu ser una literal sense signe de 4-bit"
+
+#: config/rs6000/rs6000.c:5903
+#, c-format
+msgid "argument to `%s' must be a 2-bit unsigned literal"
+msgstr "l'argument per a \"%s\" deu ser una literal sense signe de 2-bit"
+
+#: config/rs6000/rs6000.c:6016
+msgid "argument to dss must be a 2-bit unsigned literal"
+msgstr "l'argument per a dss deu ser una literal sense signe de 2-bit"
+
+#: config/rs6000/rs6000.c:6254
+msgid "argument 1 of __builtin_spe_predicate must be a constant"
+msgstr "l'argument 1 de __builtin__spe_predicate deu ser una constant"
+
+#: config/rs6000/rs6000.c:6327
+msgid "argument 1 of __builtin_spe_predicate is out of range"
+msgstr "l'argument 1 de __builtin_spe_predicate està fora de rang"
+
+#: config/rs6000/rs6000.c:8531
+msgid "your function will be miscompiled"
+msgstr ""
+
+#: config/rs6000/rs6000.c:8779
+#, c-format
+msgid "invalid %%f value"
+msgstr "valor %%f invàlid"
+
+#: config/rs6000/rs6000.c:8788
+#, c-format
+msgid "invalid %%F value"
+msgstr "valor %%F invàlid"
+
+#: config/rs6000/rs6000.c:8797
+#, c-format
+msgid "invalid %%G value"
+msgstr "valor %%G invàlid"
+
+#: config/rs6000/rs6000.c:8832
+#, c-format
+msgid "invalid %%j code"
+msgstr "valor %%j invàlid"
+
+#: config/rs6000/rs6000.c:8842
+#, c-format
+msgid "invalid %%J code"
+msgstr "valor %%J invàlid"
+
+#: config/rs6000/rs6000.c:8852
+#, c-format
+msgid "invalid %%k value"
+msgstr "valor %%k invàlid"
+
+#: config/rs6000/rs6000.c:8872 config/xtensa/xtensa.c:1999
+#, c-format
+msgid "invalid %%K value"
+msgstr "valor %%K invàlid"
+
+#: config/rs6000/rs6000.c:8939
+#, c-format
+msgid "invalid %%O value"
+msgstr "valor %%O invàlid"
+
+#: config/rs6000/rs6000.c:8986
+#, c-format
+msgid "invalid %%q value"
+msgstr "valor invàlid per a %%q"
+
+#: config/rs6000/rs6000.c:9030
+#, c-format
+msgid "invalid %%S value"
+msgstr "valor %%S invàlid"
+
+#: config/rs6000/rs6000.c:9072
+#, c-format
+msgid "invalid %%T value"
+msgstr "valor %%T invàlid"
+
+#: config/rs6000/rs6000.c:9082
+#, c-format
+msgid "invalid %%u value"
+msgstr "valor %%u invàlid"
+
+#: config/rs6000/rs6000.c:9091 config/xtensa/xtensa.c:1969
+#, c-format
+msgid "invalid %%v value"
+msgstr "valor %%v invàlid"
+
+#: config/rs6000/rs6000.c:13581
+msgid "no profiling of 64-bit code for this ABI"
+msgstr ""
+
+#: config/rs6000/aix.h:184 config/rs6000/beos.h:32
+msgid "Always pass floating-point arguments in memory"
+msgstr "Passar sempre els arguments de coma flotant en memòria"
+
+#: config/rs6000/aix.h:186 config/rs6000/beos.h:34
+msgid "Don't always pass floating-point arguments in memory"
+msgstr "No passar sempre els arguments de coma flotant en memòria"
+
+#: config/rs6000/aix41.h:27 config/rs6000/aix43.h:31 config/rs6000/aix51.h:31
+#: config/rs6000/aix52.h:31
+msgid "Support message passing with the Parallel Environment"
+msgstr "Suport per al pas de missatges amb l'Ambient Paral·lel"
+
+#: config/rs6000/aix43.h:27 config/rs6000/aix51.h:27 config/rs6000/aix52.h:27
+msgid "Compile for 64-bit pointers"
+msgstr "Compilar per a punters de 64-bit"
+
+#: config/rs6000/aix43.h:29 config/rs6000/aix51.h:29 config/rs6000/aix52.h:29
+msgid "Compile for 32-bit pointers"
+msgstr "Compilar per a punters de 32-bit"
+
+#: config/rs6000/aix43.h:48 config/rs6000/aix51.h:48 config/rs6000/aix52.h:48
+msgid "-maix64 and POWER architecture are incompatible"
+msgstr "-maix64 i l'arquitectura POWER són incompatibles"
+
+#: config/rs6000/aix43.h:53 config/rs6000/aix51.h:53 config/rs6000/aix52.h:53
+msgid "-maix64 requires PowerPC64 architecture remain enabled"
+msgstr "-maix64 requereix que l'arquitectura PowerPC64 romangui activada"
+
+#: config/rs6000/aix43.h:57 config/rs6000/aix51.h:57 config/rs6000/aix52.h:57
+msgid "-maix64 required: 64-bit computation with 32-bit addressing not yet supported"
+msgstr "es requereix -maix64: càlcul de 64 bits amb adreçament de 32 bits no té suport encara"
+
+#: config/rs6000/darwin.h:64
+msgid "Generate code suitable for executables (NOT shared libs)"
+msgstr ""
+
+#. The Darwin ABI always includes AltiVec, can't be (validly) turned
+#. off.
+#: config/rs6000/darwin.h:80
+msgid "-mdynamic-no-pic overrides -fpic or -fPIC"
+msgstr ""
+
+#. Darwin doesn't support -fpic.
+#: config/rs6000/darwin.h:86
+#, fuzzy
+msgid "-fpic is not supported; -fPIC assumed"
+msgstr "el model de codi %s no té suport en el mode PIC"
+
+#: config/rs6000/linux64.h:96
+#, fuzzy
+msgid "-m64 requires a PowerPC64 cpu"
+msgstr "-maix64 requereix que l'arquitectura PowerPC64 romangui activada"
+
+#: config/rs6000/linux64.h:201
+#, fuzzy
+msgid "Call mcount for profiling before a function prologue"
+msgstr "No moure les instruccions al pròleg d'una funció"
+
+#: config/rs6000/linux64.h:203
+#, fuzzy
+msgid "Call mcount for profiling after a function prologue"
+msgstr "No moure les instruccions al pròleg d'una funció"
+
+#. Run-time compilation parameters selecting different hardware subsets.
+#.
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/rs6000/rs6000.h:262
+msgid "Use POWER instruction set"
+msgstr "Usar el conjunt d'instruccions POWER"
+
+#: config/rs6000/rs6000.h:265
+msgid "Use POWER2 instruction set"
+msgstr "Usar el conjunt d'instruccions POWER2"
+
+#: config/rs6000/rs6000.h:267
+msgid "Do not use POWER2 instruction set"
+msgstr "No usar el conjunt d'instruccions POWER2"
+
+#: config/rs6000/rs6000.h:270
+msgid "Do not use POWER instruction set"
+msgstr "No usar el conjunt d'instruccions POWER"
+
+#: config/rs6000/rs6000.h:272
+msgid "Use PowerPC instruction set"
+msgstr "Usar el conjunt d'instruccions PowerPC"
+
+#: config/rs6000/rs6000.h:275
+msgid "Do not use PowerPC instruction set"
+msgstr "No usar el conjunt d'instruccions PowerPC"
+
+#: config/rs6000/rs6000.h:277
+msgid "Use PowerPC General Purpose group optional instructions"
+msgstr "Usar el grup opcional d'instruccions PowerPC de Propòsit General"
+
+#: config/rs6000/rs6000.h:279
+#, fuzzy
+msgid "Do not use PowerPC General Purpose group optional instructions"
+msgstr "No usar el grup opcional d'instruccions PowerPC de Propòsit General"
+
+#: config/rs6000/rs6000.h:281
+msgid "Use PowerPC Graphics group optional instructions"
+msgstr "Usar el grup opcional d'instruccions PowerPC de Gràfiques"
+
+#: config/rs6000/rs6000.h:283
+#, fuzzy
+msgid "Do not use PowerPC Graphics group optional instructions"
+msgstr "No usar el grup opcional d'instruccions PowerPC de Gràfiques"
+
+#: config/rs6000/rs6000.h:285
+msgid "Use PowerPC-64 instruction set"
+msgstr "Usar el conjunt d'instruccions PowerPC-64"
+
+#: config/rs6000/rs6000.h:287
+#, fuzzy
+msgid "Do not use PowerPC-64 instruction set"
+msgstr "No usar el conjunt d'instruccions PowerPC-64"
+
+#: config/rs6000/rs6000.h:289
+msgid "Use AltiVec instructions"
+msgstr "Usar instruccions AltiVec"
+
+#: config/rs6000/rs6000.h:291
+#, fuzzy
+msgid "Do not use AltiVec instructions"
+msgstr "No usar instruccions AltiVec"
+
+#: config/rs6000/rs6000.h:293
+msgid "Use new mnemonics for PowerPC architecture"
+msgstr "Usar els mnemònics nous per a l'arquitectura PowerPC"
+
+#: config/rs6000/rs6000.h:295
+msgid "Use old mnemonics for PowerPC architecture"
+msgstr "Usar els mnemònics vells per a l'arquitectura PowerPC"
+
+#: config/rs6000/rs6000.h:298
+msgid "Put everything in the regular TOC"
+msgstr "Col·locar tot en el TOC normal"
+
+#: config/rs6000/rs6000.h:300
+msgid "Place floating point constants in TOC"
+msgstr "Col·locar les constants de coma flotant en TOC"
+
+#: config/rs6000/rs6000.h:302
+#, fuzzy
+msgid "Do not place floating point constants in TOC"
+msgstr "No col·locar les constants de coma flotant en TOC"
+
+#: config/rs6000/rs6000.h:304
+msgid "Place symbol+offset constants in TOC"
+msgstr "Col·locar les constants símbol+desplaçament en TOC"
+
+#: config/rs6000/rs6000.h:306
+#, fuzzy
+msgid "Do not place symbol+offset constants in TOC"
+msgstr "No col·locar les constants símbol+desplaçament en TOC"
+
+#: config/rs6000/rs6000.h:312
+msgid "Place variable addresses in the regular TOC"
+msgstr "Col·locar les adreces variables en el TOC normal"
+
+#: config/rs6000/rs6000.h:318
+msgid "Generate load/store multiple instructions"
+msgstr "Generar múltiples instruccions load/store"
+
+#: config/rs6000/rs6000.h:320
+msgid "Do not generate load/store multiple instructions"
+msgstr "No generar múltiples instruccions load/store"
+
+#: config/rs6000/rs6000.h:322
+msgid "Generate string instructions for block moves"
+msgstr "Generar instruccions de cadena per a moviment de blocs"
+
+#: config/rs6000/rs6000.h:324
+msgid "Do not generate string instructions for block moves"
+msgstr "No generar instruccions de cadena per a moviment de blocs"
+
+#: config/rs6000/rs6000.h:326
+msgid "Generate load/store with update instructions"
+msgstr "Generar load/store amb instruccions d'actualització"
+
+#: config/rs6000/rs6000.h:328
+msgid "Do not generate load/store with update instructions"
+msgstr "No generar load/store amb instruccions d'actualització"
+
+#: config/rs6000/rs6000.h:332
+#, fuzzy
+msgid "Do not generate fused multiply/add instructions"
+msgstr "No generar instruccions multiply/add de curt circuit"
+
+#: config/rs6000/rs6000.h:336
+#, fuzzy
+msgid "Do not schedule the start and end of the procedure"
+msgstr "No calendaritzar l'inici i el final del procediment"
+
+#: config/rs6000/rs6000.h:342
+msgid "Return all structures in memory (AIX default)"
+msgstr "Regressar totes les estructures en memòria (per omissió en AIX)"
+
+#: config/rs6000/rs6000.h:344
+msgid "Return small structures in registers (SVR4 default)"
+msgstr "Regressar les petites estructures en registres (per omissió en SVR4)"
+
+#: config/rs6000/rs6000.h:350
+#, fuzzy
+msgid "Generate single field mfcr instruction"
+msgstr "Generar instruccions char"
+
+#: config/rs6000/rs6000.h:352
+#, fuzzy
+msgid "Do not generate single field mfcr instruction"
+msgstr "No generar instruccions char"
+
+#: config/rs6000/rs6000.h:435 config/sparc/sparc.h:654
+msgid "Use features of and schedule code for given CPU"
+msgstr "Usar característiques i calendaritzar el codi per al CPU donat"
+
+#: config/rs6000/rs6000.h:438
+msgid "Enable debug output"
+msgstr "Activar la sortida de depuració"
+
+#: config/rs6000/rs6000.h:440
+msgid "Select full, part, or no traceback table"
+msgstr ""
+
+#: config/rs6000/rs6000.h:441
+msgid "Specify ABI to use"
+msgstr "Especificar el ABI a utilitzar"
+
+#: config/rs6000/rs6000.h:443
+msgid "Specify size of long double (64 or 128 bits)"
+msgstr "Especificar la grandària de long double (64 o 128 bits)"
+
+#: config/rs6000/rs6000.h:445
+msgid "Specify yes/no if isel instructions should be generated"
+msgstr ""
+
+#: config/rs6000/rs6000.h:447
+msgid "Specify yes/no if SPE SIMD instructions should be generated"
+msgstr ""
+
+#: config/rs6000/rs6000.h:449
+#, fuzzy
+msgid "Specify yes/no if using floating point in the GPRs"
+msgstr "Especifica la versió de l'emulador de nombre de coma flotant"
+
+#: config/rs6000/rs6000.h:451
+msgid "Specify yes/no if VRSAVE instructions should be generated for AltiVec"
+msgstr ""
+
+#: config/rs6000/rs6000.h:453
+msgid "Avoid all range limits on call instructions"
+msgstr "Evitar tots els límits de rang en les instruccions de cridades"
+
+#: config/rs6000/rs6000.h:456
+msgid "Determine which dependences between insns are considered costly"
+msgstr ""
+
+#: config/rs6000/rs6000.h:458
+msgid "Specify which post scheduling nop insertion scheme to apply"
+msgstr ""
+
+#: config/rs6000/rs6000.h:460
+#, fuzzy
+msgid "Specify alignment of structure fields default/natural"
+msgstr "Especificar l'alineació mínima de bit de les estructures"
+
+#: config/rs6000/rs6000.h:462
+msgid "Specify scheduling priority for dispatch slot restricted insns"
+msgstr ""
+
+#. Definitions for __builtin_return_address and __builtin_frame_address.
+#. __builtin_return_address (0) should give link register (65), enable
+#. this.
+#. This should be uncommented, so that the link register is used, but
+#. currently this would result in unmatched insns and spilling fixed
+#. registers so we'll leave it for another day. When these problems are
+#. taken care of one additional fetch will be necessary in RETURN_ADDR_RTX.
+#. (mrs)
+#. #define RETURN_ADDR_IN_PREVIOUS_FRAME
+#. Number of bytes into the frame return addresses can be found. See
+#. rs6000_stack_info in rs6000.c for more information on how the different
+#. abi's store the return address.
+#: config/rs6000/rs6000.h:1929
+msgid "RETURN_ADDRESS_OFFSET not supported"
+msgstr "No es dona suport a RETURN_ADDRESS_OFFSET"
+
+#: config/rs6000/sysv4.h:87
+msgid "Select ABI calling convention"
+msgstr "Seleccionar la convenció de cridada ABI"
+
+#: config/rs6000/sysv4.h:88
+msgid "Select method for sdata handling"
+msgstr "Seleccionar el mètode per al maneig de sdata"
+
+#: config/rs6000/sysv4.h:100
+msgid "Align to the base type of the bit-field"
+msgstr "Alinear al tipus base del camp de bit"
+
+#: config/rs6000/sysv4.h:102
+msgid "Don't align to the base type of the bit-field"
+msgstr "No alinear al tipus base del camp de bit"
+
+#: config/rs6000/sysv4.h:104
+msgid "Don't assume that unaligned accesses are handled by the system"
+msgstr "No assumir que els accessos sense alinear són manejats pel sistema"
+
+#: config/rs6000/sysv4.h:106
+msgid "Assume that unaligned accesses are handled by the system"
+msgstr "Assumir que els accessos sense alinear són manejats pel sistema"
+
+#: config/rs6000/sysv4.h:108 config/rs6000/sysv4.h:112
+msgid "Produce code relocatable at runtime"
+msgstr "Produir codi re-ubicable en el moment d'execució"
+
+#: config/rs6000/sysv4.h:110 config/rs6000/sysv4.h:114
+msgid "Don't produce code relocatable at runtime"
+msgstr "No produir codi re-ubicable en el moment d'execució"
+
+#: config/rs6000/sysv4.h:116 config/rs6000/sysv4.h:118
+msgid "Produce little endian code"
+msgstr "Produir codi little endian"
+
+#: config/rs6000/sysv4.h:120 config/rs6000/sysv4.h:122
+msgid "Produce big endian code"
+msgstr "Produir codi big endian"
+
+#: config/rs6000/sysv4.h:123 config/rs6000/sysv4.h:124
+#: config/rs6000/sysv4.h:125 config/rs6000/sysv4.h:126
+#: config/rs6000/sysv4.h:127 config/rs6000/sysv4.h:128
+#: config/rs6000/sysv4.h:138 config/rs6000/sysv4.h:139
+#: config/rs6000/sysv4.h:151 config/rs6000/sysv4.h:157
+msgid "no description yet"
+msgstr "sense descripció encara"
+
+#: config/rs6000/sysv4.h:129
+msgid "Use EABI"
+msgstr "Usar EABI"
+
+#: config/rs6000/sysv4.h:130
+msgid "Don't use EABI"
+msgstr "No usar EABI"
+
+#: config/rs6000/sysv4.h:133
+msgid "Do not allow bit-fields to cross word boundaries"
+msgstr "No permetre que els camps de bits creuin els límits de word"
+
+#: config/rs6000/sysv4.h:135
+msgid "Use alternate register names"
+msgstr "Usar noms de registre alternats"
+
+#: config/rs6000/sysv4.h:137
+msgid "Don't use alternate register names"
+msgstr "No usar noms de registre alternats"
+
+#: config/rs6000/sysv4.h:141
+msgid "Link with libsim.a, libc.a and sim-crt0.o"
+msgstr "Enllaçar amb libsim.a, libc.a i sim-crt0.o"
+
+#: config/rs6000/sysv4.h:143
+msgid "Link with libads.a, libc.a and crt0.o"
+msgstr "Enllaçar amb libads.a, libc.a i crt0.o"
+
+#: config/rs6000/sysv4.h:145
+msgid "Link with libyk.a, libc.a and crt0.o"
+msgstr "Enllaçar amb libyk.a, libc.a i crt0.o"
+
+#: config/rs6000/sysv4.h:147
+msgid "Link with libmvme.a, libc.a and crt0.o"
+msgstr "Enllaçar amb libmvme.a, libc.a i crt0.o"
+
+#: config/rs6000/sysv4.h:149
+msgid "Set the PPC_EMB bit in the ELF flags header"
+msgstr "Activar el bit PPC_EMB en els interruptors de l'encapçalat ELF"
+
+#: config/rs6000/sysv4.h:150
+msgid "Use the WindISS simulator"
+msgstr ""
+
+#: config/rs6000/sysv4.h:153
+#, fuzzy
+msgid "Generate 64-bit code"
+msgstr "Generar codi 64 bit per a x86-64"
+
+#: config/rs6000/sysv4.h:155
+#, fuzzy
+msgid "Generate 32-bit code"
+msgstr "Generar codi 32 bit per a i386"
+
+#. Sometimes certain combinations of command options do not make sense
+#. on a particular target machine. You can define a macro
+#. `OVERRIDE_OPTIONS' to take account of this. This macro, if
+#. defined, is executed once just after all the command options have
+#. been parsed.
+#.
+#. The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to
+#. get control.
+#: config/rs6000/sysv4.h:214
+#, c-format
+msgid "bad value for -mcall-%s"
+msgstr "valor erroni per a -mcall-%s"
+
+#: config/rs6000/sysv4.h:230
+#, c-format
+msgid "bad value for -msdata=%s"
+msgstr "valor erroni per a -msdata=%s"
+
+#: config/rs6000/sysv4.h:247
+#, c-format
+msgid "-mrelocatable and -msdata=%s are incompatible"
+msgstr "-mrelocatable and i -msdata=%s són incompatibles"
+
+#: config/rs6000/sysv4.h:256
+#, c-format
+msgid "-f%s and -msdata=%s are incompatible"
+msgstr "-f%s i -msdata=%s són incompatibles"
+
+#: config/rs6000/sysv4.h:265
+#, c-format
+msgid "-msdata=%s and -mcall-%s are incompatible"
+msgstr "-msdata=%s i -mcall-%s són incompatibles"
+
+#: config/rs6000/sysv4.h:274
+msgid "-mrelocatable and -mno-minimal-toc are incompatible"
+msgstr "-mrelocatable i -mno-minimal-toc són incompatibles"
+
+#: config/rs6000/sysv4.h:280
+#, c-format
+msgid "-mrelocatable and -mcall-%s are incompatible"
+msgstr "-mrelocatable i -mcall-%s són incompatibles"
+
+#: config/rs6000/sysv4.h:287
+#, c-format
+msgid "-fPIC and -mcall-%s are incompatible"
+msgstr "-fPIC i -mcall-%s són incompatibles"
+
+#: config/rs6000/sysv4.h:294
+msgid "-mcall-aixdesc must be big endian"
+msgstr "-mcall-aixdesc deu ser big endian"
+
+#: config/rs6000/sysv4.h:309
+#, fuzzy, c-format
+msgid "-m%s not supported in this configuration"
+msgstr "%s no té suport en aquesta configuració"
+
+#: config/s390/s390.c:926
+#, c-format
+msgid "Unknown cpu used in -march=%s."
+msgstr ""
+
+#: config/s390/s390.c:945
+#, fuzzy, c-format
+msgid "Unknown cpu used in -mtune=%s."
+msgstr "especificació de versió de cpu de CRIS desconeguda en -mtune= : %s"
+
+#: config/s390/s390.c:950
+#, fuzzy, c-format
+msgid "z/Architecture mode not supported on %s."
+msgstr "no és dona suport al mode trap en Unicos/Mk"
+
+#: config/s390/s390.c:952
+#, fuzzy
+msgid "64-bit ABI not supported in ESA/390 mode."
+msgstr "el model de codi %s no té suport en el mode PIC"
+
+#: config/s390/s390.c:3336
+msgid "invalid UNSPEC as operand (1)"
+msgstr "UNSPEC invàlid com operant (1)"
+
+#: config/s390/s390.c:3384
+msgid "invalid UNSPEC as operand (2)"
+msgstr "UNSPEC invàlid com operant (2)"
+
+#: config/s390/s390.c:3390
+msgid "UNKNOWN in s390_output_symbolic_const !?"
+msgstr "UNKNOWN en s390_output_symbolic_const !?"
+
+#: config/s390/s390.c:3406
+msgid "Cannot decompose address."
+msgstr "No es pot descompondre l'adreça."
+
+#: config/s390/s390.c:3577
+msgid "UNKNOWN in print_operand !?"
+msgstr "UNKNOWN en print_operand !?"
+
+#: config/s390/s390.c:5304
+msgid "Total size of local variables exceeds architecture limit."
+msgstr "La grandària total de les variables locals excedeix el límit de l'arquitectura."
+
+#: config/s390/s390.h:126
+msgid "Set backchain"
+msgstr "Establir la cadena cap a endarrere"
+
+#: config/s390/s390.h:127
+msgid "Don't set backchain (faster, but debug harder"
+msgstr "No establir la cadena cap a endarrere (més ràpid, però més difícil de depurar"
+
+#: config/s390/s390.h:128
+msgid "Use bras for executable < 64k"
+msgstr "Usar bras per a executable < 64k"
+
+#: config/s390/s390.h:129
+msgid "Don't use bras"
+msgstr "No usar bras"
+
+#: config/s390/s390.h:130
+msgid "Additional debug prints"
+msgstr "Impressions addicionals de depuració"
+
+#: config/s390/s390.h:131
+msgid "Don't print additional debug prints"
+msgstr "No imprimir impressions addicionals de depuració"
+
+#: config/s390/s390.h:132
+#, fuzzy
+msgid "64 bit ABI"
+msgstr "Usar el ABI 64 bits"
+
+#: config/s390/s390.h:133
+#, fuzzy
+msgid "31 bit ABI"
+msgstr "Usar el ABI 64 bits"
+
+#: config/s390/s390.h:134
+msgid "z/Architecture"
+msgstr ""
+
+#: config/s390/s390.h:135
+msgid "ESA/390 architecture"
+msgstr ""
+
+#: config/s390/s390.h:136
+msgid "mvcle use"
+msgstr "ùs de mvcle"
+
+#: config/s390/s390.h:137
+msgid "mvc&ex"
+msgstr "mvc&ex"
+
+#: config/s390/s390.h:138
+#, fuzzy
+msgid "enable tpf OS code"
+msgstr "Generar codi SA"
+
+#: config/s390/s390.h:139
+msgid "disable tpf OS code"
+msgstr ""
+
+#: config/s390/s390.h:140
+#, fuzzy
+msgid "disable fused multiply/add instructions"
+msgstr "Generar instruccions multiply/add de curt circuit"
+
+#: config/s390/s390.h:141
+#, fuzzy
+msgid "enable fused multiply/add instructions"
+msgstr "Generar instruccions multiply/add de curt circuit"
+
+#: config/sh/sh.c:5841
+msgid "__builtin_saveregs not supported by this subtarget"
+msgstr "no es dóna suport a _builtin_saveregs en aquest subobjectiu"
+
+#: config/sh/sh.c:6743
+msgid "attribute interrupt_handler is not compatible with -m5-compact"
+msgstr ""
+
+#. The sp_switch attribute only has meaning for interrupt functions.
+#: config/sh/sh.c:6765 config/sh/sh.c:6800
+#, c-format
+msgid "`%s' attribute only applies to interrupt functions"
+msgstr "l'atribut \"%s\" aplica solament a funcions d'interrupció"
+
+#. The argument must be a constant string.
+#: config/sh/sh.c:6772
+#, c-format
+msgid "`%s' attribute argument not a string constant"
+msgstr "l'argument de l'atribut \"%s\" no és una cadena constant"
+
+#. The argument must be a constant integer.
+#: config/sh/sh.c:6807
+#, c-format
+msgid "`%s' attribute argument not an integer constant"
+msgstr "l'argument de l'atribut \"%s\" no és una cadena entera"
+
+#. There are no delay slots on SHmedia.
+#. Relaxation isn't yet supported for SHmedia
+#. -fprofile-arcs needs a working libgcov . In unified tree configurations with newlib, this requires to configure with --with-newlib --with-headers. But there is no way to check here we have a working libgcov, so just assume that we have.
+#: config/sh/sh.h:478
+msgid "Profiling is not supported on this target."
+msgstr "No es dóna suport a anàlisi de perfil en aquest objectiu."
+
+#: config/sparc/sparc.c:360
+#, c-format
+msgid "%s is not supported by this configuration"
+msgstr "%s no té suport en aquesta configuració"
+
+#: config/sparc/sparc.c:367
+msgid "-mlong-double-64 not allowed with -m64"
+msgstr "no es permet -mlong-double-64 amb -m64"
+
+#: config/sparc/sparc.c:392
+msgid "-mcmodel= is not supported on 32 bit systems"
+msgstr "-mcmodel= no té suport en sistemes de 32 bit"
+
+#: config/sparc/sparc.c:6793 config/sparc/sparc.c:6799
+#, c-format
+msgid "invalid %%Y operand"
+msgstr "operant %%Y invàlid"
+
+#: config/sparc/sparc.c:6869
+#, c-format
+msgid "invalid %%A operand"
+msgstr "operant %%A invàlid"
+
+#: config/sparc/sparc.c:6879
+#, c-format
+msgid "invalid %%B operand"
+msgstr "operant %%B invàlid"
+
+#: config/sparc/sparc.c:6918
+#, c-format
+msgid "invalid %%c operand"
+msgstr "operant %%c invàlid"
+
+#: config/sparc/sparc.c:6919
+#, c-format
+msgid "invalid %%C operand"
+msgstr "operant %%C invàlid"
+
+#: config/sparc/sparc.c:6940
+#, c-format
+msgid "invalid %%d operand"
+msgstr "operant %%d invàlid"
+
+#: config/sparc/sparc.c:6941
+#, c-format
+msgid "invalid %%D operand"
+msgstr "operant %%D invàlid"
+
+#: config/sparc/sparc.c:6957
+#, c-format
+msgid "invalid %%f operand"
+msgstr "operant %%f invàlid"
+
+#: config/sparc/sparc.c:6971
+#, c-format
+msgid "invalid %%s operand"
+msgstr "operant %%s invàlid"
+
+#: config/sparc/sparc.c:7025
+msgid "long long constant not a valid immediate operand"
+msgstr "la constant long long no és un operant immediat vàlid"
+
+#: config/sparc/sparc.c:7028
+msgid "floating point constant not a valid immediate operand"
+msgstr "la constant de coma flotant no és un operant immediat vàlid"
+
+#: config/sparc/freebsd.h:81 config/sparc/linux.h:92
+#: config/sparc/linux64.h:104 config/sparc/netbsd-elf.h:216
+msgid "Use 128 bit long doubles"
+msgstr "Usar long doubles de 128 bits"
+
+#: config/sparc/sp64-elf.h:90
+msgid "Generate code for big endian"
+msgstr "Generar codi per a big endian"
+
+#: config/sparc/sp64-elf.h:91
+msgid "Generate code for little endian"
+msgstr "Generar codi per a little endian"
+
+#: config/sparc/sp86x-elf.h:68
+msgid "Use little-endian byte order for data"
+msgstr "Usar l'ordre d'octet little-endian per a les dades"
+
+#: config/sparc/sparc.h:553
+msgid "Assume possible double misalignment"
+msgstr "Assumir desalineació de double possible"
+
+#: config/sparc/sparc.h:555
+msgid "Assume all doubles are aligned"
+msgstr "Assumir que tots els doubles estan alineats"
+
+#: config/sparc/sparc.h:557
+msgid "Pass -assert pure-text to linker"
+msgstr "Passar el text pur de -assert al enllaçador"
+
+#: config/sparc/sparc.h:559
+msgid "Do not pass -assert pure-text to linker"
+msgstr "No passar el text pur de -assert al enllaçador"
+
+#: config/sparc/sparc.h:561
+msgid "Use flat register window model"
+msgstr "Usar el model pla de finestra de registre"
+
+#: config/sparc/sparc.h:563
+msgid "Do not use flat register window model"
+msgstr "No usar el model pla de finestra de registre"
+
+#: config/sparc/sparc.h:565
+msgid "Use ABI reserved registers"
+msgstr "Usar els registres ABI reservats"
+
+#: config/sparc/sparc.h:567
+msgid "Do not use ABI reserved registers"
+msgstr "No usar els registres ABI reservats"
+
+#: config/sparc/sparc.h:569
+msgid "Use hardware quad fp instructions"
+msgstr "Usar instruccions de fp quad de maquinari"
+
+#: config/sparc/sparc.h:571
+msgid "Do not use hardware quad fp instructions"
+msgstr "No usar instruccions de fp quad de maquinari"
+
+#: config/sparc/sparc.h:573
+msgid "Compile for v8plus ABI"
+msgstr "Compilar per a el ABI de v8plus"
+
+#: config/sparc/sparc.h:575
+msgid "Do not compile for v8plus ABI"
+msgstr "No compilar per a el ABI de v8plus"
+
+#: config/sparc/sparc.h:577
+msgid "Utilize Visual Instruction Set"
+msgstr "Utilitzar el Conjunt d'Instruccions Visuals"
+
+#: config/sparc/sparc.h:579
+msgid "Do not utilize Visual Instruction Set"
+msgstr "No utilitzar el Conjunt d'Instruccions Visuals"
+
+#. ??? These are deprecated, coerced to -mcpu=. Delete in 2.9.
+#: config/sparc/sparc.h:582
+msgid "Optimize for Cypress processors"
+msgstr "Optimitzar per als processadors Cypress"
+
+#: config/sparc/sparc.h:584
+msgid "Optimize for SPARCLite processors"
+msgstr "Optimitzar per als processadors SPARCLite"
+
+#: config/sparc/sparc.h:586
+msgid "Optimize for F930 processors"
+msgstr "Optimitzar per als processadors F930"
+
+#: config/sparc/sparc.h:588
+msgid "Optimize for F934 processors"
+msgstr "Optimitzar per als processadors F934"
+
+#: config/sparc/sparc.h:590
+msgid "Use V8 SPARC ISA"
+msgstr "Usar el ISA V8 de SPARC"
+
+#: config/sparc/sparc.h:592
+msgid "Optimize for SuperSPARC processors"
+msgstr "Optimitzar per als processadors SuperSPARC"
+
+#. End of deprecated options.
+#: config/sparc/sparc.h:595
+msgid "Pointers are 64-bit"
+msgstr "El punters són de 64 bits"
+
+#: config/sparc/sparc.h:597
+msgid "Pointers are 32-bit"
+msgstr "El punters són de 32 bits"
+
+#: config/sparc/sparc.h:599
+msgid "Use 32-bit ABI"
+msgstr "Usar el ABI 32 bits"
+
+#: config/sparc/sparc.h:601
+msgid "Use 64-bit ABI"
+msgstr "Usar el ABI 64 bits"
+
+#: config/sparc/sparc.h:603
+msgid "Use stack bias"
+msgstr "Usar tendència de la pila"
+
+#: config/sparc/sparc.h:605
+msgid "Do not use stack bias"
+msgstr "No usar tendència de la pila"
+
+#: config/sparc/sparc.h:607
+msgid "Use structs on stronger alignment for double-word copies"
+msgstr "Usar structs en alineació més forta per a còpies double-word"
+
+#: config/sparc/sparc.h:609
+msgid "Do not use structs on stronger alignment for double-word copies"
+msgstr "No usar structs en alineació més forta per a còpies double-word"
+
+#: config/sparc/sparc.h:611
+msgid "Optimize tail call instructions in assembler and linker"
+msgstr "Optimitzar les instruccions de la cridada de l'extrem en el ensemblador i el enllaçador"
+
+#: config/sparc/sparc.h:613
+msgid "Do not optimize tail call instructions in assembler or linker"
+msgstr "No optimitzar les instruccions de la cridada de l'extrem en el ensemblador i el enllaçador"
+
+#: config/sparc/sparc.h:658
+msgid "Use given SPARC code model"
+msgstr "Usar el model de codi del SPARC donat"
+
+#: config/stormy16/stormy16.c:526
+#, fuzzy
+msgid "Constant halfword load operand out of range."
+msgstr "l'argument constant està fora de rang per a \"%s\""
+
+#: config/stormy16/stormy16.c:536
+#, fuzzy
+msgid "Constant arithmetic operand out of range."
+msgstr "l'argument constant està fora de rang per a \"%s\""
+
+#: config/stormy16/stormy16.c:1027
+msgid "Local variable memory requirements exceed capacity."
+msgstr ""
+
+#: config/stormy16/stormy16.c:1193
+#, fuzzy
+msgid "function_profiler support"
+msgstr "suport per a function_profiler per a MMIX"
+
+#: config/stormy16/stormy16.c:1292
+msgid "cannot use va_start in interrupt function"
+msgstr "no es pot usar va_start en una funció d'interrupció"
+
+#: config/stormy16/stormy16.c:1624
+msgid "`B' operand is not constant"
+msgstr "l'operant \"B\" no és una constant"
+
+#: config/stormy16/stormy16.c:1630
+msgid "`B' operand has multiple bits set"
+msgstr "l'operant \"B\" té establerts múltiples bits"
+
+#: config/stormy16/stormy16.c:1656
+msgid "`o' operand is not constant"
+msgstr "l'operant \"o\" no és una constant"
+
+#: config/stormy16/stormy16.c:1670
+msgid "xstormy16_print_operand: unknown code"
+msgstr "xstormy16_print_operand: codi desconegut"
+
+#: config/stormy16/stormy16.c:1716
+#, c-format
+msgid "switch statement of size %lu entries too large"
+msgstr "la declaració switch de grandària de %lu entrades és massa gran"
+
+#: config/v850/v850-c.c:67
+msgid "#pragma GHS endXXXX found without previous startXXX"
+msgstr "es va trobar un #pragma GHS endXXXX sense un startXXX previ"
+
+#: config/v850/v850-c.c:69
+msgid "#pragma GHS endXXX does not match previous startXXX"
+msgstr "el #pragma GHS endXXXX no coincideix amb el startXXX previ"
+
+#: config/v850/v850-c.c:94
+msgid "cannot set interrupt attribute: no current function"
+msgstr "no es pot establir l'atribut d'interrupció: no hi ha funció actual"
+
+#: config/v850/v850-c.c:102
+msgid "cannot set interrupt attribute: no such identifier"
+msgstr "no es pot establir l'atribut d'interrupció: no hi ha tal identificador"
+
+#: config/v850/v850-c.c:147
+msgid "junk at end of #pragma ghs section"
+msgstr "escombraries al final de la secció #pragma ghs"
+
+#: config/v850/v850-c.c:164
+#, c-format
+msgid "unrecognized section name \"%s\""
+msgstr "no es reconeix el nom de secció \"%s\""
+
+#: config/v850/v850-c.c:179
+msgid "malformed #pragma ghs section"
+msgstr "secció #pragma ghs malformada"
+
+#: config/v850/v850-c.c:198
+msgid "junk at end of #pragma ghs interrupt"
+msgstr "escombraries al final del #pragma ghs interrupt"
+
+#: config/v850/v850-c.c:209
+msgid "junk at end of #pragma ghs starttda"
+msgstr "escombraries al final del #pragma ghs starttda"
+
+#: config/v850/v850-c.c:220
+msgid "junk at end of #pragma ghs startsda"
+msgstr "escombraries al final del #pragma ghs startsda"
+
+#: config/v850/v850-c.c:231
+msgid "junk at end of #pragma ghs startzda"
+msgstr "escombraries al final del #pragma ghs startzda"
+
+#: config/v850/v850-c.c:242
+msgid "junk at end of #pragma ghs endtda"
+msgstr "escombraries al final del #pragma ghs endtda"
+
+#: config/v850/v850-c.c:253
+msgid "junk at end of #pragma ghs endsda"
+msgstr "escombraries al final del #pragma ghs endsda"
+
+#: config/v850/v850-c.c:264
+msgid "junk at end of #pragma ghs endzda"
+msgstr "escombraries al final del #pragma ghs endzda"
+
+#: config/v850/v850.c:142
+#, c-format
+msgid "%s=%s is not numeric"
+msgstr "%s=%s no és numèric"
+
+#: config/v850/v850.c:149
+#, c-format
+msgid "%s=%s is too large"
+msgstr "%s=%s é massa gran"
+
+#: config/v850/v850.c:301
+msgid "const_double_split got a bad insn:"
+msgstr "const_double_split va rebre un insn erroni:"
+
+#: config/v850/v850.c:866
+msgid "output_move_single:"
+msgstr "output_move_single:"
+
+#: config/v850/v850.c:2209
+#, fuzzy
+msgid "%Jdata area attributes cannot be specified for local variables"
+msgstr "no es pot especificar un atribut d'àrea de dades per a variables locals"
+
+#: config/v850/v850.c:2220
+#, fuzzy
+msgid "%Jdata area of '%D' conflicts with previous declaration"
+msgstr "l'àrea de dades de \"%s\" en conflicte amb una declaració prèvia"
+
+#: config/v850/v850.c:2419
+#, c-format
+msgid "bogus JR construction: %d\n"
+msgstr "construcció JR ambigua: %d\n"
+
+#: config/v850/v850.c:2440 config/v850/v850.c:2643
+#, c-format
+msgid "bad amount of stack space removal: %d"
+msgstr "quantitat errònia d'eliminació d'espai de pila: %d"
+
+#: config/v850/v850.c:2619
+#, c-format
+msgid "bogus JARL construction: %d\n"
+msgstr "construcció JARL ambigua: %d\n"
+
+#: config/v850/v850.c:2989
+#, c-format
+msgid "Bogus DISPOSE construction: %d\n"
+msgstr "construcció DISPOSE ambigua: %d\n"
+
+#: config/v850/v850.c:3011
+#, c-format
+msgid "Too much stack space to dispose of: %d"
+msgstr ""
+
+#: config/v850/v850.c:3184
+#, c-format
+msgid "Bogus PREPEARE construction: %d\n"
+msgstr "construcció PREPEARE ambigua: %d\n"
+
+#: config/v850/v850.c:3206
+#, c-format
+msgid "Too much stack space to prepare: %d"
+msgstr "Massa espai de pila per a preparar: %d"
+
+#. Macro to define tables used to set the flags.
+#. This is a list in braces of pairs in braces,
+#. each pair being { "NAME", VALUE }
+#. where VALUE is the bits to set or minus the bits to clear.
+#. An empty string NAME is used to identify the default VALUE.
+#: config/v850/v850.h:174
+msgid "Support Green Hills ABI"
+msgstr "Dona suport al ABI Green Hills"
+
+#: config/v850/v850.h:177
+msgid "Prohibit PC relative function calls"
+msgstr "Prohibir la cridada a funcions relatives al PC"
+
+#: config/v850/v850.h:180
+msgid "Reuse r30 on a per function basis"
+msgstr "Reusar r30 basat per funció"
+
+#: config/v850/v850.h:183
+msgid "Use stubs for function prologues"
+msgstr "Usar caps per als pròlegs de funció"
+
+#: config/v850/v850.h:186
+msgid "Same as: -mep -mprolog-function"
+msgstr "Igual que: -mep -mprolog-function"
+
+#: config/v850/v850.h:187
+msgid "Enable backend debugging"
+msgstr "Habilitar la depuració per la fi"
+
+#: config/v850/v850.h:189
+msgid "Compile for the v850 processor"
+msgstr "Compilar per al processador v850"
+
+#: config/v850/v850.h:191
+#, fuzzy
+msgid "Compile for v850e1 processor"
+msgstr "Compilar per al processador v850e"
+
+#. Make sure that the other bits are cleared.
+#: config/v850/v850.h:193
+msgid "Compile for v850e processor"
+msgstr "Compilar per al processador v850e"
+
+#. Make sure that the other bits are cleared.
+#: config/v850/v850.h:195
+msgid "Enable the use of the short load instructions"
+msgstr "Activar l'ús de les instruccions short load"
+
+#: config/v850/v850.h:198
+msgid "Do not use the callt instruction"
+msgstr "No usar la instrucció callt"
+
+#: config/v850/v850.h:205
+msgid "Do not use registers r2 and r5"
+msgstr "No usar els registres r2 i r5"
+
+#: config/v850/v850.h:207
+msgid "Enforce strict alignment"
+msgstr "Reforçar l'alineació estricta"
+
+#: config/v850/v850.h:210
+msgid "Use 4 byte entries in switch tables"
+msgstr "Usar entrades de 4 octet en les matrius de switch"
+
+#: config/v850/v850.h:236
+msgid "Set the max size of data eligible for the TDA area"
+msgstr "Establir la grandària màxima de dades elegibles per a l'àrea TDA"
+
+#: config/v850/v850.h:239
+msgid "Set the max size of data eligible for the SDA area"
+msgstr "Establir la grandària màxima de dades elegibles per a l'àrea SDA"
+
+#: config/v850/v850.h:242
+msgid "Set the max size of data eligible for the ZDA area"
+msgstr "Establir la grandària màxima de dades elegibles per a l'àrea ZDA"
+
+#: config/xtensa/xtensa.c:1828
+msgid "boolean registers required for the floating-point option"
+msgstr "es requereixen registres booleans per a l'opció de coma flotant"
+
+#: config/xtensa/xtensa.c:1882
+#, fuzzy, c-format
+msgid "-f%s is not supported with CONST16 instructions"
+msgstr "%s no té suport en aquesta configuració"
+
+#: config/xtensa/xtensa.c:1887
+msgid "PIC is required but not supported with CONST16 instructions"
+msgstr ""
+
+#: config/xtensa/xtensa.c:1957
+#, c-format
+msgid "invalid %%D value"
+msgstr "valor invàlid per a %%D"
+
+#: config/xtensa/xtensa.c:1994
+msgid "invalid mask"
+msgstr "màscara invàlida"
+
+#: config/xtensa/xtensa.c:2020
+#, fuzzy, c-format
+msgid "invalid %%x value"
+msgstr "valor invàlid per a %%x/X"
+
+#: config/xtensa/xtensa.c:2027
+#, fuzzy, c-format
+msgid "invalid %%d value"
+msgstr "valor %%v invàlid"
+
+#: config/xtensa/xtensa.c:2048 config/xtensa/xtensa.c:2058
+#, fuzzy, c-format
+msgid "invalid %%t/%%b value"
+msgstr "valor %%b invàlid"
+
+#: config/xtensa/xtensa.c:2100
+msgid "invalid address"
+msgstr "adreça invàlida"
+
+#: config/xtensa/xtensa.c:2125
+msgid "no register in address"
+msgstr "no hi ha registre en l'adreça"
+
+#: config/xtensa/xtensa.c:2133
+msgid "address offset not a constant"
+msgstr "el desplaçament d'adreça no és una constant"
+
+#: config/xtensa/xtensa.c:2744
+msgid "only uninitialized variables can be placed in a .bss section"
+msgstr "només les variables sense inicialitzar es poden col·locar en una secció .bss"
+
+#: config/xtensa/xtensa.h:79
+#, fuzzy
+msgid "Use CONST16 instruction to load constants"
+msgstr "Usar instruccions push per a guardar els arguments de sortida"
+
+#: config/xtensa/xtensa.h:81
+#, fuzzy
+msgid "Use PC-relative L32R instruction to load constants"
+msgstr "Usar instruccions CALLn directes per a cridades ràpides"
+
+#: config/xtensa/xtensa.h:83
+msgid "Disable fused multiply/add and multiply/subtract FP instructions"
+msgstr "Desactivar les instruccions FP multiply/add i multiply/substract de curt circuit"
+
+#: config/xtensa/xtensa.h:85
+msgid "Enable fused multiply/add and multiply/subtract FP instructions"
+msgstr "Activar les instruccions FP multiply/add i multiply/substract de curt circuit"
+
+#: config/xtensa/xtensa.h:87
+msgid "Intersperse literal pools with code in the text section"
+msgstr "Entremesclar els conjunts de literals amb codi en la secció de text"
+
+#: config/xtensa/xtensa.h:89
+msgid "Put literal pools in a separate literal section"
+msgstr "Posar els conjunts de literals en una secció literal separada"
+
+#: config/xtensa/xtensa.h:91
+msgid "Automatically align branch targets to reduce branch penalties"
+msgstr "Alinear automàticament els objectius de les ramificacions per a reduir les faltes de ramificació"
+
+#: config/xtensa/xtensa.h:93
+msgid "Do not automatically align branch targets"
+msgstr "No alinear automàticament els objectius de les ramificacions"
+
+#: config/xtensa/xtensa.h:95
+msgid "Use indirect CALLXn instructions for large programs"
+msgstr "Usar instruccions CALLXn indirectes per a programes grans"
+
+#: config/xtensa/xtensa.h:97
+msgid "Use direct CALLn instructions for fast calls"
+msgstr "Usar instruccions CALLn directes per a cridades ràpides"
+
+#: ada/misc.c:240
+#, c-format
+msgid "missing argument to \"-%s\""
+msgstr "Falten arguments per a \"-%s\""
+
+#: ada/misc.c:281
+msgid "`-gnat' misspelled as `-gant'"
+msgstr "\"-gnat\" mal lletrejat com \"-gant\""
+
+#: cp/call.c:217
+msgid "unable to call pointer to member function here"
+msgstr "no es pot cridar un punter a una funció membre aquí"
+
+#: cp/call.c:2228
+msgid "%s %D(%T, %T, %T) <built-in>"
+msgstr "%s %D(%T, %T, %T) <intern>"
+
+#: cp/call.c:2233
+msgid "%s %D(%T, %T) <built-in>"
+msgstr "%s %D(%T, %T) <intern>"
+
+#: cp/call.c:2237
+msgid "%s %D(%T) <built-in>"
+msgstr "%s %D(%T) <intern>"
+
+#: cp/call.c:2241
+msgid "%s %T <conversion>"
+msgstr "%s %T <conversió>"
+
+#: cp/call.c:2243
+msgid "%J%s %+#D <near match>"
+msgstr ""
+
+#: cp/call.c:2245
+#, fuzzy
+msgid "%J%s %+#D"
+msgstr "%s %+#D"
+
+#: cp/call.c:2280
+msgid "candidates are:"
+msgstr ""
+
+#: cp/call.c:2468
+msgid "conversion from `%T' to `%T' is ambiguous"
+msgstr "la conversió de \"%T\" a \"%T\" és ambigua"
+
+#: cp/call.c:2619 cp/call.c:2663
+msgid "no matching function for call to `%D(%A)'"
+msgstr "no hi ha una funció coincident per a la cridada a \"%D(%A)\""
+
+#: cp/call.c:2622 cp/call.c:2666
+msgid "call of overloaded `%D(%A)' is ambiguous"
+msgstr "la cridada del \"%D(%A)\" sobrecarregat és ambigua"
+
+#. It's no good looking for an overloaded operator() on a
+#. pointer-to-member-function.
+#: cp/call.c:2732
+#, c-format
+msgid "pointer-to-member function %E cannot be called without an object; consider using .* or ->*"
+msgstr "la funció punter-a-membre %E no es pot cridar dintre d'un objecte; consideri utilitzar .* o ->*"
+
+#: cp/call.c:2798
+msgid "no match for call to `(%T) (%A)'"
+msgstr "no hi ha coincidència per a la cridada a \"(%T) (%A)\""
+
+#: cp/call.c:2806
+msgid "call of `(%T) (%A)' is ambiguous"
+msgstr "la cridada de \"(%T) (%A)\" és ambigua"
+
+#: cp/call.c:2839
+#, c-format
+msgid "%s for ternary 'operator?:' in '%E ? %E : %E'"
+msgstr ""
+
+#: cp/call.c:2845
+#, c-format
+msgid "%s for 'operator%s' in '%E%s'"
+msgstr "%s per a \"operator%s\" en \"%E%s\""
+
+#: cp/call.c:2849
+#, c-format
+msgid "%s for 'operator[]' in '%E[%E]'"
+msgstr ""
+
+#: cp/call.c:2854
+#, fuzzy, c-format
+msgid "%s for '%s' in '%s %E'"
+msgstr "%s per a \"operador%s\" en \"%s%E\""
+
+#: cp/call.c:2859
+#, c-format
+msgid "%s for 'operator%s' in '%E %s %E'"
+msgstr ""
+
+#: cp/call.c:2862
+#, c-format
+msgid "%s for 'operator%s' in '%s%E'"
+msgstr "%s per a \"operador%s\" en \"%s%E\""
+
+#: cp/call.c:2951
+msgid "ISO C++ forbids omitting the middle term of a ?: expression"
+msgstr "ISO C++ prohibeix l'omissió del terme mig d'una expressió ?:"
+
+#: cp/call.c:3028
+#, c-format
+msgid "`%E' has type `void' and is not a throw-expression"
+msgstr "\"%E\" té tipus \"void\" i no és una expressió throw"
+
+#: cp/call.c:3061 cp/call.c:3265
+msgid "operands to ?: have different types"
+msgstr "els operants de ?: tenen tipus diferents"
+
+#: cp/call.c:3219
+msgid "enumeral mismatch in conditional expression: `%T' vs `%T'"
+msgstr "no coincideix el enumeral en l'expressió condicional: \"%T\" vs \"%T\""
+
+#: cp/call.c:3226
+msgid "enumeral and non-enumeral type in conditional expression"
+msgstr "tipus enumeral i no enumeral en l'expressió condicional"
+
+#: cp/call.c:3511
+msgid "no `%D(int)' declared for postfix `%s', trying prefix operator instead"
+msgstr "no es va declarar \"%D(int)\" per al \"%s\" postfix, intentant en el seu lloc l'operador prefix"
+
+#: cp/call.c:3560
+msgid "using synthesized `%#D' for copy assignment"
+msgstr "usant \"%#D\" sintetitzat per a assignació de còpia"
+
+#: cp/call.c:3562
+msgid " where cfront would use `%#D'"
+msgstr " on cfront podria usar \"%#D\""
+
+#: cp/call.c:3585
+msgid "comparison between `%#T' and `%#T'"
+msgstr "comparança entre \"%#T\" i \"%#T\""
+
+#: cp/call.c:3831
+#, fuzzy
+msgid "no suitable `operator %s' for `%T'"
+msgstr "no hi ha un operador \"operator delete\" adequat per a \"%T\""
+
+#: cp/call.c:3848
+msgid "`%+#D' is private"
+msgstr "\"%+#D\" és privat"
+
+#: cp/call.c:3850
+msgid "`%+#D' is protected"
+msgstr "\"%+#D\" està protegit"
+
+#: cp/call.c:3852
+msgid "`%+#D' is inaccessible"
+msgstr "\"%+#D\" és inaccessible"
+
+#: cp/call.c:3853
+msgid "within this context"
+msgstr "des d'aquest context"
+
+#: cp/call.c:3923
+msgid "invalid conversion from `%T' to `%T'"
+msgstr "conversió invàlida de \"%T\" a \"%T\""
+
+#: cp/call.c:3925
+msgid " initializing argument %P of `%D'"
+msgstr " inicialitzant l'argument %P de \"%D\""
+
+#: cp/call.c:4079
+#, fuzzy
+msgid "cannot bind bitfield `%E' to `%T'"
+msgstr "no es pot inicialitzar \"%T\" des de \"%T\""
+
+#: cp/call.c:4082
+#, fuzzy
+msgid "cannot bind packed field `%E' to `%T'"
+msgstr "no es pot declarar que el camp \"%D\" sigui de tipus \"%T\""
+
+#: cp/call.c:4085
+#, fuzzy
+msgid "cannot bind rvalue `%E' to `%T'"
+msgstr "no es pot inicialitzar \"%T\" des de \"%T\""
+
+#: cp/call.c:4173
+msgid "cannot pass objects of non-POD type `%#T' through `...'; call will abort at runtime"
+msgstr "no es pot passar objectes de tipus \"%#T\" que no és POD a través de \"...\"; la cridada avortarà en temps d'execució"
+
+#. Undefined behavior [expr.call] 5.2.2/7.
+#: cp/call.c:4197
+#, fuzzy
+msgid "cannot receive objects of non-POD type `%#T' through `...'; call will abort at runtime"
+msgstr "no es pot passar objectes de tipus \"%#T\" que no és POD a través de \"...\"; la cridada avortarà en temps d'execució"
+
+#: cp/call.c:4237
+#, fuzzy
+msgid "the default argument for parameter %d of `%D' has not yet been parsed"
+msgstr "l'argument per omissió per al paràmetre del tipus \"%T\" té el tipus \"%T\""
+
+#: cp/call.c:4432
+msgid "passing `%T' as `this' argument of `%#D' discards qualifiers"
+msgstr "passar \"%T\" com l'argument \"this\" de \"%#D\" descarta als qualificadors"
+
+#: cp/call.c:4451
+msgid "`%T' is not an accessible base of `%T'"
+msgstr "\"%T\" no és una base inaccessible de \"%T\""
+
+#: cp/call.c:4720
+msgid "could not find class$ field in java interface type `%T'"
+msgstr "no es va poder trobar un camp class$ en el tipus d'interfície java \"%T\""
+
+#: cp/call.c:4975
+msgid "call to non-function `%D'"
+msgstr "cridada a \"%D\" que no és funció"
+
+#: cp/call.c:5001
+msgid "request for member `%D' in `%E', which is of non-aggregate type `%T'"
+msgstr "sol·licitud pel membre \"%D\" en \"%E\" el qual és del tipus no agregat \"%T\""
+
+#: cp/call.c:5079
+#, fuzzy
+msgid "no matching function for call to `%T::%s(%A)%#V'"
+msgstr "no es troba una funció coincident per a la cridada a \"%T::%D(%A)%#V\""
+
+#: cp/call.c:5096
+#, fuzzy, c-format
+msgid "call of overloaded `%s(%A)' is ambiguous"
+msgstr "la cridada del \"%D(%A)\" sobrecarregat és ambigua"
+
+#: cp/call.c:5117
+msgid "cannot call member function `%D' without object"
+msgstr "no es pot cridar a la funció membre \"%D\" sense un objecte"
+
+#: cp/call.c:5702
+msgid "passing `%T' chooses `%T' over `%T'"
+msgstr "passar \"%T\" escull \"%T\" sobre \"%T\""
+
+#: cp/call.c:5704 cp/name-lookup.c:4143
+msgid " in call to `%D'"
+msgstr " en la cridada a \"%D\""
+
+#: cp/call.c:5761
+msgid "choosing `%D' over `%D'"
+msgstr "escollint \"%D\" sobre \"%D\""
+
+#: cp/call.c:5762
+msgid " for conversion from `%T' to `%T'"
+msgstr " per a la conversió de \"%T\" a \"%T\""
+
+#: cp/call.c:5764
+msgid " because conversion sequence for the argument is better"
+msgstr " perquè la seqüència de conversió per a l'argument és millor"
+
+#: cp/call.c:5884
+msgid "ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:"
+msgstr ""
+
+#: cp/call.c:5888
+msgid "candidate 1:"
+msgstr ""
+
+#: cp/call.c:5889
+msgid "candidate 2:"
+msgstr ""
+
+#: cp/call.c:5998
+msgid "could not convert `%E' to `%T'"
+msgstr "no es pot convertir \"%E\" a \"%T\""
+
+#: cp/call.c:6103
+msgid "invalid initialization of non-const reference of type '%T' from a temporary of type '%T'"
+msgstr "const_cast invàlid d'un rvalue de tipus \"%T\" al tipus \"%T\""
+
+#: cp/call.c:6107
+msgid "invalid initialization of reference of type '%T' from expression of type '%T'"
+msgstr "initialització invàlida de reference de tipus \"%T\" a partir d'una expressió de tipus \"%T\""
+
+#: cp/class.c:279
+msgid "cannot convert from base `%T' to derived type `%T' via virtual base `%T'"
+msgstr "no es pot convertir de la base \"%T\" al tipus derivat \"%T\" a través de la base virtual \"%T\""
+
+#: cp/class.c:762
+#, fuzzy
+msgid "Java class '%T' cannot have an implicit non-trivial destructor"
+msgstr "la classe base \"%#T\" té un destructor no virtual"
+
+#: cp/class.c:763
+#, fuzzy
+msgid "Java class '%T' cannot have a destructor"
+msgstr "la classe base \"%#T\" té un destructor no virtual"
+
+#: cp/class.c:931
+msgid "`%#D' and `%#D' cannot be overloaded"
+msgstr "no es poden sobrecarregar \"%#D\" i \"%#D\""
+
+#: cp/class.c:977
+msgid "conflicting access specifications for method `%D', ignored"
+msgstr "especificacions d'accés en conflicte per al mètode \"%D\", ignorat"
+
+#: cp/class.c:979
+#, c-format
+msgid "conflicting access specifications for field `%s', ignored"
+msgstr "especificacions d'accés en conflicte per al camp \"%s\", ignorat"
+
+#: cp/class.c:1029
+msgid "`%D' names constructor"
+msgstr "\"%D\" nomena al constructor"
+
+#: cp/class.c:1034
+msgid "`%D' invalid in `%T'"
+msgstr "\"%D\" invàlid en \"%#T\""
+
+#: cp/class.c:1042
+msgid "no members matching `%D' in `%#T'"
+msgstr "no hi ha membres que coincideixin amb \"%D\" en \"%#T\""
+
+#: cp/class.c:1074 cp/class.c:1082
+msgid "`%D' invalid in `%#T'"
+msgstr "\"%D\" invàlid en \"%#T\""
+
+#: cp/class.c:1075
+msgid " because of local method `%#D' with same name"
+msgstr " a causa del mètode local \"%D\" amb el mateix nom"
+
+#: cp/class.c:1083
+msgid " because of local member `%#D' with same name"
+msgstr " a causa del membre local \"%D\" amb el mateix nom"
+
+#: cp/class.c:1153
+msgid "base class `%#T' has a non-virtual destructor"
+msgstr "la classe base \"%#T\" té un destructor no virtual"
+
+#: cp/class.c:1173
+msgid "base `%T' with only non-default constructor in class without a constructor"
+msgstr "base \"%#T\" amb només un constructor que no és per omissió en una classe sense un constructor"
+
+#: cp/class.c:1557
+msgid "all member functions in class `%T' are private"
+msgstr "tots les funcions membres en la classe \"%#T\" són privades"
+
+#: cp/class.c:1568
+msgid "`%#T' only defines a private destructor and has no friends"
+msgstr "\"%#T\" solament defineix un destructor privat i no té friends"
+
+#: cp/class.c:1610
+msgid "`%#T' only defines private constructors and has no friends"
+msgstr "\"%#T\" solament defineix constructors privats i no té friends"
+
+#: cp/class.c:1995
+msgid "no unique final overrider for `%D' in `%T'"
+msgstr "no hi ha un eixafador únic final per a \"%D\" en \"%#T\""
+
+#. Here we know it is a hider, and no overrider exists.
+#: cp/class.c:2441
+msgid "`%D' was hidden"
+msgstr "\"%D\" estava amagat"
+
+#: cp/class.c:2442
+msgid " by `%D'"
+msgstr " per \"%D\""
+
+#: cp/class.c:2484 cp/decl2.c:1160
+msgid "`%#D' invalid; an anonymous union can only have non-static data members"
+msgstr "\"%D\" invàlid; un union anònim només pot tenir membres amb dades no estàtiques"
+
+#: cp/class.c:2490 cp/decl2.c:1167
+msgid "private member `%#D' in anonymous union"
+msgstr "membre privat \"%D\" en union anònima"
+
+#: cp/class.c:2493 cp/decl2.c:1169
+msgid "protected member `%#D' in anonymous union"
+msgstr "membre protegit \"%D\" en union anònima"
+
+#: cp/class.c:2612
+msgid "vtable layout for class `%T' may not be ABI-compliant and may change in a future version of GCC due to implicit virtual destructor"
+msgstr ""
+
+#: cp/class.c:2672
+msgid "bit-field `%#D' with non-integral type"
+msgstr "camp de bits \"%D\" amb tipus no enter"
+
+#: cp/class.c:2692
+msgid "bit-field `%D' width not an integer constant"
+msgstr "l'amplària del camp de bits \"%D\" no és una constant entera"
+
+#: cp/class.c:2698
+msgid "negative width in bit-field `%D'"
+msgstr "amplària negativa en el camp de bit \"%D\""
+
+#: cp/class.c:2703
+msgid "zero width for bit-field `%D'"
+msgstr "amplària zero per al camp de bits \"%D\""
+
+#: cp/class.c:2709
+msgid "width of `%D' exceeds its type"
+msgstr "l'amplària de \"%D\" excedeix el seu tipus"
+
+#: cp/class.c:2718
+msgid "`%D' is too small to hold all values of `%#T'"
+msgstr "\"%D\" és massa petit per a guardar tots els valors de \"%#T\""
+
+#: cp/class.c:2780
+msgid "member `%#D' with constructor not allowed in union"
+msgstr "no es permet el membre \"%D\" amb constructor en la union"
+
+#: cp/class.c:2783
+msgid "member `%#D' with destructor not allowed in union"
+msgstr "no es permet el membre \"%D\" amb destructor en la union"
+
+#: cp/class.c:2786
+msgid "member `%#D' with copy assignment operator not allowed in union"
+msgstr "no es permet el membre \"%D\" amb operador d'assignació de còpia en la union"
+
+#: cp/class.c:2813
+msgid "multiple fields in union `%T' initialized"
+msgstr "múltiples camps inicialitzats en la unió \"%#T\""
+
+#: cp/class.c:2879
+msgid "ignoring packed attribute on unpacked non-POD field `%#D'"
+msgstr ""
+
+#: cp/class.c:2939
+#, fuzzy
+msgid "`%D' may not be static because it is a member of a union"
+msgstr "\"%D\" deu ser una funció membre que no sigui static"
+
+#: cp/class.c:2944
+msgid "`%D' may not have reference type `%T' because it is a member of a union"
+msgstr ""
+
+#: cp/class.c:2952
+msgid "field `%D' in local class cannot be static"
+msgstr "el camp \"%D\" en la classe local no pot ser static"
+
+#: cp/class.c:2958
+msgid "field `%D' invalidly declared function type"
+msgstr "el camp \"%D\" és declarat invàlidament com un tipus de funció"
+
+#: cp/class.c:2965
+msgid "field `%D' invalidly declared method type"
+msgstr "el camp \"%D\" és declarat invàlidament com un tipus de mètode"
+
+#: cp/class.c:2998
+msgid "non-static reference `%#D' in class without a constructor"
+msgstr "referència \"%D\" que no és static en una classe sense un constructor"
+
+#: cp/class.c:3041
+msgid "non-static const member `%#D' in class without a constructor"
+msgstr "membre const \"%D\" que no és static en una classe sense un constructor"
+
+#: cp/class.c:3056
+msgid "field `%#D' with same name as class"
+msgstr "camp \"%D\" amb el mateix nom que la classe"
+
+#: cp/class.c:3074
+msgid "`%#T' has pointer data members"
+msgstr "\"%#T\" té membres punters a dades"
+
+#: cp/class.c:3078
+msgid " but does not override `%T(const %T&)'"
+msgstr " però no s'imposa a \"%T(const %T&)\""
+
+#: cp/class.c:3080
+msgid " or `operator=(const %T&)'"
+msgstr " o a \"operator=(cont %T&)\""
+
+#: cp/class.c:3083
+msgid " but does not override `operator=(const %T&)'"
+msgstr " però no s'imposa a \"operator=(const %T&)\""
+
+#: cp/class.c:3513
+msgid "offset of empty base `%T' may not be ABI-compliant and maychange in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:3623
+msgid "class `%T' will be considered nearly empty in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:3710
+msgid "initializer specified for non-virtual method `%D'"
+msgstr "es va especificar un inicialitzador per al mètode no virtual \"%D\""
+
+#: cp/class.c:4398
+msgid "offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:4488
+msgid "direct base `%T' inaccessible in `%T' due to ambiguity"
+msgstr "base directa \"%T\" inaccessible en \"%T\" a causa de ambigüitat"
+
+#: cp/class.c:4501
+msgid "virtual base `%T' inaccessible in `%T' due to ambiguity"
+msgstr "base virtual \"%T\" inaccessible en \"%T\" a causa de ambigüitat"
+
+#: cp/class.c:4675
+msgid "size assigned to `%T' may not be ABI-compliant and may change in a future version of GCC"
+msgstr ""
+
+#. Versions of G++ before G++ 3.4 did not reset the
+#. DECL_MODE.
+#: cp/class.c:4714
+msgid "the offset of `%D' may not be ABI-compliant and may change in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:4737
+msgid "offset of `%D' is not ABI-compliant and may change in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:4746
+msgid "`%D' contains empty classes which may cause base classes to be placed at different locations in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:4805
+msgid "layout of classes derived from empty class `%T' may change in a future version of GCC"
+msgstr ""
+
+#: cp/class.c:4935 cp/semantics.c:2044
+msgid "redefinition of `%#T'"
+msgstr "redefinició de \"%#T\""
+
+#: cp/class.c:5105
+msgid "`%#T' has virtual functions but non-virtual destructor"
+msgstr "\"%#T\" té funcions virtuals però destructors no virtuals"
+
+#: cp/class.c:5184
+msgid "trying to finish struct, but kicked out due to previous parse errors"
+msgstr "es va tractar d'acabar struct, però va ser tret a causa de errors previs de decodificació"
+
+#: cp/class.c:5626
+#, c-format
+msgid "language string `\"%s\"' not recognized"
+msgstr "cadena de llenguatge \"\"%s\"\" no reconeguda"
+
+#: cp/class.c:5714
+msgid "cannot resolve overloaded function `%D' based on conversion to type `%T'"
+msgstr "no es pot resoldre la funció sobrecarregada \"%D\" basant-se en la conversió al tipus \"%T\""
+
+#: cp/class.c:5839
+msgid "no matches converting function `%D' to type `%#T'"
+msgstr "no hi ha coincidències al convertir la funció \"%D\" al tipus \"%#T\""
+
+#: cp/class.c:5862
+msgid "converting overloaded function `%D' to type `%#T' is ambiguous"
+msgstr "la conversió de la funció sobrecarregada \"%D\" al tipus \"%#T\" és ambigua"
+
+#: cp/class.c:5888
+msgid "assuming pointer to member `%D'"
+msgstr "assumint el punter a membre \"%D\""
+
+#: cp/class.c:5891
+#, c-format
+msgid "(a pointer to member can only be formed with `&%E')"
+msgstr "(un punter a membre solament es pot formar amb \"&%E\")"
+
+#: cp/class.c:5936 cp/class.c:6118 cp/class.c:6125
+msgid "not enough type information"
+msgstr "no hi ha suficient informació de tipus"
+
+#: cp/class.c:5953
+msgid "argument of type `%T' does not match `%T'"
+msgstr "l'argument de tipus \"%T\" no coincideix amb \"%T\""
+
+#: cp/class.c:6102
+msgid "invalid operation on uninstantiated type"
+msgstr "operació invàlida en tipus no instanciat"
+
+#. [basic.scope.class]
+#.
+#. A name N used in a class S shall refer to the same declaration
+#. in its context and when re-evaluated in the completed scope of
+#. S.
+#: cp/class.c:6360 cp/decl.c:1222 cp/name-lookup.c:502 cp/pt.c:2097
+msgid "declaration of `%#D'"
+msgstr "la declaració de \"%#D\""
+
+#: cp/class.c:6361
+msgid "changes meaning of `%D' from `%+#D'"
+msgstr "canvia el significat de \"%D\" a partir de \"%+#D\""
+
+#: cp/cp-lang.c:398
+#, fuzzy
+msgid "inter-module optimisations not implemented yet"
+msgstr "no s'ha implementat encara profiling"
+
+#: cp/cvt.c:88
+msgid "can't convert from incomplete type `%T' to `%T'"
+msgstr "no es pot convertir des del tipus de dada incompleta \"%T\" a \"%T\""
+
+#: cp/cvt.c:97
+msgid "conversion of `%E' from `%T' to `%T' is ambiguous"
+msgstr "la conversió de \"%E\" des de \"%T\" a \"%T\" és ambigua"
+
+#: cp/cvt.c:113 cp/cvt.c:127
+msgid "converting from `%T' to `%T'"
+msgstr "convertint de \"%T\" a \"%T\""
+
+#: cp/cvt.c:185 cp/cvt.c:253 cp/cvt.c:297
+msgid "cannot convert `%E' from type `%T' to type `%T'"
+msgstr "no es pot convertir \"%E\" des del tipus \"%T\" al tipus \"%T\""
+
+#: cp/cvt.c:214 cp/cvt.c:218
+msgid "pointer to member cast from `%T' to `%T' is via virtual base"
+msgstr "el punter a la conversió de membre de \"%T\" a \"%T\" és a través d'una base virtual"
+
+#: cp/cvt.c:276
+msgid "invalid conversion from '%T' to '%T'"
+msgstr "conversió invàlida de \"%T\" a \"%T\""
+
+#: cp/cvt.c:508
+msgid "conversion from `%T' to `%T' discards qualifiers"
+msgstr "la conversió de \"%T\" a \"%T\" descarta els qualificadors"
+
+#: cp/cvt.c:526
+msgid "casting `%T' to `%T' does not dereference pointer"
+msgstr "la conversió de \"%T\" a \"%T\" no dereferencia els punters"
+
+#: cp/cvt.c:553
+msgid "cannot convert type `%T' to type `%T'"
+msgstr "no es pot convertir del tipus \"%T\" al tipus \"%T\""
+
+#: cp/cvt.c:679
+msgid "conversion from `%#T' to `%#T'"
+msgstr "conversió de \"%#T\" a \"%#T\""
+
+#: cp/cvt.c:691
+msgid "`%#T' used where a `%T' was expected"
+msgstr "es va usar un \"%#T\" on s'esperava un \"%T\""
+
+#: cp/cvt.c:715
+msgid "`%#T' used where a floating point value was expected"
+msgstr "es va usar un \"%#T\" on s'esperava un valor de coma flotant"
+
+#: cp/cvt.c:762
+msgid "conversion from `%T' to non-scalar type `%T' requested"
+msgstr "es va sol·licitar la conversió des de \"%T\" al tipus no escalar \"%T\""
+
+#: cp/cvt.c:850
+msgid "object of incomplete type `%T' will not be accessed in %s"
+msgstr "l'objecte de tipus incomplet \"%T\" no es accesará en %s"
+
+#: cp/cvt.c:853
+msgid "object of type `%T' will not be accessed in %s"
+msgstr "l'objecte de tipus \"%T\" no es accesará en %s"
+
+#: cp/cvt.c:869
+msgid "object `%E' of incomplete type `%T' will not be accessed in %s"
+msgstr "l'objecte \"%E\" de tipus incomplet \"%T\" no es accesará en %s"
+
+#. [over.over] enumerates the places where we can take the address
+#. of an overloaded function, and this is not one of them.
+#: cp/cvt.c:885
+#, c-format
+msgid "%s cannot resolve address of overloaded function"
+msgstr "%s no es pot resoldre l'adreça de la funció sobrecarregada"
+
+#. Only warn when there is no &.
+#: cp/cvt.c:891
+#, c-format
+msgid "%s is a reference, not call, to function `%E'"
+msgstr "%s és una referència, no una cridada, a la funció \"%E\""
+
+#: cp/cvt.c:898
+#, fuzzy, c-format
+msgid "%s has no effect"
+msgstr "%s no té %s"
+
+#: cp/cvt.c:1009
+msgid "converting NULL to non-pointer type"
+msgstr "convertint NULL a un tipus que no és apuntador"
+
+#: cp/cvt.c:1082
+msgid "ambiguous default type conversion from `%T'"
+msgstr "conversió de tipus per omissió ambigua des de \"%T\""
+
+#: cp/cvt.c:1084
+msgid " candidate conversions include `%D' and `%D'"
+msgstr " les conversions candidates inclouen \"%D\" i \"%D\""
+
+#: cp/decl.c:371
+msgid "label `%D' used but not defined"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: cp/decl.c:378
+msgid "label `%D' defined but not used"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: cp/decl.c:1130 cp/decl.c:1556
+msgid "previous declaration of `%D'"
+msgstr "declaració prèvia de \"%D\""
+
+#: cp/decl.c:1178
+#, fuzzy
+msgid "%Jfunction '%D' redeclared as inline"
+msgstr "funció \"%s\" re declarada com inline"
+
+#: cp/decl.c:1179
+#, fuzzy
+msgid "%Jprevious declaration of '%D' with attribute noinline"
+msgstr "declaració prèvia de la funció \"%s\" amb l'atribut noinline"
+
+#: cp/decl.c:1186
+#, fuzzy
+msgid "%Jfunction '%D' redeclared with attribute noinline"
+msgstr "funció \"%s\" re-declarada amb l'atribut noinline"
+
+#: cp/decl.c:1188
+#, fuzzy
+msgid "%Jprevious declaration of '%D' was inline"
+msgstr "la declaració prèvia de la funció \"%s\" va ser inline"
+
+#: cp/decl.c:1209 cp/decl.c:1247
+msgid "shadowing %s function `%#D'"
+msgstr "enfosquint la funció de biblioteca \"%#D\""
+
+#: cp/decl.c:1218
+msgid "library function `%#D' redeclared as non-function `%#D'"
+msgstr "la funció de biblioteca \"%#D\" és redeclarada com \"%#D\" que no és funció"
+
+#: cp/decl.c:1223
+msgid "conflicts with built-in declaration `%#D'"
+msgstr "causa conflicte amb la declaració interna \"%#D\""
+
+#: cp/decl.c:1242 cp/decl.c:1354 cp/decl.c:1370
+msgid "new declaration `%#D'"
+msgstr "declaració nova \"%#D\""
+
+#: cp/decl.c:1243
+msgid "ambiguates built-in declaration `%#D'"
+msgstr "fa ambigua la declaració interna \"%#D\""
+
+#: cp/decl.c:1314
+msgid "`%#D' redeclared as different kind of symbol"
+msgstr "\"%#D\" redeclarat com un tipus diferent de símbol"
+
+#: cp/decl.c:1317
+msgid "previous declaration of `%#D'"
+msgstr "declaració prèvia de \"%#D\""
+
+#: cp/decl.c:1339
+msgid "declaration of template `%#D'"
+msgstr "declaració del patró \"%#D\""
+
+#: cp/decl.c:1340 cp/name-lookup.c:503
+msgid "conflicts with previous declaration `%#D'"
+msgstr "causa conflictes amb la declaració prèvia \"%#D\""
+
+#: cp/decl.c:1355 cp/decl.c:1371
+msgid "ambiguates old declaration `%#D'"
+msgstr "fa ambigua la declaració antiga \"%#D\""
+
+#: cp/decl.c:1363
+msgid "declaration of C function `%#D' conflicts with"
+msgstr "la declaració de la funció C \"%#D\" té conflictes amb"
+
+#: cp/decl.c:1365
+msgid "previous declaration `%#D' here"
+msgstr "declaració prèvia de \"%#D\" aquí"
+
+#: cp/decl.c:1381
+#, fuzzy
+msgid "conflicting declaration '%#D'"
+msgstr "declaracions de \"%s\" en conflicte"
+
+#: cp/decl.c:1382
+#, fuzzy
+msgid "'%D' has a previous declaration as `%#D'"
+msgstr "declaració prèvia com \"%#D\""
+
+#: cp/decl.c:1435
+msgid "`%#D' previously defined here"
+msgstr "es va definir \"%#D\" prèviament aquí"
+
+#: cp/decl.c:1436
+msgid "`%#D' previously declared here"
+msgstr "es va declarar \"%#D\" prèviament aquí"
+
+#. Prototype decl follows defn w/o prototype.
+#: cp/decl.c:1445
+msgid "prototype for `%#D'"
+msgstr "el prototip per a \"%#D\""
+
+#: cp/decl.c:1446
+#, fuzzy
+msgid "%Jfollows non-prototype definition here"
+msgstr "a continuació la definició del no prototip aquí"
+
+#: cp/decl.c:1458
+msgid "previous declaration of `%#D' with %L linkage"
+msgstr "declaració prèvia de \"%#D\" amb l'enllaç %L"
+
+#: cp/decl.c:1460
+msgid "conflicts with new declaration with %L linkage"
+msgstr "té conflictes amb la declaració nova amb l'enllaç %L"
+
+#: cp/decl.c:1483 cp/decl.c:1490
+msgid "default argument given for parameter %d of `%#D'"
+msgstr "argument per omissió donat per al paràmetre %d de \"%#D\""
+
+#: cp/decl.c:1485 cp/decl.c:1492
+msgid "after previous specification in `%#D'"
+msgstr "després de l'especificació prèvia en \"%#D\""
+
+#: cp/decl.c:1501
+msgid "`%#D' was used before it was declared inline"
+msgstr "es va usar \"%#D\" abans que fora declarat inline"
+
+#: cp/decl.c:1502
+#, fuzzy
+msgid "%Jprevious non-inline declaration here"
+msgstr "declaració prèvia no inline aquí"
+
+#: cp/decl.c:1555
+msgid "redundant redeclaration of `%D' in same scope"
+msgstr "declaració redundant de \"%D\" en el mateix àmbit"
+
+#: cp/decl.c:1649
+#, c-format
+msgid "declaration of `%F' throws different exceptions"
+msgstr "la declaració de \"%F\" llança excepcions diferents"
+
+#: cp/decl.c:1651
+#, c-format
+msgid "than previous declaration `%F'"
+msgstr "que la declaració prèvia \"%F\""
+
+#. From [temp.expl.spec]:
+#.
+#. If a template, a member template or the member of a class
+#. template is explicitly specialized then that
+#. specialization shall be declared before the first use of
+#. that specialization that would cause an implicit
+#. instantiation to take place, in every translation unit in
+#. which such a use occurs.
+#: cp/decl.c:1798
+msgid "explicit specialization of %D after first use"
+msgstr "especialització explícita de %D després del primer ús"
+
+#: cp/decl.c:1878
+msgid "%J'%D': visibility attribute ignored because it"
+msgstr ""
+
+#: cp/decl.c:1880
+#, fuzzy
+msgid "%Jconflicts with previous declaration here"
+msgstr "causa conflictes amb la declaració prèvia \"%#D\""
+
+#: cp/decl.c:1974
+msgid "implicit declaration of function `%#D'"
+msgstr "declaració implícita de la funció \"%#D\""
+
+#: cp/decl.c:2137
+#, c-format
+msgid "label `%s' referenced outside of any function"
+msgstr "l'etiqueta \"%s\" es va referenciar fora de qualsevol funció"
+
+#: cp/decl.c:2234 cp/decl.c:2258 cp/decl.c:2346
+msgid "jump to label `%D'"
+msgstr "salt a l'etiqueta \"%D\""
+
+#: cp/decl.c:2236 cp/decl.c:2260
+msgid "jump to case label"
+msgstr "salt a l'etiqueta case"
+
+#: cp/decl.c:2239 cp/decl.c:2263
+#, fuzzy
+msgid "%H from here"
+msgstr " des d'aquí"
+
+#: cp/decl.c:2244
+msgid " crosses initialization of `%#D'"
+msgstr " creua la inicialització de \"%#D\""
+
+#: cp/decl.c:2247 cp/decl.c:2362
+msgid " enters scope of non-POD `%#D'"
+msgstr " entra en l'àmbit de \"%#D\" que no és POD"
+
+#: cp/decl.c:2267 cp/decl.c:2366
+msgid " enters try block"
+msgstr " entra intent de bloc"
+
+#: cp/decl.c:2269 cp/decl.c:2368
+msgid " enters catch block"
+msgstr " entra captura de bloc"
+
+#: cp/decl.c:2347
+msgid " from here"
+msgstr " des d'aquí"
+
+#. Can't skip init of __exception_info.
+#: cp/decl.c:2358
+#, fuzzy
+msgid "%J enters catch block"
+msgstr " entra captura de bloc"
+
+#: cp/decl.c:2360
+msgid " skips initialization of `%#D'"
+msgstr " salta la inicialización de \"%#D\""
+
+#: cp/decl.c:2394
+msgid "label named wchar_t"
+msgstr "etiqueta nomenada wchar_t"
+
+#: cp/decl.c:2397
+msgid "duplicate label `%D'"
+msgstr "etiqueta duplicada \"%D\""
+
+#: cp/decl.c:2625 cp/parser.c:3182
+msgid "`%D' used without template parameters"
+msgstr "s'usa \"%D\" sense paràmetres de patró"
+
+#: cp/decl.c:2635 cp/decl.c:2651 cp/decl.c:2739
+msgid "no class template named `%#T' in `%#T'"
+msgstr "no hi ha una patró de classe cridada \"%#T\" en \"%#T\""
+
+#: cp/decl.c:2672 cp/decl.c:2682 cp/decl.c:2702
+msgid "no type named `%#T' in `%#T'"
+msgstr "no hi ha un tipus cridat \"%#T\" en \"%#T\""
+
+#: cp/decl.c:3429
+#, fuzzy
+msgid "%Jan anonymous union cannot have function members"
+msgstr "un union anònim no pot tenir funcions membre"
+
+#: cp/decl.c:3447
+msgid "member %#D' with constructor not allowed in anonymous aggregate"
+msgstr "no es permet el membre \"%#D\" amb constructor en un agregat anònim"
+
+#: cp/decl.c:3450
+msgid "member %#D' with destructor not allowed in anonymous aggregate"
+msgstr "no es permet el membre \"%#D\" amb destructor en un agregat anònim"
+
+#: cp/decl.c:3453
+msgid "member %#D' with copy assignment operator not allowed in anonymous aggregate"
+msgstr "no es permet el membre \"%#D\" amb operador d'assignació de còpia en un agregat anònim"
+
+#: cp/decl.c:3493
+msgid "redeclaration of C++ built-in type `%T'"
+msgstr "redeclaración del tipus intern de C++ \"%T\""
+
+#: cp/decl.c:3531
+msgid "multiple types in one declaration"
+msgstr "tipus múltiples en una declaració"
+
+#: cp/decl.c:3557
+msgid "missing type-name in typedef-declaration"
+msgstr "falta el nom del tipus en la declaració typedef"
+
+#: cp/decl.c:3565
+msgid "ISO C++ prohibits anonymous structs"
+msgstr "ISO C++ prohibeix structs anònims"
+
+#: cp/decl.c:3572
+msgid "`%D' can only be specified for functions"
+msgstr "\"%D\" només pot ser especificat per a funcions"
+
+#: cp/decl.c:3574
+msgid "`%D' can only be specified inside a class"
+msgstr "\"%D\" només pot ser especificat dintre d'una classe"
+
+#: cp/decl.c:3576
+msgid "`%D' can only be specified for constructors"
+msgstr "\"%D\" només pot ser especificat per a constructors"
+
+#: cp/decl.c:3579
+msgid "`%D' can only be specified for objects and functions"
+msgstr "\"%D\" només pot ser especificat per a objectes i funcions"
+
+#: cp/decl.c:3721 cp/decl2.c:854
+msgid "typedef `%D' is initialized (use __typeof__ instead)"
+msgstr "typedef \"%D\" està inicialitzat (utilitzi __typeof__ en el seu lloc)"
+
+#: cp/decl.c:3726
+msgid "function `%#D' is initialized like a variable"
+msgstr "la funció \"%#D\" està inicialitzada com una variable"
+
+#: cp/decl.c:3738
+msgid "declaration of `%#D' has `extern' and is initialized"
+msgstr "la declaració de \"%#D\" té \"extern\" i està inicialitzada"
+
+#: cp/decl.c:3771
+msgid "`%#D' is not a static member of `%#T'"
+msgstr "\"%#D\" no és un membre static de \"%#T\""
+
+#: cp/decl.c:3777
+msgid "ISO C++ does not permit `%T::%D' to be defined as `%T::%D'"
+msgstr "ISO C++ no permet que \"%T::%D\" es defineixi com \"%T::%D\""
+
+#: cp/decl.c:3788
+msgid "duplicate initialization of %D"
+msgstr "inicialització duplicada de %D"
+
+#: cp/decl.c:3819
+msgid "declaration of `%#D' outside of class is not definition"
+msgstr "la declaració de \"%#D\" fora de la classe no és una definició"
+
+#: cp/decl.c:3868
+msgid "variable `%#D' has initializer but incomplete type"
+msgstr "la variable \"%#D\" té inicializador però de tipus de dada incompleta"
+
+#: cp/decl.c:3876 cp/decl.c:4445
+msgid "elements of array `%#D' have incomplete type"
+msgstr "alguns elements de la matriu \"%#D\" tenen tipus de dada incompleta"
+
+#: cp/decl.c:3892
+msgid "aggregate `%#D' has incomplete type and cannot be defined"
+msgstr "l'agregat \"%#D\" té un tipus incomplet i no es pot definir"
+
+#: cp/decl.c:3942
+msgid "`%D' declared as reference but not initialized"
+msgstr "\"%D\" declarat com referència però no està inicialitzat"
+
+#: cp/decl.c:3948
+msgid "ISO C++ forbids use of initializer list to initialize reference `%D'"
+msgstr "ISO C++ prohibeix l'ús d'una llista de inicialitzadors per a inicialitzar la referència \"%D\""
+
+#: cp/decl.c:3976
+msgid "cannot initialize `%T' from `%T'"
+msgstr "no es pot inicialitzar \"%T\" des de \"%T\""
+
+#: cp/decl.c:4008
+msgid "initializer fails to determine size of `%D'"
+msgstr "el inicializador no pot determinar la grandària de \"%D\""
+
+#: cp/decl.c:4013
+msgid "array size missing in `%D'"
+msgstr "falta la grandària de la matriu en \"%D\""
+
+#: cp/decl.c:4025
+msgid "zero-size array `%D'"
+msgstr "matriu \"%D\" de grandària zero"
+
+#. An automatic variable with an incomplete type: that is an error.
+#. Don't talk about array types here, since we took care of that
+#. message in grokdeclarator.
+#: cp/decl.c:4062
+msgid "storage size of `%D' isn't known"
+msgstr "no es coneix la grandària d'emmagatzematge de \"%D\""
+
+#: cp/decl.c:4084
+msgid "storage size of `%D' isn't constant"
+msgstr "la grandària d'emmagatzematge de \"%D\" no és constant"
+
+#: cp/decl.c:4139
+msgid "sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)"
+msgstr "perdó: la semàntica de les dades static de la funció inline \"%#D\" és errònia (acabarà amb múltiples còpies)"
+
+#: cp/decl.c:4140
+#, fuzzy
+msgid "%J you can work around this by removing the initializer"
+msgstr " pot evitar això eliminant el inicializador"
+
+#: cp/decl.c:4166
+msgid "uninitialized const `%D'"
+msgstr "const \"%D\" sense inicialitzar"
+
+#: cp/decl.c:4245
+msgid "brace-enclosed initializer used to initialize `%T'"
+msgstr "es va utilitzar un inicialitzador entre parèntesis per a inicialitzar \"%T\""
+
+#: cp/decl.c:4309
+msgid "initializer for `%T' must be brace-enclosed"
+msgstr "el inicialitzador per a \"%T\" deu estar tancat entre parèntesis"
+
+#: cp/decl.c:4326
+msgid "ISO C++ does not allow designated initializers"
+msgstr "ISO C++ no permet inicialitzadors designats"
+
+#: cp/decl.c:4330
+msgid "`%T' has no non-static data member named `%D'"
+msgstr "\"%T\" té una dada membre que no és non-static cridada \"%D\""
+
+#: cp/decl.c:4378
+msgid "name `%D' used in a GNU-style designated initializer for an array"
+msgstr ""
+
+#: cp/decl.c:4401
+msgid "too many initializers for `%T'"
+msgstr "massa inicialitzadors per a \"%T\""
+
+#: cp/decl.c:4439
+msgid "variable-sized object `%D' may not be initialized"
+msgstr "l'objecte de grandària variable \"%D\" no pot ser inicialitzat"
+
+#: cp/decl.c:4450
+msgid "`%D' has incomplete type"
+msgstr "\"%D\" té un tipus de dada incompleta"
+
+#: cp/decl.c:4505
+msgid "`%D' must be initialized by constructor, not by `{...}'"
+msgstr "\"%D\" deu ser inicialitzat per un constructor, no per \"{...}\""
+
+#: cp/decl.c:4549
+msgid "structure `%D' with uninitialized const members"
+msgstr "estructura \"%D\" amb membres const sense inicialitzar"
+
+#: cp/decl.c:4551
+msgid "structure `%D' with uninitialized reference members"
+msgstr "estructura \"%D\" amb membres de referència sense inicialitzar"
+
+#: cp/decl.c:4732
+msgid "assignment (not initialization) in declaration"
+msgstr "assignació (no inicialització) en la declaració"
+
+#: cp/decl.c:4749
+msgid "cannot initialize `%D' to namespace `%D'"
+msgstr "no es poden inicialitzar \"%D\" per a l'espai de noms \"%D\""
+
+#: cp/decl.c:4803
+msgid "shadowing previous type declaration of `%#D'"
+msgstr "enfosquint la declaració de tipus prèvia de \"%#D\""
+
+#: cp/decl.c:4840
+msgid "`%D' cannot be thread-local because it has non-POD type `%T'"
+msgstr "\"%D\" no pot ser thread-local perquè és de tipus \"%T\" que no és POD"
+
+#: cp/decl.c:4855
+msgid "`%D' is thread-local and so cannot be dynamically initialized"
+msgstr "\"%D\" és thread-local i per tant no es pot inicialitzar dinàmicament"
+
+#: cp/decl.c:5337
+msgid "invalid catch parameter"
+msgstr "paràmetre de captura invàlid"
+
+#: cp/decl.c:5451
+msgid "destructor for alien class `%T' cannot be a member"
+msgstr "el destructor per a la classe estrangera \"%T\" no pot ser un membre"
+
+#: cp/decl.c:5454
+msgid "constructor for alien class `%T' cannot be a member"
+msgstr "el constructor per a la classe estrangera \"%T\" no pot ser un membre"
+
+#: cp/decl.c:5476
+msgid "`%D' declared as a `virtual' %s"
+msgstr "\"%D\" va ser declarat com un %s \"virtual\""
+
+#: cp/decl.c:5478
+msgid "`%D' declared as an `inline' %s"
+msgstr "\"%D\" va ser declarat com un %s \"inline\""
+
+#: cp/decl.c:5480
+msgid "`const' and `volatile' function specifiers on `%D' invalid in %s declaration"
+msgstr "especificadors de funció \"const\" i \"volatile\" en \"%D\" invàlids en la declaració %s"
+
+#: cp/decl.c:5483
+msgid "`%D' declared as a friend"
+msgstr "\"%D\" declarat com un friend"
+
+#: cp/decl.c:5489
+msgid "`%D' declared with an exception specification"
+msgstr "\"%D\" declarat amb una excepció d'especificació"
+
+#: cp/decl.c:5571
+msgid "cannot declare `::main' to be a template"
+msgstr "no es pot declarar \"::main\" com template"
+
+#: cp/decl.c:5573
+msgid "cannot declare `::main' to be inline"
+msgstr "no es pot declarar \"::main\" com inline"
+
+#: cp/decl.c:5575
+msgid "cannot declare `::main' to be static"
+msgstr "no es pot declarar \"::main\" com static"
+
+#: cp/decl.c:5578
+msgid "`main' must return `int'"
+msgstr "\"main\" deu retornar \"int\""
+
+#: cp/decl.c:5606
+msgid "non-local function `%#D' uses anonymous type"
+msgstr "la funció \"%#D\" que no és local usa un tipus anònim"
+
+#: cp/decl.c:5609
+msgid "`%#D' does not refer to the unqualified type, so it is not used for linkage"
+msgstr "\"%#D\" no es refereix al tipus sense qualificar, així que no s'usa per a l'enllaçat"
+
+#: cp/decl.c:5615
+msgid "non-local function `%#D' uses local type `%T'"
+msgstr "la funció \"%#D\" que no és local utilitza el tipus local \"%T\""
+
+#: cp/decl.c:5639
+msgid "%smember function `%D' cannot have `%T' method qualifier"
+msgstr "%sfunció membre \"%D\" no pot tenir el qualificador de mètode \"%T\""
+
+#: cp/decl.c:5663
+msgid "defining explicit specialization `%D' in friend declaration"
+msgstr "definint l'especialització explícita \"%D\" en la declaració friend"
+
+#. Something like `template <class T> friend void f<T>()'.
+#: cp/decl.c:5673
+msgid "invalid use of template-id `%D' in declaration of primary template"
+msgstr "ús invàlid de l'aneu de patró \"%D\" en la declaració del patró primàri"
+
+#: cp/decl.c:5700
+msgid "default arguments are not allowed in declaration of friend template specialization `%D'"
+msgstr "no es permeten els argument per omissió en la declaració de l'especialització friend del patró \"%D\""
+
+#: cp/decl.c:5707
+msgid "`inline' is not allowed in declaration of friend template specialization `%D'"
+msgstr "no es permet \"inline\" en la declaració de l'especialització friend del patró \"%D\""
+
+#: cp/decl.c:5765
+msgid "definition of implicitly-declared `%D'"
+msgstr "la definició de \"%D\" declarat implícitament"
+
+#: cp/decl.c:5785 cp/decl2.c:737
+msgid "no `%#D' member function declared in class `%T'"
+msgstr "no hi ha una funció membre \"%#D\" declarada en la classe \"%T\""
+
+#: cp/decl.c:5919
+msgid "non-local variable `%#D' uses local type `%T'"
+msgstr ""
+
+#: cp/decl.c:6034
+msgid "invalid in-class initialization of static data member of non-integral type `%T'"
+msgstr ""
+
+#: cp/decl.c:6043
+msgid "ISO C++ forbids in-class initialization of non-const static member `%D'"
+msgstr "ISO C++ prohibeix la inicialización en la classe del membre static \"%D\" que no és constant"
+
+#: cp/decl.c:6046
+msgid "ISO C++ forbids initialization of member constant `%D' of non-integral type `%T'"
+msgstr "ISO C++ prohibeix la inicialització del membre constant \"%D\" del tipus \"%T\" que no és enter"
+
+#: cp/decl.c:6065
+#, fuzzy
+msgid "size of array `%D' has non-integral type `%T'"
+msgstr "la grandària de la matriu \"%D\" té un tipus no enter"
+
+#: cp/decl.c:6067
+#, fuzzy
+msgid "size of array has non-integral type `%T'"
+msgstr "la grandària de la matriu té un tipus no enter"
+
+#: cp/decl.c:6103
+msgid "size of array `%D' is negative"
+msgstr "la grandària de la matriu \"%D\" és negatiu"
+
+#: cp/decl.c:6105
+msgid "size of array is negative"
+msgstr "la grandària de la matriu és negatiu"
+
+#: cp/decl.c:6113
+msgid "ISO C++ forbids zero-size array `%D'"
+msgstr "ISO C++ prohibeix la matriu \"%D\" de grandària zero"
+
+#: cp/decl.c:6115
+msgid "ISO C++ forbids zero-size array"
+msgstr "ISO C++ prohibeix la matriu de grandària zero"
+
+#: cp/decl.c:6122
+msgid "size of array `%D' is not an integral constant-expression"
+msgstr "la grandària de la matriu \"%D\" no és una expressió constant integral"
+
+#: cp/decl.c:6125
+msgid "size of array is not an integral constant-expression"
+msgstr "la grandària de la matriu no és una expressió constant integral"
+
+#: cp/decl.c:6130
+msgid "ISO C++ forbids variable-size array `%D'"
+msgstr "ISO C++ prohibeix la matriu \"%D\" de grandària variable"
+
+#: cp/decl.c:6132
+msgid "ISO C++ forbids variable-size array"
+msgstr "ISO C++ prohibeix la matriu de grandària variable"
+
+#: cp/decl.c:6154
+msgid "overflow in array dimension"
+msgstr "desbordament en la dimensió de la matriu"
+
+#: cp/decl.c:6248
+msgid "declaration of `%D' as %s"
+msgstr "declaración de \"%D\" com %s"
+
+#: cp/decl.c:6250
+#, c-format
+msgid "creating %s"
+msgstr "creant %s"
+
+#: cp/decl.c:6262
+msgid "declaration of `%D' as multidimensional array must have bounds for all dimensions except the first"
+msgstr "la declaració de \"%D\" com una matriu multidimensional deu tenir límits per a totes les dimensions excepte la primera"
+
+#: cp/decl.c:6265
+msgid "multidimensional array must have bounds for all dimensions except the first"
+msgstr "una matriu multidimensional deu tenir límits per a totes les dimensions excepte per a la primera"
+
+#: cp/decl.c:6293
+msgid "return type specification for constructor invalid"
+msgstr "l'especificació del tipus de retorn per al constructor és invàlid"
+
+#: cp/decl.c:6300
+msgid "return type specification for destructor invalid"
+msgstr "l'especificació del tipus de retorn per al destructor és invàlid"
+
+#: cp/decl.c:6306
+msgid "operator `%T' declared to return `%T'"
+msgstr "l'operador \"%T\" es va declarar per a retornar \"%T\""
+
+#: cp/decl.c:6308
+msgid "return type specified for `operator %T'"
+msgstr "es va especificar un tipus de retorn per a \"operator %T\""
+
+#: cp/decl.c:6452
+msgid "destructors must be member functions"
+msgstr "els destructors deuen ser funcions membre"
+
+#: cp/decl.c:6471
+msgid "destructor `%T' must match class name `%T'"
+msgstr "el destructor \"%T\" deu coincidir amb el nom de la classe \"%T\""
+
+#: cp/decl.c:6534
+msgid "declarator-id missing; using reserved word `%D'"
+msgstr "falta l'identificador del declarador; utilitzant la paraula reservada \"%D\""
+
+#: cp/decl.c:6588
+msgid "type `%T' is not derived from type `%T'"
+msgstr "el tipus \"%T\" no és derivat del tipus \"%T\""
+
+#. Parse error puts this typespec where
+#. a declarator should go.
+#: cp/decl.c:6651
+msgid "`%T' specified as declarator-id"
+msgstr "\"%T\" especificat com identificador de declarador"
+
+#: cp/decl.c:6653
+msgid " perhaps you want `%T' for a constructor"
+msgstr " potser vol \"%T\" per a un constructor"
+
+#. Sometimes, we see a template-name used as part of a
+#. decl-specifier like in
+#. std::allocator alloc;
+#. Handle that gracefully.
+#: cp/decl.c:6675
+#, c-format
+msgid "invalid use of template-name '%E' in a declarator"
+msgstr "ús invàlid del nom de patró \"%E\" en un declarador"
+
+#: cp/decl.c:6695
+msgid "declaration of `%D' as non-function"
+msgstr "la declaració de \"%D\" com una no funció"
+
+#: cp/decl.c:6772
+msgid "`bool' is now a keyword"
+msgstr "`bool' ara és una paraula clau"
+
+#: cp/decl.c:6774
+msgid "extraneous `%T' ignored"
+msgstr "\"%T\" extra ignorat"
+
+#: cp/decl.c:6790 cp/decl.c:6834
+msgid "multiple declarations `%T' and `%T'"
+msgstr "declaracions múltiples \"%T\" i \"%T\""
+
+#: cp/decl.c:6803
+msgid "ISO C++ does not support `long long'"
+msgstr "ISO C++ no dóna suport a \"long long\""
+
+#: cp/decl.c:6907 cp/decl.c:6910
+#, c-format
+msgid "ISO C++ forbids declaration of `%s' with no type"
+msgstr "ISO C++ prohibeix la declaració de \"%s\" sense tipus"
+
+#: cp/decl.c:6941
+#, c-format
+msgid "short, signed or unsigned invalid for `%s'"
+msgstr "short, signed o unsigned invàlid per a \"%s\""
+
+#: cp/decl.c:6946
+#, c-format
+msgid "long and short specified together for `%s'"
+msgstr "long i short especificats junts per a \"%s\""
+
+#: cp/decl.c:6957
+#, c-format
+msgid "signed and unsigned given together for `%s'"
+msgstr "es van donar junts signed i unsigned per a \"%s\""
+
+#: cp/decl.c:7066
+msgid "qualifiers are not allowed on declaration of `operator %T'"
+msgstr "no es permeten qualificadors en la declaració de \"operator %T\""
+
+#: cp/decl.c:7088
+msgid "member `%D' cannot be declared both virtual and static"
+msgstr ""
+
+#: cp/decl.c:7097
+msgid "`%T::%D' is not a valid declarator"
+msgstr "\"%T::%D\" no és una declaració vàlida"
+
+#: cp/decl.c:7109
+msgid "storage class specifiers invalid in parameter declarations"
+msgstr "especificadors de classe d'emmagatzematge invàlids en les declaracions de paràmetres"
+
+#: cp/decl.c:7113
+msgid "typedef declaration invalid in parameter declaration"
+msgstr "declaració typedef invàlida en la declaració de paràmetres"
+
+#: cp/decl.c:7126
+msgid "virtual outside class declaration"
+msgstr "declaració de virtual fora de class"
+
+#: cp/decl.c:7185
+#, c-format
+msgid "storage class specified for %s `%s'"
+msgstr "classe d'emmagatzematge especificada per %s \"%s\""
+
+#: cp/decl.c:7220
+#, c-format
+msgid "top-level declaration of `%s' specifies `auto'"
+msgstr "la declaració del nivell superior de \"%s\" especifica \"auto\""
+
+#: cp/decl.c:7232
+msgid "storage class specifiers invalid in friend function declarations"
+msgstr "especificadors de classe d'emmagatzematge invàlids en les declaracions de funcions friend"
+
+#: cp/decl.c:7397
+msgid "destructor cannot be static member function"
+msgstr "el destructor no pot ser una funció membre de tipus static"
+
+#: cp/decl.c:7400
+#, c-format
+msgid "destructors may not be `%s'"
+msgstr "els destructors no poden ser \"%s\""
+
+#: cp/decl.c:7421
+msgid "constructor cannot be static member function"
+msgstr "el constructor no pot ser una funció membre de tipus static"
+
+#: cp/decl.c:7424
+msgid "constructors cannot be declared virtual"
+msgstr "els constructors no poden ser declarats virtual"
+
+#: cp/decl.c:7429
+#, c-format
+msgid "constructors may not be `%s'"
+msgstr "els constructors no poden ser \"%s\""
+
+#: cp/decl.c:7439
+msgid "return value type specifier for constructor ignored"
+msgstr "el especificador de tipus del valor retornat per al constructor és ignorat"
+
+#: cp/decl.c:7458
+#, c-format
+msgid "can't initialize friend function `%s'"
+msgstr "no es pot inicialitzar la funció friend \"%s\""
+
+#. Cannot be both friend and virtual.
+#: cp/decl.c:7462
+msgid "virtual functions cannot be friends"
+msgstr "les funcions virtual no poden ser friend"
+
+#: cp/decl.c:7467
+msgid "friend declaration not in class definition"
+msgstr "la declaració friend no està en una definició de classe"
+
+#: cp/decl.c:7469
+#, c-format
+msgid "can't define friend function `%s' in a local class definition"
+msgstr "no es pot definir la funció friend \"%s\" en una definició de classe local"
+
+#: cp/decl.c:7490
+msgid "destructors may not have parameters"
+msgstr "els destructors no poden tenir paràmetres"
+
+#: cp/decl.c:7510 cp/decl.c:7517
+msgid "cannot declare reference to `%#T'"
+msgstr "no es poden declarar referències a \"%#T\""
+
+#: cp/decl.c:7511
+msgid "cannot declare pointer to `%#T'"
+msgstr "no es pot declarar un punter a \"%#T\""
+
+#: cp/decl.c:7516
+msgid "cannot declare pointer to `%#T' member"
+msgstr "no es pot declarar un punter al membre \"%#T\""
+
+#: cp/decl.c:7654
+msgid "extra qualification `%T::' on member `%s' ignored"
+msgstr "s'ignora la qualificació extra `%T::' en el membre \"%s\""
+
+#: cp/decl.c:7670
+msgid "cannot declare member function `%T::%s' within `%T'"
+msgstr "no es pot declarar la funció membre \"%T::%s\" dintre de \"%T\""
+
+#: cp/decl.c:7685
+msgid "cannot declare member `%T::%s' within `%T'"
+msgstr "no es pot declarar el membre \"%T::%s\" dintre de \"%T\""
+
+#: cp/decl.c:7765
+msgid "data member may not have variably modified type `%T'"
+msgstr ""
+
+#: cp/decl.c:7767
+msgid "parameter may not have variably modified type `%T'"
+msgstr ""
+
+#. [dcl.fct.spec] The explicit specifier shall only be used in
+#. declarations of constructors within a class definition.
+#: cp/decl.c:7775
+msgid "only declarations of constructors can be `explicit'"
+msgstr "solament les declaracions de constructors poden ser \"explicit\""
+
+#: cp/decl.c:7783
+#, c-format
+msgid "non-member `%s' cannot be declared `mutable'"
+msgstr "el no-membre \"%s\" no pot ser declarat \"mutable\""
+
+#: cp/decl.c:7788
+#, c-format
+msgid "non-object member `%s' cannot be declared `mutable'"
+msgstr "el membre non-objecte \"%s\" no pot ser declarat \"mutable\""
+
+#: cp/decl.c:7794
+#, c-format
+msgid "function `%s' cannot be declared `mutable'"
+msgstr "la funció \"%s\" no pot ser declarada \"mutable\""
+
+#: cp/decl.c:7799
+#, c-format
+msgid "static `%s' cannot be declared `mutable'"
+msgstr "static \"%s\" no pot ser declarat \"mutable\""
+
+#: cp/decl.c:7804
+#, c-format
+msgid "const `%s' cannot be declared `mutable'"
+msgstr "const \"%s\" no pot ser declarat \"mutable\""
+
+#: cp/decl.c:7817
+msgid "template-id `%D' used as a declarator"
+msgstr "l'identificador de patró \"%D\" s'usa com un declarador"
+
+#: cp/decl.c:7838
+msgid "ISO C++ forbids nested type `%D' with same name as enclosing class"
+msgstr "ISO C++ prohibeix el tipus niat \"%D\" amb el mateix nom que la classe que ho conté"
+
+#: cp/decl.c:7846
+#, fuzzy
+msgid "%Jtypedef name may not be a nested-name-specifier"
+msgstr "el nom de la definició de tipus pot no ser qualificada per a la classe"
+
+#: cp/decl.c:7892
+#, fuzzy
+msgid "%Jinvalid type qualifier for non-member function type"
+msgstr "qualificador de tipus invàlid per al tipus de funció no membre"
+
+#: cp/decl.c:7955
+msgid "type qualifiers specified for friend class declaration"
+msgstr "es van especificar qualificadors de tipus en una declaració de classe friend"
+
+#: cp/decl.c:7960
+msgid "`inline' specified for friend class declaration"
+msgstr "es va especificar \"inline\" per a la declaració de classe friend"
+
+#: cp/decl.c:7968
+msgid "template parameters cannot be friends"
+msgstr "els paràmetres del patró no poden ser friends"
+
+#: cp/decl.c:7970
+msgid "friend declaration requires class-key, i.e. `friend class %T::%D'"
+msgstr "la declaració friend requereix una clau de classe, ex. \"friend class %T::%D\""
+
+#: cp/decl.c:7974
+msgid "friend declaration requires class-key, i.e. `friend %#T'"
+msgstr "la declaració friend requereix una clau de classe, ex. \"friend %#T\""
+
+#: cp/decl.c:7987
+msgid "trying to make class `%T' a friend of global scope"
+msgstr "tractant fer que la classe \"%T\" sigui un friend d'àmbit global"
+
+#: cp/decl.c:7998
+msgid "invalid qualifiers on non-member function type"
+msgstr "qualificadors invàlids en el tipus de funció no membre"
+
+#: cp/decl.c:8017
+msgid "abstract declarator `%T' used as declaration"
+msgstr "el declarador abstracte \"%T\" es va utilitzar com una declaració"
+
+#: cp/decl.c:8029
+msgid "unnamed variable or field declared void"
+msgstr "variable sense nom o camp declarat void"
+
+#: cp/decl.c:8038
+msgid "variable or field declared void"
+msgstr "variable o camp declarat void"
+
+#: cp/decl.c:8048
+msgid "cannot use `::' in parameter declaration"
+msgstr "no es pot usar \"::\" en la declaració de paràmetres"
+
+#. Something like struct S { int N::j; };
+#: cp/decl.c:8093
+msgid "invalid use of `::'"
+msgstr "ús invàlid de \"::\""
+
+#: cp/decl.c:8105
+msgid "function `%D' cannot be declared friend"
+msgstr "la funció \"%D\" no pot ser declarada friend"
+
+#: cp/decl.c:8117
+msgid "can't make `%D' into a method -- not in a class"
+msgstr "no es pot fer \"%D\" en un mètode -- no està en una classe"
+
+#: cp/decl.c:8126
+msgid "function `%D' declared virtual inside a union"
+msgstr "la funció \"%s\" es va declarar virtual dintre d'un union"
+
+#: cp/decl.c:8135
+msgid "`%D' cannot be declared virtual, since it is always static"
+msgstr "\"%D\" no es pot declarar virtual, ja que sempre és static"
+
+#: cp/decl.c:8214
+msgid "field `%D' has incomplete type"
+msgstr "el camp \"%D\" té tipus de dada incompleta"
+
+#: cp/decl.c:8216
+msgid "name `%T' has incomplete type"
+msgstr "el nom \"%T\" té tipus de dada incompleta"
+
+#: cp/decl.c:8225
+msgid " in instantiation of template `%T'"
+msgstr " en la instanciació det patró \"%T\""
+
+#: cp/decl.c:8235
+#, c-format
+msgid "`%s' is neither function nor member function; cannot be declared friend"
+msgstr "\"%s\" no és ni funció ni funció membre; no pot ser declarat friend"
+
+#: cp/decl.c:8246
+msgid "member functions are implicitly friends of their class"
+msgstr "les funcions membres són implícitament friends de la seva classe"
+
+#. An attempt is being made to initialize a non-static
+#. member. But, from [class.mem]:
+#.
+#. 4 A member-declarator can contain a
+#. constant-initializer only if it declares a static
+#. member (_class.static_) of integral or enumeration
+#. type, see _class.static.data_.
+#.
+#. This used to be relatively common practice, but
+#. the rest of the compiler does not correctly
+#. handle the initialization unless the member is
+#. static so we make it static below.
+#: cp/decl.c:8286
+msgid "ISO C++ forbids initialization of member `%D'"
+msgstr "ISO C++ prohibeix la inicialización del membre \"%D\""
+
+#: cp/decl.c:8288
+msgid "making `%D' static"
+msgstr "fent a \"%D\" static"
+
+#: cp/decl.c:8344
+#, c-format
+msgid "storage class `auto' invalid for function `%s'"
+msgstr "la classe d'emmagatzematge \"auto\" és invàlida per a la funció \"%s\""
+
+#: cp/decl.c:8346
+#, c-format
+msgid "storage class `register' invalid for function `%s'"
+msgstr "la classe d'emmagatzematge \"register\" és invàlida per a la funció \"%s\""
+
+#: cp/decl.c:8348
+#, c-format
+msgid "storage class `__thread' invalid for function `%s'"
+msgstr "la classe d'emmagatzematge \"__thread\" és invàlida per a la funció \"%s\""
+
+#: cp/decl.c:8359
+#, c-format
+msgid "storage class `static' invalid for function `%s' declared out of global scope"
+msgstr "la classe d'emmagatzematge \"static\" és invàlida per a la funció \"%s\" declarada fora de l'àmbit global"
+
+#: cp/decl.c:8361
+#, c-format
+msgid "storage class `inline' invalid for function `%s' declared out of global scope"
+msgstr "la classe d'emmagatzematge \"inline\" és invàlida per a la funció \"%s\" declarada fora de l'àmbit global"
+
+#: cp/decl.c:8368
+#, c-format
+msgid "virtual non-class function `%s'"
+msgstr "la funció virtual \"%s\" no és classe"
+
+#: cp/decl.c:8399
+msgid "cannot declare member function `%D' to have static linkage"
+msgstr "no es pot declarar que la funció membre \"%D\" tingui enllaçat estàtic"
+
+#. FIXME need arm citation
+#: cp/decl.c:8405
+msgid "cannot declare static function inside another function"
+msgstr "no es pot declarar una funció static dintre d'altra funció"
+
+#: cp/decl.c:8433
+msgid "`static' may not be used when defining (as opposed to declaring) a static data member"
+msgstr "\"static\" pot no ser utilitzat quan es defineix (oposat a la declaració) una dada membre static"
+
+#: cp/decl.c:8439
+msgid "static member `%D' declared `register'"
+msgstr "es va declarar el membre static \"%D\" com \"register\""
+
+#: cp/decl.c:8444
+msgid "cannot explicitly declare member `%#D' to have extern linkage"
+msgstr "no es pot declarar explícitament que el membre \"%#D\" tingui un enllaçat extern"
+
+#: cp/decl.c:8584
+msgid "default argument for `%#D' has type `%T'"
+msgstr "l'argument per omissió de \"%#D\" té tipus \"%T\""
+
+#: cp/decl.c:8587
+msgid "default argument for parameter of type `%T' has type `%T'"
+msgstr "l'argument per omissió per al paràmetre del tipus \"%T\" té el tipus \"%T\""
+
+#: cp/decl.c:8604
+msgid "default argument `%E' uses local variable `%D'"
+msgstr "l'argument per omissió \"%E\" usa la variable local \"%D\""
+
+#: cp/decl.c:8648
+#, c-format
+msgid "invalid string constant `%E'"
+msgstr "constant de cadena invàlida \"%E\""
+
+#: cp/decl.c:8650
+msgid "invalid integer constant in parameter list, did you forget to give parameter name?"
+msgstr "constant entera invàlida en la llista de paràmetres, va oblidar proporcionar nom(s) de paràmetre(s)?"
+
+#: cp/decl.c:8688
+msgid "parameter `%D' invalidly declared method type"
+msgstr "el paràmetre \"%D\" es va declarar invàlidament com tipus de mètode"
+
+#: cp/decl.c:8712
+msgid "parameter `%D' includes %s to array of unknown bound `%T'"
+msgstr "el paràmetre \"%D\" inclou %s per a la matriu \"%T\" de límit desconegut"
+
+#. [class.copy]
+#.
+#. A declaration of a constructor for a class X is ill-formed if
+#. its first parameter is of type (optionally cv-qualified) X
+#. and either there are no other parameters or else all other
+#. parameters have default arguments.
+#.
+#. We *don't* complain about member template instantiations that
+#. have this form, though; they can occur as we try to decide
+#. what constructor to use during overload resolution. Since
+#. overload resolution will never prefer such a constructor to
+#. the non-template copy constructor (which is either explicitly
+#. or implicitly defined), there's no need to worry about their
+#. existence. Theoretically, they should never even be
+#. instantiated, but that's hard to forestall.
+#: cp/decl.c:8871
+msgid "invalid constructor; you probably meant `%T (const %T&)'"
+msgstr "constructor invàlid; tal vegada va voler dir \"%T (const %T&)\""
+
+#: cp/decl.c:8999
+msgid "`%D' must be a nonstatic member function"
+msgstr "\"%D\" deu ser una funció membre que no sigui static"
+
+#: cp/decl.c:9005
+msgid "`%D' must be either a non-static member function or a non-member function"
+msgstr "\"%D\" deu ser una funció membre no estàtic o una funció no membre"
+
+#: cp/decl.c:9022
+msgid "`%D' must have an argument of class or enumerated type"
+msgstr "\"%D\" deu tenir un argument de tipus classe o enumerat"
+
+#: cp/decl.c:9057
+#, c-format
+msgid "conversion to %s%s will never use a type conversion operator"
+msgstr "la conversió a %s%s mai usarà un operador de conversió de tipus"
+
+#. 13.4.0.3
+#: cp/decl.c:9064
+msgid "ISO C++ prohibits overloading operator ?:"
+msgstr "ISO C++ prohibeix la sobrecàrrega de l'operador ?:"
+
+#: cp/decl.c:9114
+msgid "postfix `%D' must take `int' as its argument"
+msgstr "el postfix \"%D\" deu prendre \"int\" com el seu argument"
+
+#: cp/decl.c:9118
+msgid "postfix `%D' must take `int' as its second argument"
+msgstr "el postfix \"%D\" deu prendre \"int\" com el seu segon argument"
+
+#: cp/decl.c:9125
+msgid "`%D' must take either zero or one argument"
+msgstr "\"%D\" deu prendre zero o un arguments"
+
+#: cp/decl.c:9127
+msgid "`%D' must take either one or two arguments"
+msgstr "\"%D\" deu prendre un o dos arguments"
+
+#: cp/decl.c:9148
+msgid "prefix `%D' should return `%T'"
+msgstr "el prefix \"%D\" deu regressar \"%T\""
+
+#: cp/decl.c:9154
+msgid "postfix `%D' should return `%T'"
+msgstr "el postfix \"%D\" deu regressar \"%T\""
+
+#: cp/decl.c:9163
+msgid "`%D' must take `void'"
+msgstr "\"%D\" deu prendre \"void\""
+
+#: cp/decl.c:9165 cp/decl.c:9173
+msgid "`%D' must take exactly one argument"
+msgstr "\"%D\" deu prendre un argument exactament"
+
+#: cp/decl.c:9175
+msgid "`%D' must take exactly two arguments"
+msgstr "\"%D\" deu prendre dos arguments exactament"
+
+#: cp/decl.c:9183
+msgid "user-defined `%D' always evaluates both arguments"
+msgstr "el \"%D\" definit per l'usuari sempre avalua ambdós arguments"
+
+#: cp/decl.c:9197
+msgid "`%D' should return by value"
+msgstr "\"%D\" deu regressar per valor"
+
+#: cp/decl.c:9209 cp/decl.c:9212
+msgid "`%D' cannot have default arguments"
+msgstr "\"%D\" no pot tenir arguments per omissió"
+
+#: cp/decl.c:9272
+msgid "using typedef-name `%D' after `%s'"
+msgstr "usant el nom de definició de tipus \"%D\" després de \"%s\""
+
+#: cp/decl.c:9278
+msgid "using template type parameter `%T' after `%s'"
+msgstr "usant el paràmetre de tipus patró \"%T\" després de \"%s\""
+
+#: cp/decl.c:9286
+#, fuzzy
+msgid "`%T' referred to as `%s'"
+msgstr "\"%#D\" redeclarat com %C"
+
+#: cp/decl.c:9292
+#, fuzzy
+msgid "`%T' referred to as enum"
+msgstr "\"%#D\" redeclarat com %C"
+
+#. If a class template appears as elaborated type specifier
+#. without a template header such as:
+#.
+#. template <class T> class C {};
+#. void f(class C); // No template header here
+#.
+#. then the required template argument is missing.
+#: cp/decl.c:9307
+#, fuzzy
+msgid "template argument required for `%s %T'"
+msgstr "es requereix un argument de patró per a \"%T\""
+
+#: cp/decl.c:9452
+msgid "use of enum `%#D' without previous declaration"
+msgstr "ús del enum \"%#D\" sense declaració prèvia"
+
+#: cp/decl.c:9509
+msgid "derived union `%T' invalid"
+msgstr "union derivada \"%T\" invàlida"
+
+#: cp/decl.c:9562
+msgid "base type `%T' fails to be a struct or class type"
+msgstr "el tipus base \"%T\" falla a ser un tipus struct o classe"
+
+#: cp/decl.c:9570
+msgid "recursive type `%T' undefined"
+msgstr "tipus recursivo \"%T\" sense definir"
+
+#: cp/decl.c:9572
+msgid "duplicate base type `%T' invalid"
+msgstr "tipus base duplicat \"%T\" invàlid"
+
+#: cp/decl.c:9650
+msgid "Java class '%T' cannot have multiple bases"
+msgstr ""
+
+#: cp/decl.c:9652
+#, fuzzy
+msgid "Java class '%T' cannot have virtual bases"
+msgstr "la classe base \"%#T\" té un destructor no virtual"
+
+#: cp/decl.c:9692
+msgid "multiple definition of `%#T'"
+msgstr "definició múltiple de \"%#T\""
+
+#: cp/decl.c:9693
+#, fuzzy
+msgid "%Jprevious definition here"
+msgstr "definició prèvia aquí"
+
+#. DR 377
+#.
+#. IF no integral type can represent all the enumerator values, the
+#. enumeration is ill-formed.
+#: cp/decl.c:9828
+msgid "no integral type can represent all of the enumerator values for `%T'"
+msgstr ""
+
+#: cp/decl.c:9918
+msgid "enumerator value for `%D' not integer constant"
+msgstr "el valor de enumerador per a \"%D\" no és una constant entera"
+
+#: cp/decl.c:9938
+msgid "overflow in enumeration values at `%D'"
+msgstr "desbordament en valors d'enumeració en \"%D\""
+
+#: cp/decl.c:10007
+msgid "return type `%#T' is incomplete"
+msgstr "el tipus de retorn \"%#T\" és un tipus de dada incompleta"
+
+#: cp/decl.c:10125
+msgid "return type for `main' changed to `int'"
+msgstr "el tipus de retorn per a \"main\" va canviar a \"int\""
+
+#: cp/decl.c:10154
+msgid "`%D' implicitly declared before its definition"
+msgstr "\"%D\" declarat implícitament abans de la seva definició"
+
+#: cp/decl.c:10176 cp/typeck.c:6023
+msgid "`operator=' should return a reference to `*this'"
+msgstr "\"operator=\" deu retornar una referència a \"*this\""
+
+#: cp/decl.c:10445
+msgid "parameter `%D' declared void"
+msgstr "el paràmetre \"%D\" es va declarar void"
+
+#: cp/decl.c:10911
+#, fuzzy
+msgid "invalid member function declaration"
+msgstr "declaració del patró membre \"%D\" invàlida"
+
+#: cp/decl.c:10928
+msgid "`%D' is already defined in class `%T'"
+msgstr "\"%D\" ja es va definir en la classe \"%T\""
+
+#: cp/decl.c:11141
+msgid "static member function `%#D' declared with type qualifiers"
+msgstr "la funció membre static \"%#D\" és declarada amb qualificadors de tipus"
+
+#: cp/decl2.c:143
+#, c-format
+msgid "duplicate type qualifiers in %s declaration"
+msgstr "qualificadors de tipus duplicats en la declaració %s"
+
+#: cp/decl2.c:316
+msgid "name missing for member function"
+msgstr "falta el nom per a la funció membre"
+
+#: cp/decl2.c:408 cp/decl2.c:422
+msgid "ambiguous conversion for array subscript"
+msgstr "conversió ambigua per a índex de matriu"
+
+#: cp/decl2.c:416
+msgid "invalid types `%T[%T]' for array subscript"
+msgstr "tipus invàlids \"%T[%T]\" per a índex de matriu"
+
+#: cp/decl2.c:460
+msgid "deleting array `%#D'"
+msgstr "esborrant la matriu \"%#D\""
+
+#: cp/decl2.c:466
+msgid "type `%#T' argument given to `delete', expected pointer"
+msgstr "es va donar un argument de tipus \"%#T\" a \"delete\", s'esperava un punter"
+
+#: cp/decl2.c:478
+msgid "cannot delete a function. Only pointer-to-objects are valid arguments to `delete'"
+msgstr "no es pot esborrar una funció. Solament els punters a objectes són arguments vàlids per a \"delete\""
+
+#: cp/decl2.c:485
+msgid "deleting `%T' is undefined"
+msgstr "esborrar \"%T\" està indefinit"
+
+#. 14.5.2.2 [temp.mem]
+#.
+#. A local class shall not have member templates.
+#: cp/decl2.c:521
+msgid "invalid declaration of member template `%#D' in local class"
+msgstr "declaració invàlida del patró membre \"%#D\" en la classe local"
+
+#: cp/decl2.c:530
+msgid "invalid use of `virtual' in template declaration of `%#D'"
+msgstr "ús invàlid de \"virtual\" en la declaració de patró de \"%#D\""
+
+#: cp/decl2.c:540 cp/pt.c:2834
+msgid "template declaration of `%#D'"
+msgstr "declaració en patró de \"%#D\""
+
+#: cp/decl2.c:589
+msgid "Java method '%D' has non-Java return type `%T'"
+msgstr "el mètode Java \"%D\" té un tipus de retorn \"%T\" que no és de Java"
+
+#: cp/decl2.c:605
+msgid "Java method '%D' has non-Java parameter type `%T'"
+msgstr "el mètode Java \"%D\" té un tipus de paràmetre \"%T\" que no és de Java"
+
+#: cp/decl2.c:698
+msgid "prototype for `%#D' does not match any in class `%T'"
+msgstr "el prototip per a \"%#D\" no coincideix amb cap altre en la classe \"%T\""
+
+#: cp/decl2.c:777
+msgid "local class `%#T' shall not have static data member `%#D'"
+msgstr "la classe local \"%#T\" no deu tenir el membre static \"%#D\""
+
+#: cp/decl2.c:785
+msgid "initializer invalid for static member with constructor"
+msgstr "inicializador invàlid per al membre static amb constructor"
+
+#: cp/decl2.c:788
+msgid "(an out of class initialization is required)"
+msgstr "(es requereix una inicialització fora de la classe)"
+
+#: cp/decl2.c:871
+msgid "member `%D' conflicts with virtual function table field name"
+msgstr "el membre \"%D\" té conflictes amb el nom de camp de la matriu de funcions virtuals"
+
+#: cp/decl2.c:888
+msgid "`%D' is already defined in `%T'"
+msgstr "\"%D\" ja està definit en \"%T\""
+
+#: cp/decl2.c:935
+msgid "field initializer is not constant"
+msgstr "el inicializador del camp no és constant"
+
+#: cp/decl2.c:963
+msgid "`asm' specifiers are not permitted on non-static data members"
+msgstr "no es permeten els especificadores \"asm\" en membres de dades no estàtiques"
+
+#: cp/decl2.c:1013
+msgid "cannot declare `%D' to be a bit-field type"
+msgstr "no es pot declarar \"%D\" que sigui un tipus de camp de bits"
+
+#: cp/decl2.c:1023
+msgid "cannot declare bit-field `%D' with function type"
+msgstr "no es pot declarar el camp de bits \"%D\" amb un tipus de funció"
+
+#: cp/decl2.c:1030
+msgid "`%D' is already defined in the class %T"
+msgstr "\"%D\" ja està definit en la classe %T"
+
+#: cp/decl2.c:1037
+msgid "static member `%D' cannot be a bit-field"
+msgstr "el membre static \"%D\" no pot ser un camp de bits"
+
+#: cp/decl2.c:1096
+msgid "initializer specified for non-member function `%D'"
+msgstr "es va especificar un inicialitzador per a la funció no-membre \"%D\""
+
+#: cp/decl2.c:1100
+msgid "invalid initializer for virtual method `%D'"
+msgstr "inicialitzador invàlid per al mètode virtual \"%D\""
+
+#: cp/decl2.c:1147
+msgid "anonymous struct not inside named type"
+msgstr "struct anònim no es troba dintre d'un tipus nomenat"
+
+#: cp/decl2.c:1217
+msgid "namespace-scope anonymous aggregates must be static"
+msgstr "els agregats anònims d'abast de nom d'espai deuen ser static"
+
+#: cp/decl2.c:1224
+#, fuzzy
+msgid "anonymous union with no members"
+msgstr "agregat anònim sense membres"
+
+#: cp/decl2.c:1258
+msgid "`operator new' must return type `%T'"
+msgstr "\"operator new\" deu retornar el tipus \"%T\""
+
+#: cp/decl2.c:1266
+msgid "`operator new' takes type `size_t' (`%T') as first parameter"
+msgstr "\"operator new\" pren el tipus \"size_t\" (\"%T\") com primer argument"
+
+#: cp/decl2.c:1292
+msgid "`operator delete' must return type `%T'"
+msgstr "\"operator delete\" deu retornar el tipus \"%T\""
+
+#: cp/decl2.c:1300
+msgid "`operator delete' takes type `%T' as first parameter"
+msgstr "\"operator delete\" pren el tipus \"%T\" com primer argument"
+
+#: cp/decl2.c:2807
+msgid "inline function `%D' used but never defined"
+msgstr "s'usa la funció inline \"%D\" però mai es va definir"
+
+#: cp/decl2.c:2953
+msgid "default argument missing for parameter %P of `%+#D'"
+msgstr "falta l'argument per omissió per al paràmetre %P de \"%+#D\""
+
+#. damn ICE suppression
+#: cp/error.c:2387
+#, c-format
+msgid "unexpected letter `%c' in locate_error\n"
+msgstr "lletra \"%c\" inesperada en locate_error\n"
+
+#. Can't throw a reference.
+#: cp/except.c:239
+msgid "type `%T' is disallowed in Java `throw' or `catch'"
+msgstr "el tipus \"%T\" no està permès en \"throw\" o \"catch\" de Java"
+
+#: cp/except.c:250
+msgid "call to Java `catch' or `throw' with `jthrowable' undefined"
+msgstr "cridada a \"catch\" o \"throw\" de Java amb \"jthrowable\" sense definir"
+
+#. Thrown object must be a Throwable.
+#: cp/except.c:257
+msgid "type `%T' is not derived from `java::lang::Throwable'"
+msgstr "el tipus \"%T\" no és derivat de \"java::lang::Throwable\""
+
+#: cp/except.c:320
+msgid "mixing C++ and Java catches in a single translation unit"
+msgstr "barrejant \"catches\" de C++ i Java en una sola unitat de traducció"
+
+#: cp/except.c:575
+msgid "throwing NULL, which has integral, not pointer type"
+msgstr "llançant NULL, que té un tipus integral, no un tipus punter"
+
+#: cp/except.c:598 cp/init.c:2037
+#, fuzzy
+msgid "`%D' should never be overloaded"
+msgstr "\"%D\" deu regressar per valor"
+
+#: cp/except.c:665
+msgid " in thrown expression"
+msgstr " en expressió thrown"
+
+#: cp/except.c:811
+msgid "expression '%E' of abstract class type '%T' cannot be used in throw-expression"
+msgstr "no es pot usar l'expressió \"%E\" del tipus de classe abstracta \"%T\" en les expressions thrown"
+
+#: cp/except.c:893
+msgid "exception of type `%T' will be caught"
+msgstr "l'excepció del tipus \"%T\" serà atrapada"
+
+#: cp/except.c:896
+msgid " by earlier handler for `%T'"
+msgstr " per un gestor anterior per a \"%T\""
+
+#: cp/except.c:917
+msgid "`...' handler must be the last handler for its try block"
+msgstr "el gestor \"...\" deu ser l'últim gestor per al seu bloc try"
+
+#: cp/friend.c:151
+msgid "`%D' is already a friend of class `%T'"
+msgstr "\"%D\" ja és un friend de la classe \"%T\""
+
+#: cp/friend.c:202
+msgid "invalid type `%T' declared `friend'"
+msgstr "el tipus invàlid \"%T\" va ser declarat \"friend\""
+
+#. [temp.friend]
+#. Friend declarations shall not declare partial
+#. specializations.
+#: cp/friend.c:218
+msgid "partial specialization `%T' declared `friend'"
+msgstr "l'especialització parcial \"%T\" es va declarar \"friend\""
+
+#: cp/friend.c:228
+msgid "class `%T' is implicitly friends with itself"
+msgstr "la classe \"%T\" és implícitament friend amb si mateixa"
+
+#. template <class T> friend typename S<T>::X;
+#: cp/friend.c:246
+msgid "typename type `%#T' declared `friend'"
+msgstr "el tipus de nom de tipus \"%#T\" es va declarar \"friend\""
+
+#. template <class T> friend class T;
+#: cp/friend.c:252
+msgid "template parameter type `%T' declared `friend'"
+msgstr "el tipus de paràmetre de patró \"%T\" es va declarar \"friend\""
+
+#. template <class T> friend class A; where A is not a template
+#: cp/friend.c:258
+msgid "`%#T' is not a template"
+msgstr "\"%#T\" no és un patró"
+
+#: cp/friend.c:277
+#, fuzzy
+msgid "`%D' is already a friend of `%T'"
+msgstr "\"%T\" ja és un friend de \"%T\""
+
+#: cp/friend.c:287
+msgid "`%T' is already a friend of `%T'"
+msgstr "\"%T\" ja és un friend de \"%T\""
+
+#: cp/friend.c:409
+msgid "member `%D' declared as friend before type `%T' defined"
+msgstr "el membre \"%D\" és declarat friend abans que es defineixi el tipus \"%T\""
+
+#: cp/friend.c:465
+msgid "friend declaration `%#D' declares a non-template function"
+msgstr "la declaració friend \"%#D\" declara una funció que no és patró"
+
+#: cp/friend.c:468
+msgid "(if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning"
+msgstr "(si aquesta no és la seva intenció, asseguri's qu'el patró de la funció ja ha estat declarada i agregui <> aquí després del nom de la funció) -Wno-non-template-friend desactiva aquest avís"
+
+#: cp/g++spec.c:229 java/jvspec.c:415
+#, c-format
+msgid "argument to `%s' missing\n"
+msgstr "falta l'argument per a `%s'\n"
+
+#: cp/init.c:318
+msgid "`%D' should be initialized in the member initialization list"
+msgstr ""
+
+#: cp/init.c:368
+msgid "default-initialization of `%#D', which has reference type"
+msgstr "l'inicialització per omissió de \"%#D\", el qual té el tipus de referència"
+
+#: cp/init.c:373
+msgid "uninitialized reference member `%D'"
+msgstr "membre referència \"%D\" sense inicialitzar"
+
+#: cp/init.c:375
+#, fuzzy
+msgid "uninitialized member `%D' with `const' type `%T'"
+msgstr "const \"%D\" sense inicialitzar"
+
+#: cp/init.c:514
+msgid "`%D' will be initialized after"
+msgstr "\"%D\" s'inicialitzarà després"
+
+#: cp/init.c:517
+msgid "base `%T' will be initialized after"
+msgstr "la base \"%T\" s'inicialitzarà després"
+
+#: cp/init.c:520
+msgid " `%#D'"
+msgstr " \"#%D\""
+
+#: cp/init.c:522
+msgid " base `%T'"
+msgstr " base \"%T\""
+
+#: cp/init.c:523
+#, fuzzy
+msgid " when initialized here"
+msgstr "\"%D\" s'inicialitzarà després"
+
+#: cp/init.c:539
+msgid "multiple initializations given for `%D'"
+msgstr "es van donar inicialitzacions múltiples per a \"%D\""
+
+#: cp/init.c:541
+msgid "multiple initializations given for base `%T'"
+msgstr "es van donar inicialitzacions múltiples per a la base \"%T\""
+
+#: cp/init.c:608
+msgid "initializations for multiple members of `%T'"
+msgstr "inicialitzacions per a múltiples membres de \"%T\""
+
+#: cp/init.c:665
+msgid "base class `%#T' should be explicitly initialized in the copy constructor"
+msgstr "la classe base \"%#T\" deu ser inicialitzada explícitament en la còpia del constructor"
+
+#: cp/init.c:895 cp/init.c:914
+msgid "class `%T' does not have any field named `%D'"
+msgstr "la classe \"%T\" no té cap camp cridat \"%D\""
+
+#: cp/init.c:901
+#, fuzzy
+msgid "`%#D' is a static data member; it can only be initialized at its definition"
+msgstr "el camp \"%#D\" és static; l'únic punt d'inicialització és la seva definició"
+
+#: cp/init.c:908
+#, fuzzy
+msgid "`%#D' is not a non-static data member of `%T'"
+msgstr "\"%#D\" no és un membre static de \"%#T\""
+
+#: cp/init.c:947
+msgid "unnamed initializer for `%T', which has no base classes"
+msgstr "inicialitzador sense nom per a \"%T\", el qual no té una classe base"
+
+#: cp/init.c:954
+msgid "unnamed initializer for `%T', which uses multiple inheritance"
+msgstr "inicialitzador sense nom per a \"%T\", el qual usa herència múltiple"
+
+#: cp/init.c:1009
+#, fuzzy
+msgid "'%D' is both a direct base and an indirect virtual base"
+msgstr "el tipus \"%D\" no és una base directa o virtual de \"%T\""
+
+#: cp/init.c:1017
+msgid "type `%D' is not a direct or virtual base of `%T'"
+msgstr "el tipus \"%D\" no és una base directa o virtual de \"%T\""
+
+#: cp/init.c:1020
+msgid "type `%D' is not a direct base of `%T'"
+msgstr "el tipus \"%D\" no és una base directa de \"%T\""
+
+#. 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];
+#. }
+#.
+#: cp/init.c:1112
+msgid "bad array initializer"
+msgstr "inicialitzador de matriu erroni"
+
+#: cp/init.c:1310
+msgid "`%T' is not an aggregate type"
+msgstr "\"%T\" no és un tipus agregat"
+
+#: cp/init.c:1331
+msgid "`%T' fails to be an aggregate typedef"
+msgstr "\"%T\" falla a ser un tipus agregat"
+
+#: cp/init.c:1340
+msgid "type `%T' is of non-aggregate type"
+msgstr "el tipus \"%T\" és d'un tipus no agregat"
+
+#: cp/init.c:1432 cp/typeck.c:1795
+msgid "qualified type `%T' does not match destructor name `~%T'"
+msgstr "el tipus qualificat \"%T\" no coincideix amb el nom del destructor \"~%T\""
+
+#: cp/init.c:1440
+msgid "incomplete type `%T' does not have member `%D'"
+msgstr "el tipus incomplet \"%T\" no té al membre \"%D\""
+
+#: cp/init.c:1459
+msgid "`%D' is not a member of type `%T'"
+msgstr "\"%D\" no és un membre de tipus \"%T\""
+
+#: cp/init.c:1478
+msgid "invalid pointer to bit-field `%D'"
+msgstr "punter invàlid al camp de bit \"%D\""
+
+#: cp/init.c:1580
+#, fuzzy
+msgid "invalid use of non-static member function `%D'"
+msgstr "ús invàlid del camp no static \"%D\""
+
+#: cp/init.c:1586 cp/semantics.c:1236
+#, fuzzy
+msgid "invalid use of non-static data member `%D'"
+msgstr "ús invàlid del camp no static \"%D\""
+
+#: cp/init.c:1725
+msgid "new of array type fails to specify size"
+msgstr "new de matriu falla a l'especificar la grandària"
+
+#: cp/init.c:1736
+msgid "size in array new must have integral type"
+msgstr "la grandària de la matriu nova deu tenir un tipus integral"
+
+#: cp/init.c:1742
+msgid "zero size array reserves no space"
+msgstr "la matriu de grandària zero no reserva espai"
+
+#: cp/init.c:1808
+msgid "new cannot be applied to a reference type"
+msgstr "new no pot ser aplicat a un tipus de referència"
+
+#: cp/init.c:1814
+msgid "new cannot be applied to a function type"
+msgstr "new no pot ser aplicat a una funcció de referència"
+
+#: cp/init.c:1860
+msgid "call to Java constructor, while `jclass' undefined"
+msgstr "cridada a constructor Java, mentre \"jclass\" està indefinit"
+
+#: cp/init.c:1876
+msgid "can't find class$"
+msgstr "no es pot trobar class$"
+
+#: cp/init.c:2003
+msgid "invalid type `void' for new"
+msgstr "tipus \"void\" invàlid per a new"
+
+#: cp/init.c:2013
+msgid "uninitialized const in `new' of `%#T'"
+msgstr "const sense inicialitzar en \"new\" de \"%#T\""
+
+#: cp/init.c:2032
+#, c-format
+msgid "call to Java constructor with `%s' undefined"
+msgstr "cridada a constructor Java amb \"%s\" sense definir"
+
+#: cp/init.c:2073
+msgid "request for member `%D' is ambiguous"
+msgstr "a petició per al membre \"%D\" és ambigua"
+
+#: cp/init.c:2193
+msgid "ISO C++ forbids initialization in array new"
+msgstr "ISO C++ prohibeix la inicialització en la matriu new"
+
+#: cp/init.c:2667
+msgid "initializer ends prematurely"
+msgstr "el inicialitzador acaba prematurament"
+
+#: cp/init.c:2724
+msgid "cannot initialize multi-dimensional array with initializer"
+msgstr "no es poden inicialitzar matrius multidimensionals amb el inicialitzador"
+
+#: cp/init.c:2885
+msgid "possible problem detected in invocation of delete operator:"
+msgstr ""
+
+#: cp/init.c:2888
+msgid "neither the destructor nor the class-specific "
+msgstr ""
+
+#: cp/init.c:2889
+msgid "operator delete will be called, even if they are "
+msgstr ""
+
+#: cp/init.c:2890
+msgid "declared when the class is defined."
+msgstr ""
+
+#: cp/init.c:2909
+msgid "unknown array size in delete"
+msgstr "grandària de matriu desconeguda en delete"
+
+#: cp/init.c:3174
+msgid "type to vector delete is neither pointer or array type"
+msgstr "el tipus de vector delete no és del tipus punter ni matriu"
+
+#: cp/lex.c:99
+msgid "type name expected before `*'"
+msgstr "s'esperava nom de tipus abans de \"*\""
+
+#: cp/lex.c:501
+#, c-format
+msgid "junk at end of #pragma %s"
+msgstr "escombraries al final de #pragma %s"
+
+#: cp/lex.c:508
+#, c-format
+msgid "invalid #pragma %s"
+msgstr "#pragma %s invàlid"
+
+#: cp/lex.c:516
+msgid "#pragma vtable no longer supported"
+msgstr "#pragma vtable ja no té suport"
+
+#: cp/lex.c:590
+#, c-format
+msgid "#pragma implementation for %s appears after file is included"
+msgstr "implementació de #pragma per a %s apareix després que el fitxer és inclòs"
+
+#: cp/lex.c:614
+msgid "junk at end of #pragma GCC java_exceptions"
+msgstr "escombraries al final del #pragma GCC java_exceptions"
+
+#: cp/lex.c:628
+msgid "`%D' not defined"
+msgstr "\"%D\" no està definit"
+
+#: cp/lex.c:631
+msgid "`%D' was not declared in this scope"
+msgstr "\"%D\" no es va declarar en aquest àmbit"
+
+#: cp/lex.c:639
+msgid "`%D' undeclared (first use this function)"
+msgstr "\"%D\" sense declarar (primer ús en aquesta funció)"
+
+#: cp/lex.c:643
+msgid "(Each undeclared identifier is reported only once for each function it appears in.)"
+msgstr "(Cada identificador sense declarar és reportat només una vegada per a cada funció en el qual apareix.)"
+
+#. In a template, it is invalid to write "f()" or "f(3)" if no
+#. declaration of "f" is available. Historically, G++ and most
+#. other compilers accepted that usage since they deferred all name
+#. lookup until instantiation time rather than doing unqualified
+#. name lookup at template definition time; explain to the user what
+#. is going wrong.
+#.
+#. Note that we have the exact wording of the following message in
+#. the manual (trouble.texi, node "Name lookup"), so they need to
+#. be kept in synch.
+#: cp/lex.c:674
+msgid "there are no arguments to `%D' that depend on a template parameter, so a declaration of `%D' must be available"
+msgstr ""
+
+#: cp/lex.c:683
+msgid "(if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)"
+msgstr ""
+
+#: cp/mangle.c:2037
+msgid "call_expr cannot be mangled due to a defect in the C++ ABI"
+msgstr ""
+
+#: cp/mangle.c:2090
+msgid "omitted middle operand to `?:' operand cannot be mangled"
+msgstr ""
+
+#: cp/mangle.c:2389
+msgid "the mangled name of `%D' will change in a future version of GCC"
+msgstr ""
+
+#: cp/method.c:461
+msgid "generic thunk code fails for method `%#D' which uses `...'"
+msgstr "el codi de thunk genèric va fallar per al mètode \"%#D\" que utilitza \"...\""
+
+#: cp/method.c:686
+msgid "non-static const member `%#D', can't use default assignment operator"
+msgstr "el membre const \"%#D\" que no és static, no pot usar l'operador d'assignació per omissió"
+
+#: cp/method.c:691
+msgid "non-static reference member `%#D', can't use default assignment operator"
+msgstr "el membre de referència \"%#D\" que no és static, no pot usar l'operador d'assignació per omissió"
+
+#: cp/name-lookup.c:660
+msgid "`%#D' used prior to declaration"
+msgstr "s'usa \"%#D\" previ a la declaració"
+
+#: cp/name-lookup.c:691
+msgid "redeclaration of `wchar_t' as `%T'"
+msgstr "redeclaración de \"wchar_t\" com \"%T\""
+
+#. A redeclaration of main, but not a duplicate of the
+#. previous one.
+#.
+#. [basic.start.main]
+#.
+#. This function shall not be overloaded.
+#: cp/name-lookup.c:723
+msgid "invalid redeclaration of `%D'"
+msgstr "redeclaración invàlida de \"%D\""
+
+#: cp/name-lookup.c:724
+msgid "as `%D'"
+msgstr "com \"%D\""
+
+#: cp/name-lookup.c:812
+#, fuzzy
+msgid "type mismatch with previous external decl of `%#D'"
+msgstr "no coincideixen els tipus amb la declaració externa prèvia"
+
+#: cp/name-lookup.c:813
+msgid "previous external decl of `%#D'"
+msgstr "declaració externa prèvia de \"%#D\""
+
+#: cp/name-lookup.c:855
+msgid "`%D' was previously implicitly declared to return `int'"
+msgstr "\"%D\" va ser declarat prèvia i implícitament per a retornar \"int\""
+
+#: cp/name-lookup.c:913
+msgid "extern declaration of `%#D' doesn't match"
+msgstr "la declaració externa de \"%#D\" no coincideix"
+
+#: cp/name-lookup.c:914
+msgid "global declaration `%#D'"
+msgstr "amb la declaració global \"%#D\""
+
+#: cp/name-lookup.c:950 cp/name-lookup.c:957
+#, fuzzy
+msgid "declaration of '%#D' shadows a parameter"
+msgstr "la declaració de \"%#D\" enfosqueix un paràmetre"
+
+#. Location of previous decl is not useful in this case.
+#: cp/name-lookup.c:974
+#, fuzzy
+msgid "declaration of '%D' shadows a member of 'this'"
+msgstr "la declaració de \"%s\" obscurece a un membre de \"this\""
+
+#: cp/name-lookup.c:980
+#, fuzzy
+msgid "declaration of '%D' shadows a previous local"
+msgstr "la declaració de \"%#D\" enfosqueix un paràmetre"
+
+#: cp/name-lookup.c:987
+#, fuzzy
+msgid "declaration of '%D' shadows a global declaration"
+msgstr "la declaració de \"%#D\" enfosqueix un paràmetre"
+
+#: cp/name-lookup.c:1156
+msgid "name lookup of `%D' changed"
+msgstr "la recerca de nom de \"%D\" va cambiar"
+
+#: cp/name-lookup.c:1158
+msgid " matches this `%D' under ISO standard rules"
+msgstr ""
+
+#: cp/name-lookup.c:1160
+msgid " matches this `%D' under old rules"
+msgstr ""
+
+#: cp/name-lookup.c:1174 cp/name-lookup.c:1181
+msgid "name lookup of `%D' changed for new ISO `for' scoping"
+msgstr ""
+
+#: cp/name-lookup.c:1176
+msgid " cannot use obsolete binding at `%D' because it has a destructor"
+msgstr ""
+
+#: cp/name-lookup.c:1183
+msgid " using obsolete binding at `%D'"
+msgstr ""
+
+#: cp/name-lookup.c:1236
+#, c-format
+msgid "%s %s(%E) %p %d\n"
+msgstr ""
+
+#: cp/name-lookup.c:1239
+#, fuzzy, c-format
+msgid "%s %s %p %d\n"
+msgstr "%s: %s: "
+
+#: cp/name-lookup.c:1358
+msgid "XXX is_class_level != (current_scope == class_scope)\n"
+msgstr ""
+
+#: cp/name-lookup.c:1996
+msgid "`%#D' hides constructor for `%#T'"
+msgstr "\"%#D\" amaga el destructor per a \"%#T\""
+
+#: cp/name-lookup.c:2011
+msgid "`%#D' conflicts with previous using declaration `%#D'"
+msgstr "\"%#D\" causa conflicte amb la declaració prèvia en ús \"%#D\""
+
+#: cp/name-lookup.c:2023
+msgid "previous non-function declaration `%#D'"
+msgstr "la declaració prèvia \"%#D\" que no és funció"
+
+#: cp/name-lookup.c:2024
+msgid "conflicts with function declaration `%#D'"
+msgstr "causa conflicte amb la declaració de la funció \"%#D\""
+
+#. 7.3.3/5
+#. A using-declaration shall not name a template-id.
+#: cp/name-lookup.c:2101
+msgid "a using-declaration cannot specify a template-id. Try `using %D'"
+msgstr "una declaració d'ús no pot especificar un identificador de patró. Intenti \"using %D\""
+
+#: cp/name-lookup.c:2107
+msgid "namespace `%D' not allowed in using-declaration"
+msgstr "no es permet l'espai de noms \"%D\" en la declaració d'ús"
+
+#. It's a nested name with template parameter dependent scope.
+#. This can only be using-declaration for class member.
+#: cp/name-lookup.c:2115 cp/name-lookup.c:2129 cp/name-lookup.c:3369
+msgid "`%T' is not a namespace"
+msgstr "\"%T\" no és un nom d'espai"
+
+#: cp/name-lookup.c:2153
+msgid "`%D' not declared"
+msgstr "no es va declarar \"%D\""
+
+#. If the OLD_FN was really declared, the
+#. declarations don't match.
+#: cp/name-lookup.c:2165 cp/name-lookup.c:2207 cp/name-lookup.c:2244
+msgid "`%D' is already declared in this scope"
+msgstr "\"%D\" ja es va declarar en aquest àmbit"
+
+#: cp/name-lookup.c:2250
+msgid "using declaration `%D' introduced ambiguous type `%T'"
+msgstr "l'ús de la declaració \"%D\" va introduir el tipus ambigu \"%T\""
+
+#. Definition isn't the kind we were looking for.
+#: cp/name-lookup.c:2412 cp/name-lookup.c:2431
+msgid "`%#D' redeclared as %C"
+msgstr "\"%#D\" redeclarat com %C"
+
+#: cp/name-lookup.c:2804
+msgid "`%D' has the same name as the class in which it is declared"
+msgstr ""
+
+#: cp/name-lookup.c:2891
+msgid "using-declaration for non-member at class scope"
+msgstr "declaració d'ús per a un no membre en l'àmbit de la classe"
+
+#: cp/name-lookup.c:2898
+#, fuzzy
+msgid "using-declaration cannot name destructor"
+msgstr "declaració d'ús per al destructor"
+
+#: cp/name-lookup.c:2994
+msgid "declaration of `%D' not in a namespace surrounding `%D'"
+msgstr "la declaració de \"%D\" no està en un espai de noms al voltant de \"%D\""
+
+#: cp/name-lookup.c:3034
+msgid "`%D' should have been declared inside `%D'"
+msgstr "\"%D\" deuria ser declarat dintre de \"%D\""
+
+#: cp/name-lookup.c:3098
+msgid "namespace alias `%D' not allowed here, assuming `%D'"
+msgstr "no es permet aquí l'alies de l'espai de noms \"%D\", assumint que és \"%D\""
+
+#. The parser did not find it, so it's not there.
+#: cp/name-lookup.c:3213
+msgid "unknown namespace `%D'"
+msgstr "espai de noms \"%D\" desconegut"
+
+#: cp/name-lookup.c:3363
+msgid "namespace `%T' undeclared"
+msgstr "espai de noms \"%T\" sense declarar"
+
+#: cp/name-lookup.c:3396
+msgid "strong using only meaningful at namespace scope"
+msgstr ""
+
+#: cp/name-lookup.c:3403
+#, fuzzy
+msgid "`%D' attribute directive ignored"
+msgstr "s'ignora la directiva d'atribut \"%s\""
+
+#: cp/name-lookup.c:3536
+msgid "use of `%D' is ambiguous"
+msgstr "l'ús de \"%D\" és ambigu"
+
+#: cp/name-lookup.c:3537
+msgid " first declared as `%#D' here"
+msgstr " declarat inicialment com \"%#D\" aquí"
+
+#: cp/name-lookup.c:3540
+msgid " also declared as `%#D' here"
+msgstr " també declarat com \"%#D\" aquí"
+
+#: cp/name-lookup.c:3555
+msgid "`%D' denotes an ambiguous type"
+msgstr "\"%D\" denota un tipus ambigu"
+
+#: cp/name-lookup.c:3556
+#, fuzzy
+msgid "%J first type here"
+msgstr " primer tipus aquí"
+
+#: cp/name-lookup.c:3557
+#, fuzzy
+msgid "%J other type here"
+msgstr " altre tipus aquí"
+
+#. This happens for A::B where B is a template, and there are no
+#. template arguments.
+#: cp/name-lookup.c:3622 cp/typeck.c:1769
+msgid "invalid use of `%D'"
+msgstr "ús invàlid de \"%D\""
+
+#: cp/name-lookup.c:3663
+msgid "`%D::%D' is not a template"
+msgstr "\"%D::%D\" no és un patró"
+
+#: cp/name-lookup.c:3680
+msgid "`%D' undeclared in namespace `%D'"
+msgstr "\"%D\" no declarat en l'espai de noms \"%D\""
+
+#: cp/name-lookup.c:4141
+msgid "`%D' is not a function,"
+msgstr "\"%D\" no és una funció,"
+
+#: cp/name-lookup.c:4142
+msgid " conflict with `%D'"
+msgstr " té conflicte amb \"%D\""
+
+#: cp/name-lookup.c:4882
+msgid "XXX entering pop_everything ()\n"
+msgstr ""
+
+#: cp/name-lookup.c:4891
+msgid "XXX leaving pop_everything ()\n"
+msgstr ""
+
+#: cp/parser.c:609
+#, fuzzy
+msgid "invalid token"
+msgstr "codi invàlid"
+
+#: cp/parser.c:1806
+#, fuzzy
+msgid "`%D::%D' has not been declared"
+msgstr "\"%#D\" no pot ser declarat"
+
+#: cp/parser.c:1809 cp/semantics.c:2308
+#, fuzzy
+msgid "`::%D' has not been declared"
+msgstr "\"%#D\" no pot ser declarat"
+
+#: cp/parser.c:1811
+#, fuzzy
+msgid "`%D' has not been declared"
+msgstr "\"%#D\" no pot ser declarat"
+
+#: cp/parser.c:1814
+msgid "`%D::%D' %s"
+msgstr ""
+
+#: cp/parser.c:1816
+#, fuzzy
+msgid "`::%D' %s"
+msgstr "accés \"%D\""
+
+#: cp/parser.c:1818
+#, fuzzy
+msgid "`%D' %s"
+msgstr "accés \"%D\""
+
+#: cp/parser.c:1870
+#, fuzzy
+msgid "new types may not be defined in a return type"
+msgstr "new no pot ser aplicat a un tipus de referència"
+
+#: cp/parser.c:1888 cp/pt.c:4196
+msgid "`%T' is not a template"
+msgstr "\"%T\" no és un patró"
+
+#: cp/parser.c:1890
+#, fuzzy, c-format
+msgid "`%s' is not a template"
+msgstr "\"%T\" no és un patró"
+
+#: cp/parser.c:1892
+#, fuzzy
+msgid "invalid template-id"
+msgstr "rotació de insn invàlida"
+
+#: cp/parser.c:1933
+#, fuzzy, c-format
+msgid "%s cannot appear in a constant-expression"
+msgstr "desbordament en la constant implícita"
+
+#. Issue an error message.
+#: cp/parser.c:1964
+#, fuzzy, c-format
+msgid "`%s' does not name a type"
+msgstr "\"%T\" no és un tipus de classe"
+
+#: cp/parser.c:1995
+#, fuzzy
+msgid "(perhaps `typename %T::%s' was intended)"
+msgstr " (usi \"typename %T::%D\" si això és el que volia)"
+
+#: cp/parser.c:2417
+msgid "ISO C++ forbids braced-groups within expressions"
+msgstr "ISO C++ prohibeix grups de parèntesis dintre de les expressions"
+
+#: cp/parser.c:2426
+#, fuzzy
+msgid "statement-expressions are allowed only inside functions"
+msgstr "un grup de claus dintre d'una expressió només es permet dintre d'una funció"
+
+#: cp/parser.c:2477
+#, fuzzy
+msgid "`this' may not be used in this context"
+msgstr "\"%D\" no es va declarar en aquest àmbit"
+
+#: cp/parser.c:2621
+#, fuzzy
+msgid "local variable `%D' may not appear in this context"
+msgstr "\"%D\" no es va declarar en aquest àmbit"
+
+#: cp/parser.c:2986
+#, fuzzy
+msgid "typedef-name `%D' used as destructor declarator"
+msgstr "l'identificador de patró \"%D\" s'usa com un declarador"
+
+#: cp/parser.c:3635
+#, fuzzy
+msgid "ISO C++ forbids compound-literals"
+msgstr "ISO C++ prohibeix literals composats"
+
+#: cp/parser.c:4456
+msgid "array bound forbidden after parenthesized type-id"
+msgstr ""
+
+#: cp/parser.c:4457
+msgid "try removing the parentheses around the type-id"
+msgstr ""
+
+#: cp/parser.c:4619
+#, fuzzy
+msgid "expression in new-declarator must have integral or enumeration type"
+msgstr "la grandària de la matriu nova deu tenir un tipus integral"
+
+#: cp/parser.c:4800
+msgid "use of old-style cast"
+msgstr "ús de la conversió d'estil antic"
+
+#: cp/parser.c:5545
+#, c-format
+msgid "case label `%E' not within a switch statement"
+msgstr "l'etiqueta casi \"%E\" no es troba dintre d'una declaració switch"
+
+#: cp/parser.c:6087
+msgid "ISO C++ forbids computed gotos"
+msgstr "ISO C++ prohibeix gotos calculats"
+
+#: cp/parser.c:6207
+msgid "extra `;'"
+msgstr ""
+
+#: cp/parser.c:6502
+msgid "mixing declarations and function-definitions is forbidden"
+msgstr ""
+
+#: cp/parser.c:6640
+#, fuzzy
+msgid "duplicate `friend'"
+msgstr "\"%s\" duplicat"
+
+#: cp/parser.c:6789
+#, fuzzy
+msgid "class definition may not be declared a friend"
+msgstr "la funció \"%D\" no pot ser declarada friend"
+
+#: cp/parser.c:7104
+msgid "only constructors take base initializers"
+msgstr ""
+
+#: cp/parser.c:7155
+#, fuzzy
+msgid "anachronistic old-style base class initializer"
+msgstr "inicialitzador de classe base d'estil antic anacrònic"
+
+#. Warn that we do not support `export'.
+#: cp/parser.c:7548
+msgid "keyword `export' not implemented, and will be ignored"
+msgstr "la paraula clau \"export\" no està implementada, i serà ignorada"
+
+#. Otherwise, emit an error about the invalid digraph, but continue
+#. parsing because we got our argument list.
+#: cp/parser.c:7908
+#, fuzzy
+msgid "`<::' cannot begin a template-argument list"
+msgstr "l'objecte \"%E\" no es pot usar com un argument de patró"
+
+#: cp/parser.c:7909
+msgid "`<:' is an alternate spelling for `['. Insert whitespace between `<' and `::'"
+msgstr ""
+
+#: cp/parser.c:7916
+msgid "(if you use `-fpermissive' G++ will accept your code)"
+msgstr ""
+
+#. Explain what went wrong.
+#: cp/parser.c:8088
+#, fuzzy
+msgid "non-template `%D' used as template"
+msgstr "s'usa un no-patró com patró"
+
+#: cp/parser.c:8089
+#, fuzzy
+msgid "(use `%T::template %D' to indicate that it is a template)"
+msgstr "identificador de patró \"%D\" en la declaració del patró primari"
+
+#: cp/parser.c:9026
+msgid "using `typename' outside of template"
+msgstr "usant \"typename\" fora de la plantilla"
+
+#: cp/parser.c:9148
+#, fuzzy
+msgid "expected type-name"
+msgstr "operant inesperat"
+
+#: cp/parser.c:9207
+#, fuzzy
+msgid "type attributes are honored only at type definition"
+msgstr "l'atribut \"%s\" sol es pot aplicar a definicions de classe"
+
+#. [namespace.udecl]
+#.
+#. A using declaration shall not name a template-id.
+#: cp/parser.c:9590
+#, fuzzy
+msgid "a template-id may not appear in a using-declaration"
+msgstr "no es permet l'espai de noms \"%D\" en la declaració d'ús"
+
+#: cp/parser.c:9917
+msgid "an asm-specification is not allowed on a function-definition"
+msgstr ""
+
+#: cp/parser.c:9919
+#, fuzzy
+msgid "attributes are not allowed on a function-definition"
+msgstr "la variable de registre global segueix a una definició de funció"
+
+#: cp/parser.c:10052
+#, fuzzy
+msgid "attributes after parenthesized initializer ignored"
+msgstr "atributs en el declarador de parametres de matriu ignorats"
+
+#: cp/parser.c:11254
+#, fuzzy
+msgid "file ends in default argument"
+msgstr "%Hlectura de final de fitxer dintre de l'argument per defecte"
+
+#: cp/parser.c:11310
+#, fuzzy
+msgid "deprecated use of default argument for parameter of non-function"
+msgstr "argument per omissió donat per al paràmetre %d de \"%#D\""
+
+#: cp/parser.c:11313
+#, fuzzy
+msgid "default arguments are only permitted for function parameters"
+msgstr "argument per omissió donat per al paràmetre %d de \"%#D\""
+
+#: cp/parser.c:12043
+msgid "declaration of `%D' in `%D' which does not enclose `%D'"
+msgstr "declaració de \"%D\" en \"%D\" la qual no inclou a \"%D\""
+
+#: cp/parser.c:12056
+#, fuzzy
+msgid "extra qualification ignored"
+msgstr "s'ignora la qualificació extra \"%T::\" en el membre \"%D\""
+
+#: cp/parser.c:12067
+#, fuzzy
+msgid "an explicit specialization must be preceded by 'template <>'"
+msgstr "especialització explícita no precedida per \"template <>\""
+
+#: cp/parser.c:12350
+msgid "extra semicolon"
+msgstr ""
+
+#: cp/parser.c:12368
+msgid "a class-key must be used when declaring a friend"
+msgstr ""
+
+#: cp/parser.c:12399
+#, fuzzy
+msgid "friend declaration does not name a class or function"
+msgstr "la declaració friend no està en una definició de classe"
+
+#: cp/parser.c:12570
+msgid "pure-specifier on function-definition"
+msgstr ""
+
+#: cp/parser.c:12843
+#, fuzzy
+msgid "keyword `typename' not allowed outside of templates"
+msgstr "usant \"typename\" fora de la plantilla"
+
+#: cp/parser.c:12845
+msgid "keyword `typename' not allowed in this context (the base class is implicitly a type)"
+msgstr ""
+
+#: cp/parser.c:13665
+#, fuzzy
+msgid "reference to `%D' is ambiguous"
+msgstr "l'ús de \"%D\" és ambigu"
+
+#: cp/parser.c:13839
+#, fuzzy
+msgid "too few template-parameter-lists"
+msgstr "molt poques llistes de paràmetres de patró en la declaració de \"%D\""
+
+#. Otherwise, there are too many template parameter lists. We have
+#. something like:
+#.
+#. template <class T> template <class U> void S::f();
+#: cp/parser.c:13854
+#, fuzzy
+msgid "too many template-parameter-lists"
+msgstr "massa llistes de paràmetres de patró en la declaració de \"%D\""
+
+#. If begin_function_definition didn't like the definition, skip
+#. the entire function.
+#: cp/parser.c:14146
+#, fuzzy
+msgid "invalid function declaration"
+msgstr "declarador invàlid"
+
+#. Issue an error message.
+#: cp/parser.c:14183
+#, fuzzy
+msgid "named return values are no longer supported"
+msgstr "--driver ja no té suport"
+
+#: cp/parser.c:14522
+#, fuzzy
+msgid "`>>' should be `> >' within a nested template argument list"
+msgstr "\">>\" deu ser \"> >\" en el nom de classe del patró"
+
+#. If this is not a nested template argument list, the '>>' is
+#. a typo for '>'. Emit an error message and continue.
+#: cp/parser.c:14530
+msgid "spurious `>>', use `>' to terminate a template argument list"
+msgstr ""
+
+#: cp/parser.c:14535
+#, fuzzy
+msgid "missing `>' to terminate the template argument list"
+msgstr "falta parèntesi dret en la llista de paràmetres de macro"
+
+#: cp/parser.c:15023
+msgid "`%s' tag used in naming `%#T'"
+msgstr "es va usar la marca \"%s\" al nomenar a\"%#T\""
+
+#: cp/parser.c:15043
+#, fuzzy
+msgid "%D redeclared with different access"
+msgstr "\"%#D\" redeclarat com un tipus diferent de símbol"
+
+#: cp/parser.c:15060
+msgid "`template' (as a disambiguator) is only allowed within templates"
+msgstr ""
+
+#: cp/pt.c:243
+msgid "data member `%D' cannot be a member template"
+msgstr "les dades membres \"%D\" no poden ser un patró membre"
+
+#: cp/pt.c:255
+msgid "invalid member template declaration `%D'"
+msgstr "declaració del patró membre \"%D\" invàlida"
+
+#: cp/pt.c:637
+msgid "explicit specialization in non-namespace scope `%D'"
+msgstr "especialització explícita en l'àmbit \"%D\" que no és espai de noms"
+
+#: cp/pt.c:649
+msgid "enclosing class templates are not explicitly specialized"
+msgstr "les patrons de classe contingudes no són especialitzades explícitament"
+
+#: cp/pt.c:739 cp/pt.c:780
+msgid "specializing `%#T' in different namespace"
+msgstr "especialitzant \"%#T\" en diferents espais de noms"
+
+#: cp/pt.c:740 cp/pt.c:781
+msgid " from definition of `%#D'"
+msgstr " de la definició de \"%#D\""
+
+#: cp/pt.c:748
+msgid "specialization of `%T' after instantiation"
+msgstr "especialització de \"%T\" després de la instanciació"
+
+#: cp/pt.c:795
+msgid "specialization `%T' after instantiation `%T'"
+msgstr "especialització de \"%T\" després de la instanciació \"%T\""
+
+#: cp/pt.c:807
+msgid "explicit specialization of non-template `%T'"
+msgstr "especialització explícita de \"%T\" que no és patró"
+
+#: cp/pt.c:1067
+msgid "specialization of %D after instantiation"
+msgstr "especialització de %D després de la instanciació"
+
+#: cp/pt.c:1192
+msgid "%s %+#D"
+msgstr "%s %+#D"
+
+#: cp/pt.c:1241
+msgid "`%D' is not a function template"
+msgstr "\"%D\" no és un patró de funció"
+
+#: cp/pt.c:1389
+msgid "template-id `%D' for `%+D' does not match any template declaration"
+msgstr "l'idenfificador de patró \"%D\" per a \"%+D\" no coincideix amb cap declaració de patró"
+
+#: cp/pt.c:1397
+msgid "ambiguous template specialization `%D' for `%+D'"
+msgstr "especialització de patró ambigua \"%D\" per a \"%+D\""
+
+#. This case handles bogus declarations like template <>
+#. template <class T> void f<int>();
+#: cp/pt.c:1620 cp/pt.c:1694
+msgid "template-id `%D' in declaration of primary template"
+msgstr "identificador de patró \"%D\" en la declaració del patró primari"
+
+#: cp/pt.c:1633
+msgid "template parameter list used in explicit instantiation"
+msgstr "es va usar una llista de paràmetres de patró en una instanciació explícita"
+
+#: cp/pt.c:1639
+msgid "definition provided for explicit instantiation"
+msgstr "es proveeix una definició per a instanciació explícita"
+
+#: cp/pt.c:1645
+msgid "too many template parameter lists in declaration of `%D'"
+msgstr "massa llistes de paràmetres de patró en la declaració de \"%D\""
+
+#: cp/pt.c:1661
+msgid "too few template parameter lists in declaration of `%D'"
+msgstr "molt poques llistes de paràmetres de patró en la declaració de \"%D\""
+
+#: cp/pt.c:1678
+msgid "explicit specialization not preceded by `template <>'"
+msgstr "especialització explícita no precedida per \"template <>\""
+
+#: cp/pt.c:1691
+msgid "partial specialization `%D' of function template"
+msgstr "especialització parcial \"%D\" del patró de funció"
+
+#: cp/pt.c:1723
+msgid "default argument specified in explicit specialization"
+msgstr "es va especificar un argument per omissió en l'especialització explícita"
+
+#: cp/pt.c:1727
+msgid "template specialization with C linkage"
+msgstr "especialització de patró amb enllaç C"
+
+#. From [temp.expl.spec]:
+#.
+#. If such an explicit specialization for the member
+#. of a class template names an implicitly-declared
+#. special member function (clause _special_), the
+#. program is ill-formed.
+#.
+#. Similar language is found in [temp.explicit].
+#: cp/pt.c:1811
+msgid "specialization of implicitly-declared special member function"
+msgstr "especialització de la funció membre especial declarada implícitament"
+
+#: cp/pt.c:1855
+msgid "no member function `%D' declared in `%T'"
+msgstr "la funció no membre \"%D\" es va declarar en \"%T\""
+
+#. There are two many template parameter lists.
+#: cp/pt.c:2005
+msgid "too many template parameter lists in declaration of `%T'"
+msgstr "massa llistes de paràmetres de patró en la declaració de \"%T\""
+
+#: cp/pt.c:2098
+msgid " shadows template parm `%#D'"
+msgstr " enfosquen el paràmetre de patró \"%#D\""
+
+#: cp/pt.c:2495
+msgid "template parameters not used in partial specialization:"
+msgstr "no s'usen els paràmetres de patró en l'especialització parcial:"
+
+#: cp/pt.c:2499
+msgid " `%D'"
+msgstr " \"%D\""
+
+#: cp/pt.c:2511
+msgid "partial specialization `%T' does not specialize any template arguments"
+msgstr "l'especialització parcial \"%T\" no especialitza cap argument de patró"
+
+#: cp/pt.c:2536
+#, c-format
+msgid "template argument `%E' involves template parameter(s)"
+msgstr "l'argument de patró \"%E\" involucra el(s) paràmetre(s) de patró"
+
+#: cp/pt.c:2580
+msgid "type `%T' of template argument `%E' depends on template parameter(s)"
+msgstr "el tipus \"%T\" de l'argument de patró \"%E\" depèn del(s) paràmetre(s) de patró"
+
+#: cp/pt.c:2665
+msgid "no default argument for `%D'"
+msgstr "no hi ha un argument per omissió per a \"%D\""
+
+#: cp/pt.c:2814
+msgid "template with C linkage"
+msgstr "patró amb enllaç C"
+
+#: cp/pt.c:2817
+msgid "template class without a name"
+msgstr "classe de patró sense nom"
+
+#. [temp.mem]
+#.
+#. A destructor shall not be a member template.
+#: cp/pt.c:2824
+#, fuzzy
+msgid "destructor `%D' declared as member template"
+msgstr "les dades membres \"%D\" no poden ser un patró membre"
+
+#: cp/pt.c:2904
+msgid "`%D' does not declare a template type"
+msgstr "\"%D\" no declara un tipus de patró"
+
+#: cp/pt.c:2910
+msgid "template definition of non-template `%#D'"
+msgstr "definició de patró de \"%#D\" que no és patró"
+
+#: cp/pt.c:2951
+msgid "expected %d levels of template parms for `%#D', got %d"
+msgstr "s'esperaven %d nivells de paràmetres de patró per a \"%#D\", es van obtenir %d"
+
+#: cp/pt.c:2963
+msgid "got %d template parameters for `%#D'"
+msgstr "es van obtenir %d paràmetres de patró per a \"%#D\""
+
+#: cp/pt.c:2966
+msgid "got %d template parameters for `%#T'"
+msgstr "es van obtenir %d paràmetres de patró per a \"%#T\""
+
+#: cp/pt.c:2968
+#, c-format
+msgid " but %d required"
+msgstr " però es requereixen %d"
+
+#: cp/pt.c:3053
+msgid "`%T' is not a template type"
+msgstr "\"%T\" no és un tipus patró"
+
+#: cp/pt.c:3069
+msgid "previous declaration `%D'"
+msgstr "declaració prèvia de \"%D\""
+
+#: cp/pt.c:3070
+#, c-format
+msgid "used %d template parameter%s instead of %d"
+msgstr "es van usar %d paràmetre%s de patró en lloc de %d"
+
+#: cp/pt.c:3086
+msgid "template parameter `%#D'"
+msgstr "paràmetre de patró \"%#D\""
+
+#: cp/pt.c:3087
+msgid "redeclared here as `%#D'"
+msgstr "redeclarat aquí com \"%#D\""
+
+#. We have in [temp.param]:
+#.
+#. A template-parameter may not be given default arguments
+#. by two different declarations in the same scope.
+#: cp/pt.c:3097
+msgid "redefinition of default argument for `%#D'"
+msgstr "redefinició de l'argument per omissió per a \"%#D\""
+
+#: cp/pt.c:3098
+#, fuzzy
+msgid "%J original definition appeared here"
+msgstr " la definició original apareix aquí"
+
+#: cp/pt.c:3246
+#, c-format
+msgid "`%E' is not a valid template argument"
+msgstr "\"%E\" no és un argument de patró vàlid"
+
+#: cp/pt.c:3250
+msgid "it must be the address of a function with external linkage"
+msgstr "deu ser l'adreça d'una funció amb enllaç extern"
+
+#: cp/pt.c:3252
+msgid "it must be the address of an object with external linkage"
+msgstr "deu ser l'adreça d'un objecte amb enllaç extern"
+
+#: cp/pt.c:3255
+msgid "it must be a pointer-to-member of the form `&X::Y'"
+msgstr "deu ser un punter-a-membre de la forma \"&X::I\""
+
+#: cp/pt.c:3266
+#, c-format
+msgid "string literal %E is not a valid template argument because it is the address of an object with static linkage"
+msgstr "la cadena literal %E no és un argument vàlid de patró perquè és l'adreça d'un objecte amb enllaç estàtic"
+
+#: cp/pt.c:3281
+#, c-format
+msgid "address of non-extern `%E' cannot be used as template argument"
+msgstr "no es pot usar l'adreça de \"%E\" que no és extern com un argument de patró"
+
+#: cp/pt.c:3290
+#, c-format
+msgid "non-constant `%E' cannot be used as template argument"
+msgstr "\"%E\" que no és constant no es pot usar com un argument de patró"
+
+#: cp/pt.c:3298
+#, fuzzy
+msgid "type '%T' cannot be used as a value for a non-type template-parameter"
+msgstr "l'objecte \"%E\" no es pot usar com un argument de patró"
+
+#: cp/pt.c:3301
+#, fuzzy
+msgid "invalid use of '%D' as a non-type template-argument"
+msgstr "ús invàlid de \"%s\" en punter a membre"
+
+#: cp/pt.c:3303
+#, fuzzy, c-format
+msgid "invalid use of '%E' as a non-type template-argument"
+msgstr "ús invàlid de \"%s\" en punter a membre"
+
+#: cp/pt.c:3668
+#, c-format
+msgid "to refer to a type member of a template parameter, use `typename %E'"
+msgstr "per a fer referència a un tipus membre d'un paràmetre de patró, usi \"typename %E\""
+
+#: cp/pt.c:3681 cp/pt.c:3699 cp/pt.c:3738
+msgid "type/value mismatch at argument %d in template parameter list for `%D'"
+msgstr "no coincideix el tipus/valor en l'argument %d en la llista de paràmetres de patró per a \"%D\""
+
+#: cp/pt.c:3684
+msgid " expected a constant of type `%T', got `%T'"
+msgstr " s'esperava una constant de tipus \"%T\", es va obtenir \"%T\""
+
+#: cp/pt.c:3688
+#, fuzzy, c-format
+msgid " expected a class template, got `%E'"
+msgstr " s'esperava un patró de classe, es va obtenir \"%T\""
+
+#: cp/pt.c:3690
+#, c-format
+msgid " expected a type, got `%E'"
+msgstr " s'esperava un tipus, es va obtenir \"%E\""
+
+#: cp/pt.c:3702
+msgid " expected a type, got `%T'"
+msgstr " s'esperava un tipus, es va obtenir \"%T\""
+
+#: cp/pt.c:3704
+msgid " expected a class template, got `%T'"
+msgstr " s'esperava un patró de classe, es va obtenir \"%T\""
+
+#: cp/pt.c:3740
+msgid " expected a template of type `%D', got `%D'"
+msgstr " s'esperava un patró de tipus \"%D\", es va obtenir \"%D\""
+
+#: cp/pt.c:3775
+msgid "could not convert template argument `%E' to `%T'"
+msgstr "no es pot convertir l'argument de patró \"%E\" a \"%T\""
+
+#: cp/pt.c:3815
+#, c-format
+msgid "wrong number of template arguments (%d, should be %d)"
+msgstr "nombre erroni d'arguments de patró (%d, deuria ser %d)"
+
+#: cp/pt.c:3819
+msgid "provided for `%D'"
+msgstr "proveït per \"%D\""
+
+#: cp/pt.c:3847
+#, c-format
+msgid "template argument %d is invalid"
+msgstr "l'argument de patró %d és invàlid"
+
+#: cp/pt.c:4068
+msgid "non-template used as template"
+msgstr "s'usa un no-patró com patró"
+
+#: cp/pt.c:4208
+msgid "non-template type `%T' used as a template"
+msgstr "s'usa el tipus \"%T\" que és no-patró com patró"
+
+#: cp/pt.c:4210
+msgid "for template declaration `%D'"
+msgstr "per a la declaració de patró \"%D\""
+
+#: cp/pt.c:4857
+msgid "template instantiation depth exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum) instantiating `%D'"
+msgstr "la profunditat d'instanciació del patró excedeix el màxim de %d (usi -ftemplate-depth-NN per a incrementar el màxim) al instanciar \"%D\""
+
+#: cp/pt.c:5296
+msgid "ambiguous class template instantiation for `%#T'"
+msgstr "instanciació de patró classe ambigua per a \"%#T\""
+
+#: cp/pt.c:5302
+msgid "%s %+#T"
+msgstr "%s %+#T"
+
+#: cp/pt.c:6307 cp/pt.c:6427
+msgid "instantiation of `%D' as type `%T'"
+msgstr "instanciació de \"%D\" com tipus \"%T\""
+
+#: cp/pt.c:6469
+msgid "invalid parameter type `%T'"
+msgstr "tipus de paràmetre \"%T\" invàlid"
+
+#: cp/pt.c:6471
+msgid "in declaration `%D'"
+msgstr "en la declaració \"%D\""
+
+#: cp/pt.c:6545
+msgid "creating pointer to member function of non-class type `%T'"
+msgstr "creant un punter a funció membre del tipus \"%T\" que no és classe"
+
+#: cp/pt.c:6684
+msgid "creating array with size zero"
+msgstr "creant la matriu amb grandària zero"
+
+#: cp/pt.c:6698
+#, c-format
+msgid "creating array with size zero (`%E')"
+msgstr "creant la matriu amb grandària zero (\"%E\")"
+
+#: cp/pt.c:6937
+msgid "forming reference to void"
+msgstr "formant la referència a void"
+
+#: cp/pt.c:6939
+msgid "forming %s to reference type `%T'"
+msgstr "formant %s per a referenciar al tipus \"%T\""
+
+#: cp/pt.c:6976
+msgid "creating pointer to member of non-class type `%T'"
+msgstr "creant un punter al membre del tipus \"%T\" que no és classe"
+
+#: cp/pt.c:6982
+msgid "creating pointer to member reference type `%T'"
+msgstr "creant un punter al membre de referència de tipus \"%T\""
+
+#: cp/pt.c:7068
+msgid "creating array of `%T'"
+msgstr "creant la matriu de \"%T\""
+
+#: cp/pt.c:7074
+#, fuzzy
+msgid "creating array of `%T', which is an abstract class type"
+msgstr "inicialitzador sense nom per a \"%T\", el qual no té una classe base"
+
+#: cp/pt.c:7118
+msgid "`%T' is not a class, struct, or union type"
+msgstr "\"%T\" no és de tipus classe, struct o union"
+
+#: cp/pt.c:7231
+#, c-format
+msgid "use of `%s' in template"
+msgstr "ús de \"%s\" en el patró"
+
+#: cp/pt.c:7344
+#, fuzzy, c-format
+msgid "dependent-name `%E' is parsed as a non-type, but instantiation yields a type"
+msgstr "s'usa \"%D\" com un tipus, però no està definit com un tipus."
+
+#: cp/pt.c:7346
+#, fuzzy, c-format
+msgid "say `typename %E' if a type is meant"
+msgstr " (usi \"typename %T::%D\" si això és el que volia)"
+
+#: cp/pt.c:8609
+#, fuzzy
+msgid "`%T' uses anonymous type"
+msgstr "l'argument de patró \"%T\" usa un tipus anònim"
+
+#: cp/pt.c:8611
+#, fuzzy
+msgid "`%T' uses local type `%T'"
+msgstr "l'argument de patró \"%T\" usa el tipus local \"%T\""
+
+#: cp/pt.c:8619
+#, fuzzy
+msgid "`%T' is a variably modified type"
+msgstr "l'argument de patró \"%T\" és un tipus modificat variablement"
+
+#: cp/pt.c:8630
+#, fuzzy, c-format
+msgid "integral expression `%E' is not constant"
+msgstr "la grandària d'emmagatzematge de \"%D\" no és constant"
+
+#: cp/pt.c:8635
+msgid " trying to instantiate `%D'"
+msgstr " tractant d'instanciar \"%D\""
+
+#: cp/pt.c:9148
+msgid "incomplete type unification"
+msgstr "unificació de tipus incomplet"
+
+#: cp/pt.c:10095
+#, c-format
+msgid "use of `%s' in template type unification"
+msgstr "ús de \"%s\" en la unificació de tipus de patró"
+
+#: cp/pt.c:10529 cp/pt.c:10601
+msgid "explicit instantiation of non-template `%#D'"
+msgstr "instanciació explícita de \"%#D\" que no és patró"
+
+#: cp/pt.c:10545 cp/pt.c:10596
+msgid "no matching template for `%D' found"
+msgstr "no es troba una patró coincident per a \"%D\""
+
+#: cp/pt.c:10551
+msgid "explicit instantiation of `%#D'"
+msgstr "instanciació explícita de \"%#D\""
+
+#: cp/pt.c:10588
+msgid "duplicate explicit instantiation of `%#D'"
+msgstr "instanciació explícita duplicada de \"%#D\""
+
+#: cp/pt.c:10610
+msgid "ISO C++ forbids the use of `extern' on explicit instantiations"
+msgstr "ISO C++ prohibeix l'ús de \"extern\" en instanciacions explícites"
+
+#: cp/pt.c:10614 cp/pt.c:10695
+msgid "storage class `%D' applied to template instantiation"
+msgstr "classe d'emmagatzematge \"%D\" aplicada a la instanciació d'un patró"
+
+#: cp/pt.c:10667
+msgid "explicit instantiation of non-template type `%T'"
+msgstr "instanciació explícita del tipus \"%T\" del tipus no-patró"
+
+#: cp/pt.c:10676
+msgid "explicit instantiation of `%#T' before definition of template"
+msgstr "instanciació explícita de \"%#T\" abans de la definició del patró"
+
+#: cp/pt.c:10684
+#, c-format
+msgid "ISO C++ forbids the use of `%s' on explicit instantiations"
+msgstr "ISO C++ prohibeix l'ús de \"%s\" en les instanciacions explícites"
+
+#: cp/pt.c:10728
+msgid "duplicate explicit instantiation of `%#T'"
+msgstr "instanciació explícita duplicada de \"%#T\""
+
+#: cp/pt.c:11109
+msgid "explicit instantiation of `%D' but no definition available"
+msgstr "instanciació explícita de \"%D\" però no hi ha una definició disponible"
+
+#: cp/pt.c:11543
+msgid "`%#T' is not a valid type for a template constant parameter"
+msgstr "\"%#T\" no és un tipus vàlid per a un paràmetre constant de patró"
+
+#: cp/repo.c:259
+msgid "-frepo must be used with -c"
+msgstr "-frepo deu ser usat amb -c"
+
+#: cp/repo.c:346
+#, c-format
+msgid "mysterious repository information in %s"
+msgstr "informació de \"repository\" misteriosa en %s"
+
+#: cp/repo.c:361
+#, c-format
+msgid "can't create repository information file `%s'"
+msgstr "no es pot crear el fitxer d'informació de \"repository\" \"%s\""
+
+#: cp/rtti.c:248
+msgid "cannot use typeid with -fno-rtti"
+msgstr "no es pot usar typeid sense -fno-rtti"
+
+#: cp/rtti.c:254
+msgid "must #include <typeinfo> before using typeid"
+msgstr "deu fer #include <typeinfo> abans d'usar typeid"
+
+#: cp/rtti.c:326
+msgid "cannot create type information for type `%T' because its size is variable"
+msgstr "no es pot crear la informació de tipus per al tipus \"%T\" perquè la seva grandària és variable"
+
+#: cp/rtti.c:580 cp/rtti.c:594
+msgid "dynamic_cast of `%#D' to `%#T' can never succeed"
+msgstr "dynamic_cast de \"%#D\" a \"%#T\" mai podrà tenir èxit"
+
+#: cp/rtti.c:674
+msgid "cannot dynamic_cast `%E' (of type `%#T') to type `%#T' (%s)"
+msgstr "no es pot fer dynamic_cast \"%E\" (de tipus \"%#T\") al tipus \"%#T\" (%s)"
+
+#: cp/search.c:311
+msgid "`%T' is an ambiguous base of `%T'"
+msgstr "\"%T\" és una base ambigua de \"%T\""
+
+#: cp/search.c:329
+msgid "`%T' is an inaccessible base of `%T'"
+msgstr "\"%T\" és una base inaccessible de \"%T\""
+
+#: cp/search.c:1767
+msgid "invalid covariant return type for `%#D'"
+msgstr "tipus de retorn covariant invàlid per a \"%#D\""
+
+#: cp/search.c:1768 cp/search.c:1774
+msgid " overriding `%#D'"
+msgstr " substituint \"%#D\""
+
+#: cp/search.c:1772
+msgid "conflicting return type specified for `%#D'"
+msgstr "tipus de devolució en conflicte especificats per a \"%#D\""
+
+#: cp/search.c:1786
+#, c-format
+msgid "looser throw specifier for `%#F'"
+msgstr "especificador thrown més flexible per a \"%#F\""
+
+#: cp/search.c:1787
+#, c-format
+msgid " overriding `%#F'"
+msgstr " substituint \"%#F\""
+
+#. A static member function cannot match an inherited
+#. virtual member function.
+#: cp/search.c:1877
+msgid "`%#D' cannot be declared"
+msgstr "\"%#D\" no pot ser declarat"
+
+#: cp/search.c:1878
+msgid " since `%#D' declared in base class"
+msgstr " ja que es va declarar \"%#D\" en la classe base"
+
+#: cp/search.c:1955
+msgid "`%#D' needs a final overrider"
+msgstr "\"%#D\" necessita un substituent final"
+
+#: cp/semantics.c:1092
+#, c-format
+msgid "type of asm operand `%E' could not be determined"
+msgstr "no es pot determinar el tipus de l'operant asm \"%E\""
+
+#: cp/semantics.c:1233
+msgid "invalid use of member `%D' in static member function"
+msgstr "ús invàlid del membre \"%D\" en la funció membre static"
+
+#: cp/semantics.c:1237 cp/semantics.c:1276
+msgid "from this location"
+msgstr ""
+
+#: cp/semantics.c:1275
+#, fuzzy
+msgid "object missing in reference to `%D'"
+msgstr "falta un objecte en \"%E\""
+
+#: cp/semantics.c:1721
+#, fuzzy
+msgid "arguments to destructor are not allowed"
+msgstr "l'argument per a l'atribut \"%s\" és més gran que %d"
+
+#: cp/semantics.c:1770
+msgid "`this' is unavailable for static member functions"
+msgstr "\"this\" no està disponible per a funcions membre static"
+
+#: cp/semantics.c:1776
+msgid "invalid use of `this' in non-member function"
+msgstr "ús invàlid de \"this\" en la funció no membre"
+
+#: cp/semantics.c:1778
+msgid "invalid use of `this' at top level"
+msgstr "ús invàlid de \"this\" en el nivell principal"
+
+#: cp/semantics.c:1802
+#, fuzzy
+msgid "invalid qualifying scope in pseudo-destructor name"
+msgstr "qualificadors invàlids en el tipus de funció no membre"
+
+#: cp/semantics.c:1822
+msgid "`%E' is not of type `%T'"
+msgstr "\"%E\" no és de tipus \"%T\""
+
+#: cp/semantics.c:1933
+msgid "template type parameters must use the keyword `class' or `typename'"
+msgstr "els paràmetres de tipus patró deu usar la paraula clau \"class\" o \"typename\""
+
+#: cp/semantics.c:1977
+#, fuzzy
+msgid "invalid use of type `%T' as a default value for a template template-parameter"
+msgstr "\"%#T\" no és un tipus vàlid per a un paràmetre constant de patró"
+
+#: cp/semantics.c:1980
+#, fuzzy
+msgid "invalid use of `%D' as a default value for a template template-parameter"
+msgstr "\"%#T\" no és un tipus vàlid per a un paràmetre constant de patró"
+
+#: cp/semantics.c:1984
+#, fuzzy
+msgid "invalid default argument for a template template parameter"
+msgstr "\"%#T\" no és un tipus vàlid per a un paràmetre constant de patró"
+
+#: cp/semantics.c:2019
+msgid "definition of `%#T' inside template parameter list"
+msgstr "definició de \"%#T\" dintre d'una llista de paràmetres de patró"
+
+#: cp/semantics.c:2030
+msgid "invalid definition of qualified type `%T'"
+msgstr "definició invàlida del tipus qualificat \"%T\""
+
+#: cp/semantics.c:2045
+msgid "previous definition of `%#T'"
+msgstr "definició prèvia de \"%#T\""
+
+#: cp/semantics.c:2249
+msgid "invalid base-class specification"
+msgstr "especificació de classe base invàlida"
+
+#: cp/semantics.c:2258
+msgid "base class `%T' has cv qualifiers"
+msgstr "la classe base \"%T\" té qualificadors cv"
+
+#: cp/semantics.c:2290
+msgid "multiple declarators in template declaration"
+msgstr "múltiples declaradors en una declaració de patró"
+
+#: cp/semantics.c:2301
+#, fuzzy
+msgid "incomplete type `%T' used in nested name specifier"
+msgstr "el tipus incomplet \"%T\" no es pot utilitzar per a nomenar un àmbit"
+
+#: cp/semantics.c:2303 cp/typeck.c:1612
+msgid "`%D' is not a member of `%T'"
+msgstr "\"%D\" no és un membre de \"%T\""
+
+#: cp/semantics.c:2306
+#, fuzzy
+msgid "`%D' is not a member of `%D'"
+msgstr "\"%D\" no és un membre de \"%T\""
+
+#: cp/semantics.c:2431
+msgid "template parameter `%D' of type `%T' is not allowed in an integral constant expression because it is not of integral or enumeration type"
+msgstr ""
+
+#: cp/semantics.c:2584
+#, fuzzy
+msgid "`%D' cannot appear in a constant-expression"
+msgstr "la grandària de la matriu \"%D\" no és una expressió constant integral"
+
+#: cp/semantics.c:2593
+msgid "use of namespace `%D' as expression"
+msgstr "ús de l'espai de noms \"%D\" com una expressió"
+
+#: cp/semantics.c:2598
+msgid "use of class template `%T' as expression"
+msgstr "ús de la plantilla de classe \"%T\" com una expressió"
+
+#. Ambiguous reference to base members.
+#: cp/semantics.c:2604
+msgid "request for member `%D' is ambiguous in multiple inheritance lattice"
+msgstr "la petició pel membre \"%D\" és ambigua en la xarxa d'herència múltiple"
+
+#: cp/semantics.c:2664
+#, c-format
+msgid "use of %s from containing function"
+msgstr "ús de %s des d'una funció contenidora"
+
+#: cp/semantics.c:2667
+msgid " `%#D' declared here"
+msgstr " \"%#D\" declarat aquí"
+
+#: cp/semantics.c:2718
+#, c-format
+msgid "type of `%E' is unknown"
+msgstr "el tipus de \"%E\" és desconegut"
+
+#: cp/tree.c:222
+#, c-format
+msgid "non-lvalue in %s"
+msgstr "non-lvalue dintre %s"
+
+#: cp/tree.c:539
+msgid "`%V' qualifiers cannot be applied to `%T'"
+msgstr "els qualificadors \"%V\" no es poden aplicar a \"%T\""
+
+#: cp/tree.c:1828
+#, c-format
+msgid "`%s' attribute can only be applied to Java class definitions"
+msgstr "l'atribut \"%s\" només es pot aplicar a definicions de classes Java"
+
+#: cp/tree.c:1857
+#, c-format
+msgid "`%s' attribute can only be applied to class definitions"
+msgstr "l'atribut \"%s\" sol es pot aplicar a definicions de classe"
+
+#: cp/tree.c:1863
+#, c-format
+msgid "`%s' is obsolete; g++ vtables are now COM-compatible by default"
+msgstr "\"%s\" és obsolet; les vtables de g++ ara són compatibles amb COM per omissió"
+
+#: cp/tree.c:1887
+msgid "requested init_priority is not an integer constant"
+msgstr "la init_priority sol·licitada no és una constant entera"
+
+#: cp/tree.c:1908
+#, c-format
+msgid "can only use `%s' attribute on file-scope definitions of objects of class type"
+msgstr "sol es pot usar l'atribut \"%s\" en definicions de rang de fitxer d'objectes de tipus class"
+
+#: cp/tree.c:1916
+msgid "requested init_priority is out of range"
+msgstr "la init_priority sol·licitada està fora de rang"
+
+#: cp/tree.c:1926
+msgid "requested init_priority is reserved for internal use"
+msgstr "la init_priority sol·licitada està reservada per a ús intern"
+
+#: cp/tree.c:1936
+#, c-format
+msgid "`%s' attribute is not supported on this platform"
+msgstr "l'atribut \"%s\" no té suport en aquesta plataforma"
+
+#: cp/tree.c:2531
+#, c-format
+msgid "lang_* check: failed in %s, at %s:%d"
+msgstr "revisió lang_*: va fallar en %s, en %s:%d"
+
+#: cp/typeck.c:437 cp/typeck.c:451 cp/typeck.c:543
+msgid "%s between distinct pointer types `%T' and `%T' lacks a cast"
+msgstr "%s entre diferents tipus de punter \"%T\" i \"%T\" manca d'una conversió"
+
+#: cp/typeck.c:513
+#, c-format
+msgid "ISO C++ forbids %s between pointer of type `void *' and pointer-to-function"
+msgstr "ISO C++ prohibeix %s entre punters de tipus \"void *\" i punters a funcions"
+
+#: cp/typeck.c:563
+#, fuzzy
+msgid "%s between distinct pointer-to-member types `%T' and `%T' lacks a cast"
+msgstr "%s entre diferents tipus de punter \"%T\" i \"%T\" manca d'una conversió"
+
+#: cp/typeck.c:1235
+#, c-format
+msgid "invalid application of `%s' to a member function"
+msgstr "aplicació invàlida de \"%s\" a una funció membre"
+
+#: cp/typeck.c:1268
+#, fuzzy, c-format
+msgid "invalid application of `%s' to a bit-field"
+msgstr "applicació invàlida de \"%s\" a un tipus void"
+
+#: cp/typeck.c:1273
+#, fuzzy, c-format
+msgid "ISO C++ forbids applying `%s' to an expression of function type"
+msgstr "ISO C++ prohibeix l'aplicació de \"sizeof\" a una expressió de tipus de funció"
+
+#: cp/typeck.c:1342
+#, fuzzy
+msgid "invalid use of non-static member function"
+msgstr "ús invàlid del membre \"%D\" en la funció membre static"
+
+#: cp/typeck.c:1471
+msgid "deprecated conversion from string constant to `%T'"
+msgstr "conversió obsoleta d'una constant de cadena a \"%T\""
+
+#: cp/typeck.c:1583 cp/typeck.c:1874
+msgid "request for member `%D' in `%E', which is of non-class type `%T'"
+msgstr "sol·licitud pel membre \"%D\" en \"%E\", el qual és del tipus no agregat \"%T\""
+
+#: cp/typeck.c:1610
+#, fuzzy, c-format
+msgid "invalid use of nonstatic data member '%E'"
+msgstr "ús invàlid del camp no static \"%D\""
+
+#: cp/typeck.c:1662 cp/typeck.c:1684
+msgid "invalid access to non-static data member `%D' of NULL object"
+msgstr "accés invàlid a dades del membre que no és static \"%D\" de l'objecte NULL"
+
+#: cp/typeck.c:1664 cp/typeck.c:1686
+msgid "(perhaps the `offsetof' macro was used incorrectly)"
+msgstr ""
+
+#: cp/typeck.c:1801
+msgid "the type being destroyed is `%T', but the destructor refers to `%T'"
+msgstr ""
+
+#: cp/typeck.c:1924
+msgid "`%D::%D' is not a member of `%T'"
+msgstr "\"%D::%D\" no és un membre de \"%T\""
+
+#: cp/typeck.c:1935
+msgid "`%T' is not a base of `%T'"
+msgstr "\"%T\" no és una base de \"%T\""
+
+#: cp/typeck.c:1954
+msgid "'%D' has no member named '%E'"
+msgstr "\"%D\" no té un membre cridat \"%E\""
+
+#: cp/typeck.c:1969
+msgid "`%D' is not a member template function"
+msgstr "\"%D\" no és una funció patró membre"
+
+#. A pointer to incomplete type (other than cv void) can be
+#. dereferenced [expr.unary.op]/1
+#: cp/typeck.c:2075
+msgid "`%T' is not a pointer-to-object type"
+msgstr "\"%T\" no és de tipus punter-a-objecte"
+
+#: cp/typeck.c:2100
+#, c-format
+msgid "invalid use of `%s' on pointer to member"
+msgstr "ús invàlid de \"%s\" en punter a membre"
+
+#: cp/typeck.c:2106
+msgid "invalid type argument"
+msgstr "argument de tipus invàlid"
+
+#: cp/typeck.c:2212
+msgid "ISO C++ forbids subscripting non-lvalue array"
+msgstr "ISO C++ prohibeix el subindici d'una matriu de l-valors"
+
+#: cp/typeck.c:2223
+msgid "subscripting array declared `register'"
+msgstr "es va declarar el subindici de la matriu com \"register\""
+
+#: cp/typeck.c:2306
+#, c-format
+msgid "object missing in use of `%E'"
+msgstr "falta un objecte en \"%E\""
+
+#: cp/typeck.c:2408
+msgid "ISO C++ forbids calling `::main' from within program"
+msgstr "ISO C++ prohibeix la cridada \"::main\" dintre del mateix programa"
+
+#: cp/typeck.c:2433
+#, c-format
+msgid "must use .* or ->* to call pointer-to-member function in `%E (...)'"
+msgstr "es deu usar .* o ->* en la cridada a la funció punter-a-membre en \"%E (...)\""
+
+#: cp/typeck.c:2446
+#, c-format
+msgid "`%E' cannot be used as a function"
+msgstr "no es pot usar \"%E\" com una funció"
+
+#: cp/typeck.c:2539
+msgid "too many arguments to %s `%+#D'"
+msgstr "massa arguments per a %s \"%+#D\""
+
+#: cp/typeck.c:2541 cp/typeck.c:2647
+msgid "at this point in file"
+msgstr "en aquest punt en el fitxer"
+
+#: cp/typeck.c:2578
+#, fuzzy
+msgid "parameter %P of `%D' has incomplete type `%T'"
+msgstr "el paràmetre \"%s\" té tipus de dada incompleta"
+
+#: cp/typeck.c:2581
+#, fuzzy
+msgid "parameter %P has incomplete type `%T'"
+msgstr "el paràmetre té tipus incomplet"
+
+#: cp/typeck.c:2645
+msgid "too few arguments to %s `%+#D'"
+msgstr "molt pocs arguments per a %s \"%+#D\""
+
+#: cp/typeck.c:2792 cp/typeck.c:2802
+msgid "assuming cast to type `%T' from overloaded function"
+msgstr "assumint la conversió al tipus \"%T\" des de la funció sobrecarregada"
+
+#: cp/typeck.c:2863
+#, c-format
+msgid "division by zero in `%E / 0'"
+msgstr "divisió per zero en \"%E / 0\""
+
+#: cp/typeck.c:2865
+#, c-format
+msgid "division by zero in `%E / 0.'"
+msgstr "divisió per zero en \"%E / 0.\""
+
+#: cp/typeck.c:2894
+#, c-format
+msgid "division by zero in `%E %% 0'"
+msgstr "divisió per zero en \"%E %% 0\""
+
+#: cp/typeck.c:2896
+#, c-format
+msgid "division by zero in `%E %% 0.'"
+msgstr "divisió per zero en \"%E %% 0.\""
+
+#: cp/typeck.c:2976
+#, c-format
+msgid "%s rotate count is negative"
+msgstr "el compte de rotació %s és negatiu"
+
+#: cp/typeck.c:2979
+#, c-format
+msgid "%s rotate count >= width of type"
+msgstr "el compte de rotació %s >= amplària del tipus"
+
+#: cp/typeck.c:3013 cp/typeck.c:3018 cp/typeck.c:3109 cp/typeck.c:3114
+msgid "ISO C++ forbids comparison between pointer and integer"
+msgstr "ISO C++ prohibeix la comparança entre punters i enters"
+
+#: cp/typeck.c:3295
+msgid "comparison between types `%#T' and `%#T'"
+msgstr "comparança entre els tipus \"%#T\" i \"%#T\""
+
+#: cp/typeck.c:3331
+msgid "comparison between signed and unsigned integer expressions"
+msgstr "comparança entre expressions enteres signed i unsigned"
+
+#: cp/typeck.c:3396
+msgid "invalid operands of types `%T' and `%T' to binary `%O'"
+msgstr "operadors invàlids de tipus \"%T\" i \"%T\" per al binari \"%O\""
+
+#. Some sort of arithmetic operation involving NULL was
+#. performed. Note that pointer-difference and pointer-addition
+#. have already been handled above, and so we don't end up here in
+#. that case.
+#: cp/typeck.c:3418
+msgid "NULL used in arithmetic"
+msgstr "es va usar NULL en l'aritmètica"
+
+#: cp/typeck.c:3481
+msgid "ISO C++ forbids using pointer of type `void *' in subtraction"
+msgstr "ISO C++ prohibeix l'ús d'un punter de tipus \"void *\" en la substracció"
+
+#: cp/typeck.c:3483
+msgid "ISO C++ forbids using pointer to a function in subtraction"
+msgstr "ISO C++ prohibeix l'ús d'un punter a una funció en la substracció"
+
+#: cp/typeck.c:3485
+msgid "ISO C++ forbids using pointer to a method in subtraction"
+msgstr "ISO C++ prohibeix l'ús d'un punter a un mètode en la substracció"
+
+#: cp/typeck.c:3497
+msgid "invalid use of a pointer to an incomplete type in pointer arithmetic"
+msgstr "ús invàlid d'un punter a un tipus incomplet en aritmètica de punters"
+
+#: cp/typeck.c:3553
+#, c-format
+msgid "invalid use of '%E' to form a pointer-to-member-function. Use a qualified-id."
+msgstr ""
+
+#: cp/typeck.c:3559
+#, c-format
+msgid "parenthesis around '%E' cannot be used to form a pointer-to-member-function"
+msgstr ""
+
+#: cp/typeck.c:3581
+msgid "taking address of temporary"
+msgstr "prenent l'adreça del temporal"
+
+#: cp/typeck.c:3816
+#, c-format
+msgid "ISO C++ forbids %sing an enum"
+msgstr "ISO C++ prohibeix %sing un enum"
+
+#: cp/typeck.c:3827
+msgid "cannot %s a pointer to incomplete type `%T'"
+msgstr "no es pot %s un punter a un tipus incomplet \"%T\""
+
+#: cp/typeck.c:3833
+msgid "ISO C++ forbids %sing a pointer of type `%T'"
+msgstr "ISO C++ prohibeix %sing un punter de tipus \"%T\""
+
+#: cp/typeck.c:3858
+msgid "cast to non-reference type used as lvalue"
+msgstr "s'usa la conversió a un tipus no referenciat com un lvalue"
+
+#: cp/typeck.c:3892
+msgid "invalid use of `--' on bool variable `%D'"
+msgstr "ús invàlid de \"--\" en la variable booleana \"%D\""
+
+#. ARM $3.4
+#: cp/typeck.c:3923
+msgid "ISO C++ forbids taking address of function `::main'"
+msgstr "ISO C++ prohibeix prendre l'adreça de la funció \"::main\""
+
+#. An expression like &memfn.
+#: cp/typeck.c:3994
+#, fuzzy
+msgid "ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say `&%T::%D'"
+msgstr "ISO C++ prohibeix prendre l'adreça d'una funció membre no estàtica sense qualificar per a formar un punter a la funció membre. Com \"&%T::%D\""
+
+#: cp/typeck.c:3999
+msgid "ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&%T::%D'"
+msgstr "ISO C++ prohibeix prendre l'adreça d'una funció membre limitada per a formar un punter a la funció membre. Com \"&%T::%D\""
+
+#: cp/typeck.c:4027
+msgid "ISO C++ forbids taking the address of a cast to a non-lvalue expression"
+msgstr "ISO C++ prohibeix prendre l'adreça d'una conversió a una expressió no lvalue"
+
+#: cp/typeck.c:4047
+msgid "unary `&'"
+msgstr ""
+
+#: cp/typeck.c:4076
+msgid "attempt to take address of bit-field structure member `%D'"
+msgstr ""
+
+#: cp/typeck.c:4190
+msgid "taking address of destructor"
+msgstr "prenent l'adreça del destructor"
+
+#: cp/typeck.c:4203
+msgid "taking address of bound pointer-to-member expression"
+msgstr "prenent l'adreça de l'expressió limitada punter-a-membre"
+
+#: cp/typeck.c:4211
+msgid "cannot create pointer to reference member `%D'"
+msgstr "no es pot crear un punter al membre referència \"%D\""
+
+#: cp/typeck.c:4273
+msgid "cannot take the address of `this', which is an rvalue expression"
+msgstr "no es pot prendre l'adreça de \"this\" que és una expressió rvalue"
+
+#: cp/typeck.c:4292
+msgid "address requested for `%D', which is declared `register'"
+msgstr "es va sol·licitar l'adreça de \"%D\", el qual es va declarar com \"register\""
+
+#: cp/typeck.c:4360
+#, fuzzy, c-format
+msgid "%s expression list treated as compound expression"
+msgstr "la llista d'inicialitzadors es tracta com una expressió compostada"
+
+#: cp/typeck.c:4434
+#, fuzzy
+msgid "%s from type `%T' to type `%T' casts away constness"
+msgstr "static_cast del tipus \"%T\" al tipus \"%T\" proscriu la constància"
+
+#: cp/typeck.c:4626
+msgid "invalid static_cast from type `%T' to type `%T'"
+msgstr "static_cast invàlid del tipus \"%T\" al tipus \"%T\""
+
+#: cp/typeck.c:4666
+msgid "invalid reinterpret_cast of an rvalue expression of type `%T' to type `%T'"
+msgstr "reinterpret_cast invàlid d'una expressió rvalue del tipus \"%T\" al tipus \"%T\""
+
+#: cp/typeck.c:4686
+msgid "reinterpret_cast from `%T' to `%T' loses precision"
+msgstr "reinterpret_cast de \"%T\" a \"%T\" perd precisió"
+
+#: cp/typeck.c:4705
+msgid "ISO C++ forbids casting between pointer-to-function and pointer-to-object"
+msgstr "ISO C++ prohibeix la conversió entre entre punter a funció i punter a objecte"
+
+#: cp/typeck.c:4711
+msgid "invalid reinterpret_cast from type `%T' to type `%T'"
+msgstr "reinterpret_cast invàlid del tipus \"%T\" al tipus \"%T\""
+
+#: cp/typeck.c:4739
+msgid "invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type"
+msgstr "ús invàlid de const_cast amb tipus \"%T\", que no és punter, referència, ni un tipus punter-a-dades-membres"
+
+#: cp/typeck.c:4742
+msgid "invalid use of const_cast with type `%T', which is a pointer or reference to a function type"
+msgstr "ús invàlid de const_cast amb tipus \"%T\", el qual és un punter o referència a un tipus de funció"
+
+#: cp/typeck.c:4765
+msgid "invalid const_cast of an rvalue of type `%T' to type `%T'"
+msgstr "const_cast invàlid d'un rvalue de tipus \"%T\" al tipus \"%T\""
+
+#: cp/typeck.c:4782
+msgid "invalid const_cast from type `%T' to type `%T'"
+msgstr "const_cast invàlid del tipus \"%T\" al tipus \"%T\""
+
+#: cp/typeck.c:4822 cp/typeck.c:4827
+msgid "ISO C++ forbids casting to an array type `%T'"
+msgstr "ISO C++ prohibeix la conversió a un tipus de matriu \"%T\""
+
+#: cp/typeck.c:4835
+msgid "invalid cast to function type `%T'"
+msgstr "conversió invàlida al tipus de funció \"%T\""
+
+#: cp/typeck.c:4891
+msgid "cast from `%T' to `%T' discards qualifiers from pointer target type"
+msgstr "la conversió de \"%T\" a \"%T\" descarta els qualificadors del tipus de la destinació del punter"
+
+#: cp/typeck.c:4937
+msgid "cast from `%T' to `%T' increases required alignment of target type"
+msgstr "la conversió de \"%T\" a \"%T\" incrementa l'alineació requerida del tipus de la destinació"
+
+#: cp/typeck.c:5104
+msgid " in evaluation of `%Q(%#T, %#T)'"
+msgstr " en l'avaluació de \"%Q(%#T, %#T)\""
+
+#: cp/typeck.c:5146
+msgid "ISO C++ forbids cast to non-reference type used as lvalue"
+msgstr "ISO C++ prohibeix la conversió a un tipus no referent usat com lvalue"
+
+#: cp/typeck.c:5219
+msgid "incompatible types in assignment of `%T' to `%T'"
+msgstr "tipus incompatible en l'assignació de \"%T\" a \"%T\""
+
+#: cp/typeck.c:5226
+msgid "ISO C++ forbids assignment of arrays"
+msgstr "ISO C++ prohibeix l'assignació de matrius"
+
+#: cp/typeck.c:5326
+msgid " in pointer to member function conversion"
+msgstr " en la conversió del punter a funció membre"
+
+#: cp/typeck.c:5334
+msgid " in pointer to member conversion"
+msgstr " en la conversió del punter a membre"
+
+#. This is a reinterpret cast, we choose to do nothing.
+#: cp/typeck.c:5344 cp/typeck.c:5359
+#, fuzzy
+msgid "pointer to member cast via virtual base `%T'"
+msgstr "punter a la conversió membre a través de la base virtual \"%T\" de \"%T\""
+
+#: cp/typeck.c:5362
+#, fuzzy
+msgid "pointer to member conversion via virtual base `%T'"
+msgstr "punter a la conversió membre a través de la base virtual \"%T\" de \"%T\""
+
+#: cp/typeck.c:5432
+msgid "invalid conversion to type `%T' from type `%T'"
+msgstr "conversió invàlida del tipus \"%T\" a partir del tipus \"%T\""
+
+#: cp/typeck.c:5588
+msgid "passing NULL used for non-pointer %s %P of `%D'"
+msgstr "passant NULL usat per al no punter %s %P de \"%D\""
+
+#: cp/typeck.c:5591
+msgid "%s to non-pointer type `%T' from NULL"
+msgstr "%s al tipus \"%T\" que no és punter des de NULL"
+
+#: cp/typeck.c:5599
+msgid "passing `%T' for %s %P of `%D'"
+msgstr "passant \"%T\" per a %s %P de \"%D\""
+
+#: cp/typeck.c:5602
+msgid "%s to `%T' from `%T'"
+msgstr "%s a \"%T\" des de \"%T\""
+
+#: cp/typeck.c:5612
+msgid "passing negative value `%E' for %s %P of `%D'"
+msgstr "passant el valor negatiu `%E' per a %s %P de \"%D\""
+
+#: cp/typeck.c:5615
+msgid "%s of negative value `%E' to `%T'"
+msgstr "%s de valor negatiu `%I' a \"%T\""
+
+#: cp/typeck.c:5703
+msgid "cannot convert `%T' to `%T' for argument `%P' to `%D'"
+msgstr "no es pot convertir \"%T\" a \"%T\" per a l'argument `%P' per a \"%D\""
+
+#: cp/typeck.c:5706
+msgid "cannot convert `%T' to `%T' in %s"
+msgstr "no es pot convertir \"%T\" a \"%T\" en %s"
+
+#: cp/typeck.c:5783 cp/typeck.c:5785
+msgid "in passing argument %P of `%+D'"
+msgstr "en el pas de l'argument %P de \"%+D\""
+
+#: cp/typeck.c:5892
+msgid "returning reference to temporary"
+msgstr "retornant la referència al temporal"
+
+#: cp/typeck.c:5899
+msgid "reference to non-lvalue returned"
+msgstr "es va retornar una referència a un non-lvalue"
+
+#: cp/typeck.c:5911
+msgid "reference to local variable `%D' returned"
+msgstr "es va retornar una referència a la variable local \"%D\""
+
+#: cp/typeck.c:5914
+msgid "address of local variable `%D' returned"
+msgstr "es va retornar l'adreça de la variable local \"%D\""
+
+#: cp/typeck.c:5944
+msgid "returning a value from a destructor"
+msgstr "retornant un valor d'un destructor"
+
+#. If a return statement appears in a handler of the
+#. function-try-block of a constructor, the program is ill-formed.
+#: cp/typeck.c:5952
+msgid "cannot return from a handler of a function-try-block of a constructor"
+msgstr "no es pot retornar d'un gestor d'una function-try-block d'un constructor"
+
+#. You can't return a value from a constructor.
+#: cp/typeck.c:5955
+msgid "returning a value from a constructor"
+msgstr "retornant un valor d'un constructor"
+
+#: cp/typeck.c:5978
+#, fuzzy
+msgid "return-statement with no value, in function returning '%T'"
+msgstr "\"return\" sense valors, en una funció que retorna non-void"
+
+#: cp/typeck.c:5995
+#, fuzzy
+msgid "return-statement with a value, in function returning 'void'"
+msgstr "\"return\" amb valor, en una funció que retorna void"
+
+#: cp/typeck.c:6017
+msgid "`operator new' must not return NULL unless it is declared `throw()' (or -fcheck-new is in effect)"
+msgstr "\"operator new\" no deu regressar NULL a menys que es declari \"throw()\" (o -fcheck-new estigui en efecte)"
+
+#: cp/typeck2.c:55
+msgid "type `%T' is not a base type for type `%T'"
+msgstr "el tipus \"%T\" no és un tipus base per al tipus \"%T\""
+
+#: cp/typeck2.c:151
+msgid "cannot declare variable `%D' to be of type `%T'"
+msgstr "no es pot declarar que la variable \"%D\" sigui de tipus \"%T\""
+
+#: cp/typeck2.c:154
+msgid "cannot declare parameter `%D' to be of type `%T'"
+msgstr "no es pot declarar que el paràmetre \"%D\" sigui de tipus \"%T\""
+
+#: cp/typeck2.c:157
+msgid "cannot declare field `%D' to be of type `%T'"
+msgstr "no es pot declarar que el camp \"%D\" sigui de tipus \"%T\""
+
+#: cp/typeck2.c:161
+msgid "invalid return type for member function `%#D'"
+msgstr "tipus de retorn invàlid per a la funció membre \"%#D\""
+
+#: cp/typeck2.c:163
+msgid "invalid return type for function `%#D'"
+msgstr "tipus de retorn invàlid per a la funció \"%#D\""
+
+#: cp/typeck2.c:166
+msgid "cannot allocate an object of type `%T'"
+msgstr "no es pot assignar un objecte de tipus \"%T\""
+
+#: cp/typeck2.c:173
+msgid " because the following virtual functions are abstract:"
+msgstr " perquè les següents funcions virtual són abstractes:"
+
+#: cp/typeck2.c:175
+msgid "\t%#D"
+msgstr "\t%#D"
+
+#: cp/typeck2.c:178
+msgid " since type `%T' has abstract virtual functions"
+msgstr " ja que el tipus \"%T\" té funcions virtuals abstractes"
+
+#: cp/typeck2.c:427
+msgid "constructor syntax used, but no constructor declared for type `%T'"
+msgstr "es va usar la sintaxi de constructor, però no es va declarar un constructor per al tipus \"%T\""
+
+#: cp/typeck2.c:440
+msgid "cannot initialize arrays using this syntax"
+msgstr "no es poden inicialitzar matrius usant aquesta sintaxi"
+
+#: cp/typeck2.c:545
+msgid "initializing array with parameter list"
+msgstr "inicialitzant una matriu amb una llista de paràmetres"
+
+#: cp/typeck2.c:600
+msgid "initializer for scalar variable requires one element"
+msgstr "el inicialitzador per a una variable escalar requereix un element"
+
+#: cp/typeck2.c:607
+msgid "braces around scalar initializer for `%T'"
+msgstr "parèntesis al voltant del inicialitzador per a \"%T\""
+
+#: cp/typeck2.c:610
+msgid "ignoring extra initializers for `%T'"
+msgstr "ignorant els inicialitzadors extra per a \"%T\""
+
+#: cp/typeck2.c:622
+msgid "variable-sized object of type `%T' may not be initialized"
+msgstr "un objecte de grandària variable de tipus \"%T\" no pot ser inicialitzat"
+
+#: cp/typeck2.c:632
+msgid "subobject of type `%T' must be initialized by constructor, not by `%E'"
+msgstr "el subobjecte de tipus \"%T\" deu ser inicialitzat per un constructor, no per \"%E\""
+
+#: cp/typeck2.c:697
+msgid "aggregate has a partly bracketed initializer"
+msgstr "l'agregat té un inicialitzador amb parèntesis parcials"
+
+#: cp/typeck2.c:735 cp/typeck2.c:840
+msgid "non-trivial labeled initializers"
+msgstr "inicialitzadors etiquetats com no trivials"
+
+#: cp/typeck2.c:752
+msgid "non-empty initializer for array of empty elements"
+msgstr "inicialitzador no-buit per a una matriu d'elements buits"
+
+#: cp/typeck2.c:806
+msgid "initializer list for object of class with virtual base classes"
+msgstr "llista d'inicialitzadors per a un objecte d'una classe amb classes base virtual"
+
+#: cp/typeck2.c:812
+msgid "initializer list for object of class with base classes"
+msgstr "llista d'inicialitzadors per a un objecte d'una classe amb classes base"
+
+#: cp/typeck2.c:818
+msgid "initializer list for object using virtual functions"
+msgstr "llista d'inicialitzadors per a un objecte que usa funcions virtuals"
+
+#: cp/typeck2.c:880 cp/typeck2.c:896
+msgid "missing initializer for member `%D'"
+msgstr "falta el inicialitzador pel membre \"%D\""
+
+#: cp/typeck2.c:885
+msgid "uninitialized const member `%D'"
+msgstr "membre const \"%D\" sense inicialitzar"
+
+#: cp/typeck2.c:887
+msgid "member `%D' with uninitialized const fields"
+msgstr "membre \"%D\" amb camps const sense inicialitzar"
+
+#: cp/typeck2.c:890
+msgid "member `%D' is uninitialized reference"
+msgstr "el membre \"%D\" és una referència sense inicialitzar"
+
+#: cp/typeck2.c:937
+msgid "index value instead of field name in union initializer"
+msgstr "valor d'índex en lloc del nom del camp en el inicialitzador de union"
+
+#: cp/typeck2.c:949
+msgid "no field `%D' in union being initialized"
+msgstr "no existeix el camp \"%D\" en el union que s'està inicialitzant"
+
+#: cp/typeck2.c:957
+msgid "union `%T' with no named members cannot be initialized"
+msgstr "no es pot inicialitzar el union \"%T\" sense membres nomenats"
+
+#: cp/typeck2.c:993
+msgid "excess elements in aggregate initializer"
+msgstr "excés d'elements en el inicialitzador agregat"
+
+#: cp/typeck2.c:1102
+msgid "circular pointer delegation detected"
+msgstr "es va detectar una delegació de punter circular"
+
+#: cp/typeck2.c:1115
+msgid "base operand of `->' has non-pointer type `%T'"
+msgstr "l'operant base de \"->\" té el tipus \"%T\" que no és punter"
+
+#: cp/typeck2.c:1139
+msgid "result of `operator->()' yields non-pointer result"
+msgstr "el resultat de \"operator->()\" produeix un resultat que no és punter"
+
+#: cp/typeck2.c:1141
+msgid "base operand of `->' is not a pointer"
+msgstr "l'operant base de \"->\" no és un punter"
+
+#: cp/typeck2.c:1164
+msgid "`%E' cannot be used as a member pointer, since it is of type `%T'"
+msgstr "no es pot usar \"%E\" com un punter membre, perquè és de tipus \"%T\""
+
+#: cp/typeck2.c:1172
+msgid "cannot apply member pointer `%E' to `%E', which is of non-aggregate type `%T'"
+msgstr "no es pot aplicar el punter a membre \"%E\" a \"%E\", el qual és del tipus no agregat \"%T\""
+
+#: cp/typeck2.c:1182
+msgid "member type `%T::' incompatible with object type `%T'"
+msgstr "el tipus de membre \"%T::\" és incompatible amb el tipus objecte \"%T\""
+
+#: cp/typeck2.c:1398
+msgid "call to function `%D' which throws incomplete type `%#T'"
+msgstr "cridada a la funció \"%D\" la qual llança el tipus incomplet \"%#T\""
+
+#: cp/typeck2.c:1401
+msgid "call to function which throws incomplete type `%#T'"
+msgstr "cridada a una funció la qual llança el tipus incomplet \"%#T\""
+
+#. XXX Not i18n clean.
+#: cp/cp-tree.h:3756
+#, c-format
+msgid "%s is deprecated, please see the documentation for details"
+msgstr "%s és obsolet, per favor vegi la documentació per a més detalls"
+
+#: f/bad.c:388
+msgid "note:"
+msgstr "nota:"
+
+#: f/bad.c:392
+msgid "warning:"
+msgstr "avís:"
+
+#: f/bad.c:396
+msgid "fatal:"
+msgstr "fatal:"
+
+#: f/bad.c:438
+msgid "(continued):"
+msgstr "(continuat):"
+
+#: f/bad.c:488 f/bad.c:506
+msgid "[REPORT BUG!!] %"
+msgstr "[REPORTAR error!!] %"
+
+#: f/bad.c:495 f/bad.c:527
+msgid "[REPORT BUG!!]"
+msgstr "[REPORTAR error!!]"
+
+#: f/com.c:3125
+#, no-c-format
+msgid "ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling"
+msgstr "l'etiqueta ASSIGNada no entra en \"%A\" a %0 -- utilitzant una similar més ample"
+
+#: f/com.c:11565
+msgid "no INTEGER type can hold a pointer on this configuration"
+msgstr "cap tipus INTEGER pot guardar un punter en aquesta configuració"
+
+#: f/com.c:11839
+#, c-format
+msgid "configuration: REAL, INTEGER, and LOGICAL are %d bits wide,"
+msgstr "configuració: REAL, INTEGER, i LOGICAL són de %d bits d'amplària,"
+
+#: f/com.c:11841
+#, c-format
+msgid "and pointers are %d bits wide, but g77 doesn't yet work"
+msgstr "i els punters són de %d bits d'amplària, però g77 encara no treballa"
+
+#: f/com.c:11843
+msgid "properly unless they all are 32 bits wide"
+msgstr "de forma adequada a menys que tots siguin de 32 bits d'amplària"
+
+#: f/com.c:11844
+msgid "Please keep this in mind before you report bugs."
+msgstr "Per favor tingui això presenti abans de reportar errors."
+
+#. I/O will probably crash.
+#: f/com.c:11852
+#, c-format
+msgid "configuration: char * holds %d bits, but ftnlen only %d"
+msgstr "configuració: char * guarda %d bits, però ftnlen només %d"
+
+#. ASSIGN 10 TO I will crash.
+#: f/com.c:11861
+#, c-format
+msgid ""
+"configuration: char * holds %d bits, but INTEGER only %d --\n"
+" ASSIGN statement might fail"
+msgstr ""
+"configuració: char * guarda %d bits, però INTEGER només %d --\n"
+" la declaració ASSIGN pot fallar"
+
+#: f/com.c:13677
+msgid "In statement function"
+msgstr "En la declaració de la funció"
+
+#: f/com.c:13687
+msgid "Outside of any program unit:\n"
+msgstr "Fora de qualsevol unitat de programa:\n"
+
+#: f/com.c:15283
+#, no-c-format
+msgid "%A from %B at %0%C"
+msgstr "%A des de %B en %0%C"
+
+#: f/com.c:15593
+#, no-c-format
+msgid "At %0, INCLUDE file %A exists, but is not readable"
+msgstr "En %0, el fitxer INCLUDE %A existeix, però no és llegible"
+
+#: f/com.c:15628
+#, no-c-format
+msgid "At %0, INCLUDE nesting too deep"
+msgstr "En %0, la \"niació\" de INCLUDE és massa profunda"
+
+#: f/expr.c:8706
+#, no-c-format
+msgid "Two arithmetic operators in a row at %0 and %1 -- use parentheses"
+msgstr "Dos operadors aritmètics en una fila en %0 i %1 -- usi parèntesi"
+
+#: f/expr.c:8756
+#, no-c-format
+msgid "Operator at %0 has lower precedence than that at %1 -- use parentheses"
+msgstr "L'operador en %0 té una preferència menor que aquell en %1 -- usi parèntesi"
+
+#: f/expr.c:9639
+#, no-c-format
+msgid "Use .EQV./.NEQV. instead of .EQ./.NE. at %0 for LOGICAL operands at %1 and %2"
+msgstr "Usi .EQV./.NEQV. en lloc de .EQ./.NE en %0 pels operands LOGICAL en %1 i %2"
+
+#: f/expr.c:10010
+#, no-c-format
+msgid "Unsupported operand for ** at %1 -- converting to default INTEGER"
+msgstr "Operant sense suport per a ** en %1 -- es va convertir a INTEGER per omissió"
+
+#: f/g77spec.c:231
+#, c-format
+msgid "overflowed output arg list for `%s'"
+msgstr "llista d'arguments de sortida desbordada per a \"%s\""
+
+#: f/g77spec.c:353
+msgid ""
+"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"
+"or type the command `info -f g77 Copying'.\n"
+msgstr ""
+
+#: f/g77spec.c:369
+msgid "--driver no longer supported"
+msgstr "--driver ja no té suport"
+
+#: f/g77spec.c:382
+#, c-format
+msgid "argument to `%s' missing"
+msgstr "falta l'argument per a \"%s\""
+
+#: f/g77spec.c:386
+msgid "no input files; unwilling to write output files"
+msgstr "no hi ha fitxers d'entrada; incapaç d'escriure fitxers de sortida"
+
+#: f/implic.c:203
+#, no-c-format
+msgid "Implicit declaration of `%A' at %0"
+msgstr "Declaració implícita de \"%A\" en %0"
+
+#: f/lex.c:321
+#, no-c-format
+msgid "Non-ISO-C-standard escape sequence `\\%A' at %0"
+msgstr "Seqüència d'escapi que no és estàndard ISO \"\\%A\" en %0"
+
+#: f/lex.c:340
+#, no-c-format
+msgid "Unknown escape sequence `\\%A' at %0"
+msgstr "Seqüència d'escapi desconeguda \"\\%A\" en %0"
+
+#: f/lex.c:349
+#, no-c-format
+msgid "Unterminated escape sequence `\\' at %0"
+msgstr "Seqüència d'escapi sense acabar \"\\\" en %0"
+
+#: f/lex.c:360
+#, no-c-format
+msgid "Unknown escape sequence `\\' followed by char code 0x%A at %0"
+msgstr "Seqüència d'escapi desconeguda: \"\\\" seguida pel codi de caràcter 0x%A en %0"
+
+#: f/lex.c:388
+#, no-c-format
+msgid "\\x used at %0 with no following hex digits"
+msgstr "es va usar \\x en %0 sense dígits hexadecimals a continuació"
+
+#: f/lex.c:402
+#, no-c-format
+msgid "Hex escape at %0 out of range"
+msgstr "escapi Hex en %0 fora de rang"
+
+#: f/lex.c:436
+#, no-c-format
+msgid "Escape sequence at %0 out of range for character"
+msgstr "Seqüència d'escapi en %0 fora de rang per al caràcter"
+
+#: f/lex.c:590
+msgid "hex escape out of range"
+msgstr "escapi hex fora de rang"
+
+#: f/lex.c:643
+#, c-format
+msgid "non-ANSI-standard escape sequence, `\\%c'"
+msgstr "seqüència d'escapi que no és estàndard ANSI, \"\\%c\""
+
+#: f/lex.c:656
+#, c-format
+msgid "non-ISO escape sequence `\\%c'"
+msgstr "seqüència d'escapi que no és ISO, \"\\%c\""
+
+#: f/lex.c:660
+#, c-format
+msgid "unknown escape sequence `\\%c'"
+msgstr "seqüència d'escapi desconeguda, \"\\%c\""
+
+#: f/lex.c:662
+#, c-format
+msgid "unknown escape sequence: `\\' followed by char code 0x%x"
+msgstr "seqüència d'escapi desconeguda, \"\\\" seguida pel codi de caràcter 0x%x"
+
+#: f/lex.c:745
+msgid "badly formed directive -- no closing quote"
+msgstr "directiva mal formada -- cometa sense tancar"
+
+#: f/lex.c:809
+msgid "#-lines for entering and leaving files don't match"
+msgstr "el nombre de #-lines per a entrar i sortir dels fitxers no coincideixen"
+
+#: f/lex.c:969
+msgid "bad directive -- missing close-quote"
+msgstr "directiva errònia -- falta una cometa que tanqui"
+
+#: f/lex.c:1108
+msgid "invalid #ident"
+msgstr "#ident invàlid"
+
+#: f/lex.c:1125
+msgid "undefined or invalid # directive"
+msgstr "directiva # no definida o invàlida"
+
+#: f/lex.c:1180
+msgid "invalid #line"
+msgstr "#line invàlid"
+
+#: f/lex.c:1236 f/lex.c:1280
+msgid "use `#line ...' instead of `# ...' in first line"
+msgstr "usi \"#line ...\" en lloc de \"# ...\" en la primera línia"
+
+#: f/lex.c:1290
+msgid "invalid #-line"
+msgstr "#-line invàlid"
+
+#: f/lex.c:1383
+#, no-c-format
+msgid "Null character at %0 -- line ignored"
+msgstr "Caràcter nul en %0 -- línia ignorada"
+
+#: f/stb.c:9177
+#, no-c-format
+msgid "INCLUDE at %0 not the only statement on the source line"
+msgstr "INCLUDE en %0 no és la primera declaració en la línia de codi"
+
+#: f/ste.c:1397 f/ste.c:1744
+msgid "ASSIGNed FORMAT specifier is too small"
+msgstr "el especificador ASSIGNed FORMAT és massa petit"
+
+#. ~~~Someday handle CHARACTER*1, CHARACTER*N
+#: f/ste.c:2621
+#, no-c-format
+msgid "SELECT CASE on CHARACTER type (at %0) not supported -- sorry"
+msgstr "SELECT CASE en el tipus CHARACTER (en %0) no té suport -- perdó"
+
+#: f/ste.c:2725
+msgid "SELECT (at %0) has duplicate cases -- check integer overflow of CASE(s)"
+msgstr ""
+
+#: f/ste.c:2957
+msgid "ASSIGN to variable that is too small"
+msgstr "ASSIGN a una variable que és massa petita"
+
+#: f/ste.c:2989
+msgid "ASSIGNed GOTO target variable is too small"
+msgstr "la variable de l'objectiu ASSIGNed GOTO és massa petita"
+
+#: f/stu.c:305
+#, no-c-format
+msgid "Local adjustable symbol `%A' at %0"
+msgstr "Símbol local ajustable \"%A\" en %0"
+
+#: f/target.c:2545
+msgid "data initializer on host with different endianness"
+msgstr "inicialitzador de dades en l'ordinador amb \"endianness\" diferent"
+
+#: f/top.c:244
+#, fuzzy
+msgid "-fvxt-not-f90 no longer supported -- try -fvxt"
+msgstr "%s ja no té suport -- intenti -fvxt"
+
+#: f/top.c:248
+#, fuzzy
+msgid "-ff90-not-vxt no longer supported -- try -fno-vxt -ff90"
+msgstr "%s ja no té suport -- intenti -fno-vxt -ff90"
+
+#: f/top.c:318
+#, fuzzy
+msgid "-fdebug-kludge is disabled, use normal debugging flags"
+msgstr "%s desactivat, usi els interruptors normals de depuració"
+
+#: f/bad.def:39
+#, no-c-format
+msgid "Missing first operand for binary operator at %0"
+msgstr "Falta el primer operant binari per a l'operador binari en %0"
+
+#: f/bad.def:42
+#, no-c-format
+msgid "Zero-length character constant at %0"
+msgstr "Constant de caràcter de longitud zero en %0"
+
+#: f/bad.def:45
+#, no-c-format
+msgid "Invalid token at %0 in expression or subexpression at %1"
+msgstr "Element invàlid en %0 en l'expressió o subexpressió en %1"
+
+#: f/bad.def:48
+#, no-c-format
+msgid "Missing operand for operator at %1 at end of expression at %0"
+msgstr "Falta un operant per a l'operador en %1 al final de l'expressió en %0"
+
+#: f/bad.def:51
+#, no-c-format
+msgid "Label %A already defined at %1 when redefined at %0"
+msgstr "L'etiqueta %A ja es va definir en %1 quan es va redefinir en %0"
+
+#: f/bad.def:54
+#, no-c-format
+msgid "Unrecognized character at %0 [info -f g77 M LEX]"
+msgstr "Caràcter no reconegut en %0 [info -f g77 M LEX]"
+
+#: f/bad.def:57
+#, no-c-format
+msgid "Label definition %A at %0 on empty statement (as of %1)"
+msgstr "La definició de l'etiqueta %A en %0 en una declaració buida (per a %1)"
+
+#: f/bad.def:65
+#, no-c-format
+msgid "Invalid first character at %0 [info -f g77 M LEX]"
+msgstr "Primer caràcter invàlid en %0 [info -f g77 M LEX]"
+
+#: f/bad.def:68
+#, no-c-format
+msgid "Line too long as of %0 [info -f g77 M LEX]"
+msgstr "Línia massa deixa anar per a %0 [info -f g77 M LEX]"
+
+#: f/bad.def:71
+#, no-c-format
+msgid "Non-numeric character at %0 in label field [info -f g77 M LEX]"
+msgstr "Caràcter no numèric en %0 en el camp d'etiqueta [info -f g77 M LEX]"
+
+#: f/bad.def:74
+#, no-c-format
+msgid "Label number at %0 not in range 1-99999"
+msgstr "El nombre d'etiqueta en %0 no està en el rang 1-99999"
+
+#: f/bad.def:77
+#, no-c-format
+msgid "At %0, '!' and '/*' are not valid comment delimiters"
+msgstr "En %0, \"!\" i \"/*\" no són delimitadors de comentari vàlids"
+
+#: f/bad.def:80
+#, no-c-format
+msgid "Continuation indicator at %0 must appear in column 6 [info -f g77 M LEX]"
+msgstr "L'indicador de continuació en %0 deu aparèixer en la columna 6 [info -f g77 M LEX]"
+
+#: f/bad.def:83
+#, no-c-format
+msgid "Label at %0 invalid with continuation line indicator at %1 [info -f g77 M LEX]"
+msgstr "Etiqueta en %0 invàlida amb indicador de continuació de línia en %1 [info -f g77 M LEX]"
+
+#: f/bad.def:91
+#, no-c-format
+msgid "Character constant at %0 has no closing apostrophe at %1"
+msgstr "La constant de caràcter en %0 no té l'apòstrofe que tanca en %1"
+
+#: f/bad.def:94
+#, no-c-format
+msgid "Hollerith constant at %0 specified %A more characters than are present as of %1"
+msgstr "La constant hollerith en %0 especifica %A més caràcters que els presents en %1"
+
+#: f/bad.def:97
+#, no-c-format
+msgid "Missing close parenthese at %0 needed to match open parenthese at %1"
+msgstr "Falta el parèntesi que tanca en %0 necessari per a coincidir amb els parèntesis oberts en %1"
+
+#: f/bad.def:100
+#, no-c-format
+msgid "Integer at %0 too large"
+msgstr "Enter en %0 massa gran"
+
+#: f/bad.def:123
+#, no-c-format
+msgid "Period at %0 not followed by digits for floating-point number or by `NOT.', `TRUE.', or `FALSE.'"
+msgstr "El punt en %0 no està seguit de dígits per a un nombre de coma flotant o per \"NOT.\", \"TRUE.\" o \"FALSE.\""
+
+#: f/bad.def:126
+#, no-c-format
+msgid "Missing close-period between `.%A' at %0 and %1"
+msgstr "Falta el punt que tanca entri \".%A\" en %0 i %1"
+
+#: f/bad.def:129
+#, no-c-format
+msgid "Invalid exponent at %0 for real constant at %1; nondigit `%A' in exponent field"
+msgstr "Exponent invàlid en %0 per a la constant real en %1; \"%A\" que no és dígit en el camp de l'exponent"
+
+#: f/bad.def:132
+#, no-c-format
+msgid "Missing value at %1 for real-number exponent at %0"
+msgstr "Falta un valor en %1 per a l'exponent de nombre real en %0"
+
+#: f/bad.def:135
+#, no-c-format
+msgid "Expected binary operator between expressions at %0 and at %1"
+msgstr "S'esperava un operador binari entre les expressions en %0 i en %1"
+
+#: f/bad.def:253
+#, no-c-format
+msgid "Semicolon at %0 is an invalid token"
+msgstr "El punt i coma en %0 és un element invàlid"
+
+#: f/bad.def:271
+#, no-c-format
+msgid "Extraneous comma in FORMAT statement at %0"
+msgstr "Coma sobrant en la declaració FORMAT en %0"
+
+#: f/bad.def:274
+#, no-c-format
+msgid "Missing comma in FORMAT statement at %0"
+msgstr "Coma faltant en la declaració FORMAT en %0"
+
+#: f/bad.def:277
+#, no-c-format
+msgid "Spurious sign in FORMAT statement at %0"
+msgstr "Signe espuri en la declaració FORMAT en %0"
+
+#: f/bad.def:280
+#, no-c-format
+msgid "Spurious number in FORMAT statement at %0"
+msgstr "Nombre espuri en la declaració FORMAT en %0"
+
+#: f/bad.def:283
+#, no-c-format
+msgid "Spurious text trailing number in FORMAT statement at %0"
+msgstr "Text espuri addicional al nombre en la declaració FORMAT en %0"
+
+#: f/bad.def:291
+#, no-c-format
+msgid "Unrecognized FORMAT specifier at %0"
+msgstr "Especificador FORMAT no reconegut en %0"
+
+#: f/bad.def:419
+#, no-c-format
+msgid "Missing close-parenthese(s) in FORMAT statement at %0"
+msgstr "Falta(en) parèntesi(s) que tanquen en la declaració FORMAT en %0"
+
+#: f/bad.def:422
+#, no-c-format
+msgid "Missing number following period in FORMAT statement at %0"
+msgstr "Falta un nombre a continuació del punt en la declaració FORMAT en %0"
+
+#: f/bad.def:425
+#, no-c-format
+msgid "Missing number following `E' in FORMAT statement at %0"
+msgstr "Falta un nombre a continuació de \"E\" en la declaració FORMAT en %0"
+
+#: f/bad.def:433
+#, no-c-format
+msgid "Spurious trailing comma preceding terminator at %0"
+msgstr "Coma final espúria precedint al terminador en %0"
+
+#: f/bad.def:436
+#, no-c-format
+msgid "At %0, specify OPERATOR instead of ASSIGNMENT for INTERFACE statement not specifying the assignment operator (=)"
+msgstr "En %0, especifiqui OPERATOR en lloc de ASSIGNMENT per a la declaració INTERFACE que no especifica l'operador d'assignació (=)"
+
+#: f/bad.def:439
+#, no-c-format
+msgid "At %0, specify ASSIGNMENT instead of OPERATOR for INTERFACE statement specifying the assignment operator (=)"
+msgstr "En %0, especifiqui ASSIGNMENT en lloc de OPERATOR per a la declaració INTERFACE que especifica l'operador d'assignació (=)"
+
+#: f/bad.def:452
+#, no-c-format
+msgid "Cannot specify =initialization-expr at %0 unless `::' appears before list of objects"
+msgstr "No es pot especificar =expr-iniciació en %0 a menys que \"::\" aparegui abans que la llista dels objectes"
+
+#: f/bad.def:455
+#, no-c-format
+msgid "Reference to label at %1 inconsistent with its definition at %0"
+msgstr "La referència a l'etiqueta en %1 és inconsistenta amb la seva definició en %0"
+
+#: f/bad.def:458
+#, no-c-format
+msgid "Reference to label at %1 inconsistent with earlier reference at %0"
+msgstr "La referència a l'etiqueta en %1 és inconsistenta amb la referència anterior en %0"
+
+#: f/bad.def:461
+#, no-c-format
+msgid "DO-statement reference to label at %1 follows its definition at %0"
+msgstr "La referència de la declaració DO a l'etiqueta en %1 segueix la seva definició en %0"
+
+#: f/bad.def:464
+#, no-c-format
+msgid "Reference to label at %1 is outside block containing definition at %0"
+msgstr "La referència a l'etiqueta en %1 està fora del bloc que conté la definició en %0"
+
+#: f/bad.def:467
+#, no-c-format
+msgid "DO-statement references to label at %0 and %2 separated by unterminated block starting at %1"
+msgstr "Les referències de la declaració DO a l'etiqueta en %0 i %2 estan separades per un bloc sense acabar que comença en %1"
+
+#: f/bad.def:470
+#, no-c-format
+msgid "DO-statement reference to label at %0 and label definition at %2 separated by unterminated block starting at %1"
+msgstr "La referència de la declaració DO a l'etiqueta en %0 i la definició de l'etiqueta en %2 estan separades per un bloc sense acabar que comença en %1"
+
+#: f/bad.def:473
+#, no-c-format
+msgid "Label definition at %0 invalid on this kind of statement"
+msgstr "La definició d'etiqueta en %0 és invàlida en aquest tipus de declaració"
+
+#: f/bad.def:476
+#, no-c-format
+msgid "Statement at %0 invalid in this context"
+msgstr "La declaració en %0 és invàlida en aquest context"
+
+#: f/bad.def:479
+#, no-c-format
+msgid "Statement at %0 invalid in context established by statement at %1"
+msgstr "La declaració en %0 és invàlida en el context establert per la declaració en %1"
+
+#: f/bad.def:482
+#, no-c-format
+msgid "Statement at %0 must specify construct name specified at %1"
+msgstr "La declaració en %0 deu especificar el nom de la construcció especificada en %1"
+
+#: f/bad.def:485
+#, no-c-format
+msgid "Construct name at %0 superfluous, no construct name specified at %1"
+msgstr "El nom de la construcció en %0 és superflu, no es va especificar un nom de construcció en %1"
+
+#: f/bad.def:488
+#, no-c-format
+msgid "Construct name at %0 not the same as construct name at %1"
+msgstr "El nom de construcció en %0 no és el mateix que el nom de construcció en %1"
+
+#: f/bad.def:491
+#, no-c-format
+msgid "Construct name at %0 does not match construct name for any containing DO constructs"
+msgstr "El nom de construcció en %0 no coincideix amb el nom de construcció per a qualsevol construcció DO contenidora"
+
+#: f/bad.def:494
+#, no-c-format
+msgid "Label definition missing at %0 for DO construct specifying label at %1"
+msgstr "Falta la definició d'etiqueta en %0 per a la construcció DO que especifica l'etiqueta en %1"
+
+#: f/bad.def:497
+#, no-c-format
+msgid "Statement at %0 follows ELSE block for IF construct at %1"
+msgstr "La declaració en %0 segueix al bloc ELSE per a la construcció IF en %1"
+
+#: f/bad.def:500
+#, no-c-format
+msgid "No label definition for FORMAT statement at %0"
+msgstr "No hi ha definició d'etiqueta per a la declaració FORMAT en %0"
+
+#: f/bad.def:503
+#, no-c-format
+msgid "Second occurrence of ELSE WHERE at %0 within WHERE at %1"
+msgstr "Segona ocurrència de ELSE WHERE en %0 dintre de WHERE en %1"
+
+#: f/bad.def:506
+#, no-c-format
+msgid "END statement at %0 missing `%A' keyword required for internal or module procedure(s) bounded by %1"
+msgstr "A la declaració END en %0 li falta la paraula clau `%A' requerida per a procediment(s) intern(s) o mòdul(s) units per %1"
+
+#: f/bad.def:509
+#, no-c-format
+msgid "MODULE PROCEDURE statement at %0 disallowed because INTERFACE at %1 specifies no generic name, operator, or assignment"
+msgstr "No es permet la declaració MODULE PROCEDURE en %0 perquè INTERFACE en %1 no especifica un nom genèric, operador o assignació"
+
+#: f/bad.def:512
+#, no-c-format
+msgid "BLOCK DATA name at %0 superfluous, no name specified at %1"
+msgstr "El nom de BLOCK DATA en %0 és superflu, no es va especificar un nom en %1"
+
+#: f/bad.def:515
+#, no-c-format
+msgid "Program name at %0 superfluous, no PROGRAM statement specified at %1"
+msgstr "El nom de programa en %0 és superflu, no es va especificar una declaració PROGRAM en %1"
+
+#: f/bad.def:518
+#, no-c-format
+msgid "Program unit name at %0 not the same as name at %1"
+msgstr "El nom d'unitat de programa en %0 no és el mateix que el nom en %1"
+
+#: f/bad.def:521
+#, no-c-format
+msgid "Type name at %0 not the same as name at %1"
+msgstr "El nom de tipus en %0 no és el mateix que el nom en %1"
+
+#: f/bad.def:524
+#, no-c-format
+msgid "End of source file before end of block started at %0"
+msgstr "Fi del fitxer font abans que comencés el bloc en %0"
+
+#: f/bad.def:527
+#, no-c-format
+msgid "Undefined label, first referenced at %0"
+msgstr "Etiqueta indefinida, primer referenciada en %0"
+
+#: f/bad.def:530
+#, no-c-format
+msgid "SAVE statement or attribute at %1 cannot be specified along with SAVE statement or attribute at %0"
+msgstr "La declaració o atribut SAVE en %1 no es pot especificar juntament amb la declaració o atribut SAVE en %0"
+
+#: f/bad.def:533
+#, no-c-format
+msgid "PUBLIC or PRIVATE statement at %1 cannot be specified along with PUBLIC or PRIVATE statement at %0"
+msgstr "La declaració PUBLIC o PRIVATE en %1 no es pot especificar juntament amb la declaració PUBLIC o PRIVATE en %0"
+
+#: f/bad.def:536
+#, no-c-format
+msgid "RETURN statement at %0 invalid within a main program unit"
+msgstr "La declaració RETURN en %0 és invàlida dintre d'una unitat de programa principal"
+
+#: f/bad.def:539
+#, no-c-format
+msgid "Alternate return specifier at %0 invalid within a main program unit"
+msgstr "El especificador de retorn alternatiu en %0 és invàlid dintre d'una unitat de programa principal"
+
+#: f/bad.def:542
+#, no-c-format
+msgid "Alternate return specifier at %0 invalid within a function"
+msgstr "El especificador de retorn alternatiu en %0 és invàlid dintre d'una funció"
+
+#: f/bad.def:545
+#, no-c-format
+msgid "Access specifier or PRIVATE statement at %0 invalid for derived-type definition within other than the specification part of a module"
+msgstr "El especificador d'accés o la declaració PRIVATE en %0 és invàlid per a la definició de tipus derivat dintre d'un altre que la part d'especificació d'un mòdul"
+
+#: f/bad.def:548
+#, no-c-format
+msgid "Access specifier at %0 must immediately follow derived-type statement at %1 with no intervening statements"
+msgstr "El especificador d'accés en %0 deu seguir immediatament a la declaració de tipus derivat en %1 sense declaracions que intervinguin"
+
+#: f/bad.def:551
+#, no-c-format
+msgid "No components specified as of %0 for derived-type definition beginning at %1"
+msgstr "No es van especificar components per a %0 per a la definició de tipus derivat que comença en %1"
+
+#: f/bad.def:554
+#, no-c-format
+msgid "No components specified as of %0 for structure definition beginning at %1"
+msgstr "No es van especificar components per a %0 per a la la definició de l'estructura que comença en %1"
+
+#: f/bad.def:557
+#, no-c-format
+msgid "Missing structure name for outer structure definition at %0"
+msgstr "Falta el nom de l'estructura per a la definició de l'estructura externa en %0"
+
+#: f/bad.def:560
+#, no-c-format
+msgid "Field names at %0 for outer structure definition -- specify them in a subsequent RECORD statement instead"
+msgstr "Noms de camps en %0 per a la definició de l'estructura exterior -- especifiqui'ls en el seu lloc en una declaració RECORD subsecuents"
+
+#: f/bad.def:563
+#, no-c-format
+msgid "Missing field name(s) for structure definition at %0 within structure definition at %1"
+msgstr "Manca(en) el(s) nom(s) de camp(s) per a la definició de l'estructura en %0 dintre de la definició de l'estructura en %1"
+
+#: f/bad.def:566
+#, no-c-format
+msgid "No components specified as of %0 for map beginning at %1"
+msgstr "No es van especificar component en %0 per al mapa que comença en %1"
+
+#: f/bad.def:569
+#, no-c-format
+msgid "Zero or one maps specified as of %0 for union beginning at %1 -- at least two are required"
+msgstr "Es van especificar zero o un mapa en %0 per a la unió que comença en %1 -- es requereixen almenys dos"
+
+#: f/bad.def:572
+#, no-c-format
+msgid "Missing %A specifier in statement at %0"
+msgstr "Falta el especificador %A en la declaració en %0"
+
+#: f/bad.def:575
+#, no-c-format
+msgid "Items in I/O list starting at %0 invalid for namelist-directed I/O"
+msgstr "Els elements en la llista d'I/O que comença en %0 són invàlids pel I/O dirigit per una llista de noms"
+
+#: f/bad.def:578
+#, no-c-format
+msgid "Conflicting I/O control specifications at %0 and %1"
+msgstr "Especificacions de control d'I/O en conflicte en %0 i %1"
+
+#: f/bad.def:581
+#, no-c-format
+msgid "No UNIT= specifier in I/O control list at %0"
+msgstr "No hi ha un especificador UNIT= en la llista de control d'I/O en %0"
+
+#: f/bad.def:584
+#, no-c-format
+msgid "Specification at %0 requires ADVANCE=`NO' specification in same I/O control list"
+msgstr "L'especificació en %0 requereix l'especificació ADVANCE=\"NO\" en la mateixa llista de control d'I/O"
+
+#: f/bad.def:587
+#, no-c-format
+msgid "Specification at %0 requires explicit FMT= specification in same I/O control list"
+msgstr "L'especificació en %0 requereix l'especificació FMT= explícita en la mateixa llista de control d'I/O"
+
+#: f/bad.def:595
+#, no-c-format
+msgid "Second occurrence of CASE DEFAULT at %0 within SELECT CASE at %1"
+msgstr "Segona ocurrència de CASE DEFAULT en %0 dintre d'un SELECT CASE en %1"
+
+#: f/bad.def:598
+#, no-c-format
+msgid "Duplicate or overlapping case values/ranges at %0 and %1"
+msgstr "Valors/rangs casi duplicats o traslapats en %0 i %1"
+
+#: f/bad.def:601
+#, no-c-format
+msgid "Type and/or kind-type parameter disagreement between CASE value or value within range at %0 and SELECT CASE at %1"
+msgstr "Desacord de tipus i/o paràmetre de tipus entre el valor CASE o el valor dintre del rang en %0 i SELECT CASE en %1"
+
+#: f/bad.def:604
+#, no-c-format
+msgid "Range specification at %0 invalid for CASE statement within logical-type SELECT CASE statement"
+msgstr "Especificació de rang en %0 invàlida per a la declaració CASE dintre de la declaració SELECT CASE de tipus lògic"
+
+#: f/bad.def:617
+#, no-c-format
+msgid "Fortran 90 feature at %0 unsupported"
+msgstr "Característica Fortran 90 en %0 sense suport"
+
+#: f/bad.def:630
+#, no-c-format
+msgid "Invalid declaration of or reference to symbol `%A' at %0 [initially seen at %1]"
+msgstr "Declaració invàlida de/o referència al símbol \"%A\" en %0 [observat inicialment en %1]"
+
+#: f/bad.def:638
+#, no-c-format
+msgid "Null element at %0 for array reference at %1"
+msgstr "Element null en %0 per a la referència de matriu en %1"
+
+#: f/bad.def:641
+#, no-c-format
+msgid "Too few elements (%A missing) as of %0 for array reference at %1"
+msgstr "Molt pocs elements (falta %A) per a %0 per a la referència de matriu en %1"
+
+#: f/bad.def:644
+#, no-c-format
+msgid "Too many elements as of %0 for array reference at %1"
+msgstr "Massa elements per a %0 per a la referència de matriu en %1"
+
+#: f/bad.def:647
+#, no-c-format
+msgid "Missing colon as of %0 in substring reference for %1"
+msgstr "Falten dos punts en %0 en la referència de subcadene per a %1"
+
+#: f/bad.def:650
+#, no-c-format
+msgid "Invalid use at %0 of substring operator on %1"
+msgstr "ùs invàlid en %0 de l'operador de subcadenes en %1"
+
+#: f/bad.def:653
+#, no-c-format
+msgid "Substring begin/end point at %0 out of defined range"
+msgstr "El punt d'inici/fi de la subcadena en %0 està fora del rang definit"
+
+#: f/bad.def:656
+#, no-c-format
+msgid "Array element value at %0 out of defined range"
+msgstr "Valor de l'element de la matriu en %0 està fora del rang definit"
+
+#: f/bad.def:659
+#, no-c-format
+msgid "Expression at %0 has incorrect data type or rank for its context"
+msgstr "L'expressió en %0 té el tipus de dada o rang incorrecte per al seu context"
+
+#: f/bad.def:662
+#, no-c-format
+msgid "Division by 0 (zero) at %0 (IEEE not yet supported)"
+msgstr "Divisió per 0 (zero) en %0 (IEEE encara no té suport)"
+
+#: f/bad.def:665
+#, no-c-format
+msgid "%A step count known to be 0 (zero) at %0"
+msgstr "Se sap que el compte de passada %A és 0 (zero) en %0"
+
+#: f/bad.def:668
+#, no-c-format
+msgid "%A end value plus step count known to overflow at %0"
+msgstr "Se sap que el valor final %A mes el compte de passada es desborda en %0"
+
+#: f/bad.def:671
+#, no-c-format
+msgid "%A begin, end, and step-count values known to result in implementation-dependent behavior due to overflow(s) in intermediate calculations at %0"
+msgstr "Se sap que els valors d'inici, fi i compte de passada %A resulten en conducta depenent de la implementació a causa de desbordament(s) en càlculs intermedis en %0"
+
+#: f/bad.def:674
+#, no-c-format
+msgid "%A begin, end, and step-count values known to result in no iterations at %0"
+msgstr "Se sap que els valors d'inici, fi i compte de passada %A resulten en falta d'iteracions en %0"
+
+#: f/bad.def:677
+#, no-c-format
+msgid "Type disagreement between expressions at %0 and %1"
+msgstr "Desacord de tipus entre les expressions en %0 i %1"
+
+#: f/bad.def:690
+#, no-c-format
+msgid "No specification for implied-DO iterator `%A' at %0"
+msgstr "No hi ha especificació per al iterador del DO implícit `%A' en %0"
+
+#: f/bad.def:693
+#, no-c-format
+msgid "Gratuitous parentheses surround implied-DO construct at %0"
+msgstr "Parèntesis gratuïts al voltant de la construcció amb DO implícit en %0"
+
+#: f/bad.def:696
+#, no-c-format
+msgid "Zero-size specification invalid at %0"
+msgstr "Especificació de grandària zero invàlida en %0"
+
+#: f/bad.def:699
+#, no-c-format
+msgid "Zero-size array at %0"
+msgstr "Matriu de grandària zero en %0"
+
+#: f/bad.def:702
+#, no-c-format
+msgid "Target machine does not support complex entity of kind specified at %0"
+msgstr ""
+
+#: f/bad.def:705
+#, no-c-format
+msgid "Target machine does not support DOUBLE COMPLEX, specified at %0"
+msgstr ""
+
+#: f/bad.def:708
+#, no-c-format
+msgid "Attempt to raise constant zero to a power at %0"
+msgstr ""
+
+#: f/bad.def:806
+#, no-c-format
+msgid "Reference to generic intrinsic `%A' at %0 could be to form %B or %C"
+msgstr ""
+
+#: f/bad.def:809
+#, no-c-format
+msgid "Ambiguous use of intrinsic `%A' at %0 [info -f g77 M CMPAMBIG]"
+msgstr ""
+
+#: f/bad.def:812
+#, no-c-format
+msgid "Intrinsic `%A' referenced %Bly at %0, %Cly at %1 [info -f g77 M EXPIMP]"
+msgstr ""
+
+#: f/bad.def:815
+#, no-c-format
+msgid "Same name `%A' used for %B at %0 and %C at %1 [info -f g77 M INTGLOB]"
+msgstr ""
+
+#: f/bad.def:818
+#, no-c-format
+msgid "Explicit type declaration for intrinsic `%A' disagrees with invocation at %0"
+msgstr ""
+
+#: f/bad.def:821
+#, no-c-format
+msgid "Unable to open INCLUDE file `%A' at %0"
+msgstr ""
+
+#: f/bad.def:839
+#, no-c-format
+msgid "Null argument at %0 for statement function reference at %1"
+msgstr ""
+
+#: f/bad.def:842
+#, no-c-format
+msgid "Null argument at %0 for procedure invocation at %1"
+msgstr ""
+
+#: f/bad.def:845
+#, no-c-format
+msgid "%A too few arguments (starting with dummy argument `%B') as of %0 for statement function reference at %1"
+msgstr ""
+
+#: f/bad.def:848
+#, no-c-format
+msgid "%A too many arguments as of %0 for statement function reference at %1"
+msgstr ""
+
+#: f/bad.def:851
+#, no-c-format
+msgid "Array supplied at %1 for dummy argument `%A' in statement function reference at %0"
+msgstr ""
+
+#: f/bad.def:854
+#, no-c-format
+msgid "Unsupported FORMAT specifier at %0"
+msgstr ""
+
+#: f/bad.def:857
+#, no-c-format
+msgid "Variable-expression FORMAT specifier at %0 -- unsupported"
+msgstr ""
+
+#: f/bad.def:880
+#, no-c-format
+msgid "Unsupported VXT statement at %0"
+msgstr ""
+
+#: f/bad.def:883
+#, no-c-format
+msgid "Attempt to specify second initial value for `%A' at %0"
+msgstr ""
+
+#: f/bad.def:886
+#, no-c-format
+msgid "Too few initial values in list of initializers for `%A' at %0"
+msgstr ""
+
+#: f/bad.def:889
+#, no-c-format
+msgid "Too many initial values in list of initializers starting at %0"
+msgstr ""
+
+#: f/bad.def:892
+#, no-c-format
+msgid "Array or substring specification for `%A' out of range in statement at %0"
+msgstr ""
+
+#: f/bad.def:895
+#, no-c-format
+msgid "Array subscript #%B out of range for initialization of `%A' in statement at %0"
+msgstr ""
+
+#: f/bad.def:898
+#, no-c-format
+msgid "Implied do-loop step count of 0 (zero) for iteration variable `%A' in statement at %0"
+msgstr ""
+
+#: f/bad.def:901
+#, no-c-format
+msgid "Implied do-loop iteration count of 0 (zero) for iteration variable `%A' in statement at %0"
+msgstr ""
+
+#: f/bad.def:904
+#, no-c-format
+msgid "Not an integer constant expression in implied do-loop in statement at %0"
+msgstr ""
+
+#: f/bad.def:907
+#, no-c-format
+msgid "Attempt to specify second initial value for element of `%A' at %0"
+msgstr ""
+
+#: f/bad.def:910
+#, no-c-format
+msgid "Attempt to EQUIVALENCE common areas `%A' and `%B' at %0"
+msgstr ""
+
+#: f/bad.def:913
+#, no-c-format
+msgid "Can't place `%A' as directed by EQUIVALENCE due to alignment restrictions"
+msgstr ""
+
+#: f/bad.def:916
+#, no-c-format
+msgid "Mismatched EQUIVALENCE requirements for placement of `%A' at both %C and %D bytes offset from `%B'"
+msgstr ""
+
+#: f/bad.def:919
+#, no-c-format
+msgid "Array or substring specification for `%A' out of range in EQUIVALENCE statement"
+msgstr ""
+
+#: f/bad.def:922
+#, no-c-format
+msgid "Substring of non-CHARACTER entity `%A' in EQUIVALENCE statement"
+msgstr ""
+
+#: f/bad.def:925
+#, no-c-format
+msgid "Array reference to scalar variable `%A' in EQUIVALENCE statement"
+msgstr ""
+
+#: f/bad.def:928
+#, no-c-format
+msgid "Array subscript #%B out of range for EQUIVALENCE of `%A'"
+msgstr ""
+
+#: f/bad.def:936
+#, no-c-format
+msgid "Attempt to extend COMMON area beyond its starting point via EQUIVALENCE of `%A'"
+msgstr ""
+
+#: f/bad.def:939
+#, no-c-format
+msgid "Too few elements in reference to array `%A' in EQUIVALENCE statement"
+msgstr ""
+
+#: f/bad.def:942
+#, no-c-format
+msgid "Too many elements in reference to array `%A' in EQUIVALENCE statement"
+msgstr ""
+
+#: f/bad.def:945
+#, no-c-format
+msgid "Mixed CHARACTER and non-CHARACTER types via COMMON/EQUIVALENCE -- for example, `%A' and `%B'"
+msgstr ""
+
+#: f/bad.def:958
+#, no-c-format
+msgid "Return value `%A' for FUNCTION at %0 not referenced in subprogram"
+msgstr ""
+
+#: f/bad.def:976
+#, no-c-format
+msgid "Common block `%A' is SAVEd, explicitly or implicitly, at %0 but not SAVEd at %1"
+msgstr ""
+
+#: f/bad.def:979
+#, no-c-format
+msgid "Common block `%A' is %B %D in length at %0 but %C %E at %1"
+msgstr ""
+
+#: f/bad.def:987
+#, no-c-format
+msgid "Blank common initialized at %0"
+msgstr ""
+
+#: f/bad.def:990
+#, no-c-format
+msgid "Intrinsic `%A' is passed as actual argument at %0 but not explicitly declared INTRINSIC"
+msgstr ""
+
+#: f/bad.def:993
+#, no-c-format
+msgid "External procedure `%A' is passed as actual argument at %0 but not explicitly declared EXTERNAL"
+msgstr ""
+
+#: f/bad.def:996
+#, no-c-format
+msgid "Character `%A' (for example) is upper-case in symbol name at %0"
+msgstr ""
+
+#: f/bad.def:999
+#, no-c-format
+msgid "Character `%A' (for example) is lower-case in symbol name at %0"
+msgstr ""
+
+#: f/bad.def:1002
+#, no-c-format
+msgid "Character `%A' not followed at some point by lower-case character in symbol name at %0"
+msgstr ""
+
+#: f/bad.def:1005
+#, no-c-format
+msgid "Initial character `%A' is lower-case in symbol name at %0"
+msgstr ""
+
+#: f/bad.def:1013
+#, no-c-format
+msgid "NAMELIST not adequately supported by run-time library for source files with case preserved"
+msgstr ""
+
+#: f/bad.def:1016
+#, no-c-format
+msgid "Nested %% construct (%%VAL, %%REF, or %%DESCR) at %0"
+msgstr ""
+
+#: f/bad.def:1034
+#, no-c-format
+msgid "Statement at %0 invalid in BLOCK DATA program unit at %1"
+msgstr ""
+
+#: f/bad.def:1037
+#, no-c-format
+msgid "Truncating characters on right side of character constant at %0"
+msgstr ""
+
+#: f/bad.def:1040
+#, no-c-format
+msgid "Truncating characters on right side of hollerith constant at %0"
+msgstr ""
+
+#: f/bad.def:1043
+#, no-c-format
+msgid "Truncating non-zero data on left side of numeric constant at %0"
+msgstr ""
+
+#: f/bad.def:1046
+#, no-c-format
+msgid "Truncating non-zero data on left side of typeless constant at %0"
+msgstr ""
+
+#: f/bad.def:1049
+#, no-c-format
+msgid "Typeless constant at %0 too large"
+msgstr ""
+
+#: f/bad.def:1052
+#, no-c-format
+msgid "First-column ampersand continuation at %0"
+msgstr ""
+
+#: f/bad.def:1055 f/bad.def:1058
+#, no-c-format
+msgid "Global name `%A' defined at %0 already defined at %1 [info -f g77 M GLOBALS]"
+msgstr ""
+
+#: f/bad.def:1061 f/bad.def:1064
+#, no-c-format
+msgid "Global name `%A' is %B at %0 but is %C at %1 [info -f g77 M GLOBALS]"
+msgstr ""
+
+#: f/bad.def:1067 f/bad.def:1070
+#, no-c-format
+msgid "Global name `%A' at %0 has different type at %1 [info -f g77 M GLOBALS]"
+msgstr ""
+
+#: f/bad.def:1073
+#, no-c-format
+msgid "Too %B arguments passed to `%A' at %0 versus definition at %1 [info -f g77 M GLOBALS]"
+msgstr ""
+
+#: f/bad.def:1076
+#, no-c-format
+msgid "Too %B arguments for `%A' at %0 versus invocation at %1 [info -f g77 M GLOBALS]"
+msgstr ""
+
+#: f/bad.def:1079 f/bad.def:1082
+#, no-c-format
+msgid "Argument #%B of `%A' is %C at %0 but is %D at %1 [info -f g77 M GLOBALS]"
+msgstr ""
+
+#: f/bad.def:1085
+#, no-c-format
+msgid "Array `%A' at %0 is too large to handle"
+msgstr ""
+
+#: f/bad.def:1088
+#, no-c-format
+msgid "Statement function `%A' defined at %0 is not used"
+msgstr ""
+
+#: f/bad.def:1091
+#, no-c-format
+msgid "Intrinsic `%A', invoked at %0, known to be non-Y2K-compliant [info -f g77 M Y2KBAD]"
+msgstr ""
+
+#: f/bad.def:1094
+#, no-c-format
+msgid "Internal compiler error -- cannot perform operation"
+msgstr ""
+
+#. Kind messages are used in diagnostic location reports of the
+#. form "<file>: In function `foo': <error message>".
+#: f/info-k.def:32
+msgid "In unknown kind"
+msgstr ""
+
+#: f/info-k.def:33
+msgid "In entity"
+msgstr ""
+
+#: f/info-k.def:34
+msgid "In function"
+msgstr ""
+
+#: f/info-k.def:35
+msgid "In subroutine"
+msgstr ""
+
+#: f/info-k.def:36
+msgid "In program"
+msgstr ""
+
+#: f/info-k.def:37
+msgid "In block-data unit"
+msgstr ""
+
+#: f/info-k.def:38
+msgid "In common block"
+msgstr ""
+
+#: f/info-k.def:39
+msgid "In construct"
+msgstr ""
+
+#: f/info-k.def:40
+msgid "In namelist"
+msgstr ""
+
+#: f/info-k.def:41
+msgid "In anything"
+msgstr ""
+
+#: java/check-init.c:905
+#, c-format
+msgid "internal error in check-init: tree code not implemented: %s"
+msgstr ""
+
+#: java/check-init.c:977
+#, fuzzy
+msgid "%Jfinal field '%D' may not have been initialized"
+msgstr "no existeix el camp \"%D\" en el union que s'està inicialitzant"
+
+#: java/class.c:592 java/class.c:616
+msgid "internal error - too many interface type"
+msgstr ""
+
+#: java/class.c:715
+msgid "bad method signature"
+msgstr ""
+
+#: java/class.c:759
+msgid "misplaced ConstantValue attribute (not in any field)"
+msgstr ""
+
+#: java/class.c:761
+#, c-format
+msgid "duplicate ConstantValue attribute for field '%s'"
+msgstr ""
+
+#: java/class.c:772
+#, c-format
+msgid "ConstantValue attribute of field '%s' has wrong type"
+msgstr ""
+
+#: java/class.c:1067
+#, c-format
+msgid "field '%s' not found in class"
+msgstr ""
+
+#: java/class.c:1324
+msgid "%Jabstract method in non-abstract class"
+msgstr ""
+
+#: java/class.c:2141
+msgid "%Jnon-static method '%D' overrides static method"
+msgstr ""
+
+#: java/decl.c:1018
+#, fuzzy
+msgid "%J'%D' used prior to declaration"
+msgstr "s'usa \"%#D\" previ a la declaració"
+
+#: java/decl.c:1059
+#, c-format
+msgid "declaration of `%s' shadows a parameter"
+msgstr "la declaració de \"%s\" enfosquí un paràmetre"
+
+#: java/decl.c:1062
+#, c-format
+msgid "declaration of `%s' shadows a symbol from the parameter list"
+msgstr "la declaració de \"%s\" enfosquí un símbol de la llista de paràmetres"
+
+#: java/decl.c:1361
+#, fuzzy
+msgid "%Jlabel '%D' used but not defined"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: java/decl.c:1366
+#, fuzzy
+msgid "%Jlabel '%D' defined but not used"
+msgstr "s'usa l'etiqueta \"%D\" però no està definida"
+
+#: java/decl.c:1494
+msgid "%JIn %D: overlapped variable and exception ranges at %d"
+msgstr ""
+
+#: java/decl.c:1572
+msgid "bad type in parameter debug info"
+msgstr ""
+
+#: java/decl.c:1581
+msgid "%Jbad PC range for debug info for local '%D'"
+msgstr ""
+
+#: java/expr.c:519
+msgid "stack underflow - dup* operation"
+msgstr ""
+
+#: java/expr.c:1469
+#, c-format
+msgid "reference `%s' is ambiguous: appears in interface `%s' and interface `%s'"
+msgstr ""
+
+#: java/expr.c:1497
+#, c-format
+msgid "field `%s' not found"
+msgstr ""
+
+#: java/expr.c:1658
+msgid "ret instruction not implemented"
+msgstr ""
+
+#: java/expr.c:1815
+#, c-format
+msgid "method '%s' not found in class"
+msgstr ""
+
+#: java/expr.c:2020
+#, c-format
+msgid "failed to find class '%s'"
+msgstr ""
+
+#: java/expr.c:2030
+#, c-format
+msgid "class '%s' has no method named '%s' matching signature '%s'"
+msgstr ""
+
+#: java/expr.c:2040
+msgid "invokestatic on non static method"
+msgstr ""
+
+#: java/expr.c:2045
+msgid "invokestatic on abstract method"
+msgstr ""
+
+#: java/expr.c:2053
+msgid "invoke[non-static] on static method"
+msgstr ""
+
+#: java/expr.c:2352
+#, c-format
+msgid "missing field '%s' in '%s'"
+msgstr ""
+
+#: java/expr.c:2358
+#, c-format
+msgid "mismatching signature for field '%s' in '%s'"
+msgstr ""
+
+#: java/expr.c:2380
+msgid "%Jassignment to final field '%D' not in field's class"
+msgstr ""
+
+#: java/expr.c:2385
+msgid "%Jassignment to final static field `%D' not in class initializer"
+msgstr ""
+
+#: java/expr.c:2393
+msgid "%Jassignment to final field '%D' not in constructor"
+msgstr ""
+
+#: java/expr.c:2636
+#, c-format
+msgid "can't expand %s"
+msgstr ""
+
+#: java/expr.c:2808
+msgid "invalid PC in line number table"
+msgstr ""
+
+#: java/expr.c:2854
+#, c-format
+msgid "unreachable bytecode from %d to before %d"
+msgstr ""
+
+#: java/expr.c:2892
+#, c-format
+msgid "unreachable bytecode from %d to the end of the method"
+msgstr ""
+
+#. duplicate code from LOAD macro
+#: java/expr.c:3206
+msgid "unrecogized wide sub-instruction"
+msgstr ""
+
+#: java/jcf-io.c:534
+#, c-format
+msgid "source file for class `%s' is newer than its matching class file. Source file `%s' used instead"
+msgstr ""
+
+#: java/jcf-parse.c:330
+msgid "bad string constant"
+msgstr ""
+
+#: java/jcf-parse.c:348
+#, c-format
+msgid "bad value constant type %d, index %d"
+msgstr ""
+
+#: java/jcf-parse.c:514
+#, fuzzy, c-format
+msgid "can't reopen %s: %m"
+msgstr "no és pot obrir %s"
+
+#: java/jcf-parse.c:519
+#, fuzzy, c-format
+msgid "can't close %s: %m"
+msgstr "no és pot obrir %s"
+
+#: java/jcf-parse.c:604
+#, c-format
+msgid "cannot find file for class %s"
+msgstr ""
+
+#: java/jcf-parse.c:615
+msgid "not a valid Java .class file"
+msgstr ""
+
+#: java/jcf-parse.c:618
+msgid "error while parsing constant pool"
+msgstr ""
+
+#: java/jcf-parse.c:621
+#, c-format
+msgid "error in constant pool entry #%d\n"
+msgstr ""
+
+#. FIXME - where was first time
+#: java/jcf-parse.c:633
+#, c-format
+msgid "reading class %s for the second time from %s"
+msgstr ""
+
+#: java/jcf-parse.c:651
+msgid "error while parsing fields"
+msgstr ""
+
+#: java/jcf-parse.c:654
+msgid "error while parsing methods"
+msgstr ""
+
+#: java/jcf-parse.c:657
+msgid "error while parsing final attributes"
+msgstr ""
+
+#: java/jcf-parse.c:671
+#, c-format
+msgid "the `java.lang.Object' that was found in `%s' didn't have the special zero-length `gnu.gcj.gcj-compiled' attribute. This generally means that your classpath is incorrectly set. Use `info gcj \"Input Options\"' to see the info page describing how to set the classpath"
+msgstr ""
+
+#: java/jcf-parse.c:749
+msgid "missing Code attribute"
+msgstr ""
+
+#: java/jcf-parse.c:981
+msgid "%Hsource file seen twice on command line and will be compiled only once"
+msgstr ""
+
+#: java/jcf-parse.c:996
+msgid "no input file specified"
+msgstr ""
+
+#: java/jcf-parse.c:1025
+#, fuzzy, c-format
+msgid "can't close input file %s: %m"
+msgstr "no es pot tancar el fitxer temporal"
+
+#: java/jcf-parse.c:1063
+#, c-format
+msgid "bad zip/jar file %s"
+msgstr ""
+
+#: java/jcf-parse.c:1235
+#, c-format
+msgid "error while reading %s from zip file"
+msgstr ""
+
+#: java/jcf-write.c:2602
+#, c-format
+msgid "internal error in generate_bytecode_insn - tree code not implemented: %s"
+msgstr ""
+
+#: java/jcf-write.c:2934
+msgid "field initializer type mismatch"
+msgstr ""
+
+#: java/jcf-write.c:3389
+#, fuzzy, c-format
+msgid "can't create directory %s: %m"
+msgstr "no es pot obtenir el directori actual"
+
+#: java/jcf-write.c:3442
+#, fuzzy, c-format
+msgid "can't create %s: %m"
+msgstr "no és pot obrir %s"
+
+#: java/jv-scan.c:185
+msgid "only one of `--print-main', `--list-class', and `--complexity' allowed"
+msgstr ""
+
+#: java/jv-scan.c:188
+#, c-format
+msgid "can't open output file `%s'"
+msgstr ""
+
+#: java/jv-scan.c:222
+#, c-format
+msgid "file not found `%s'"
+msgstr ""
+
+#: java/jvspec.c:418
+msgid "can't specify `-D' without `--main'\n"
+msgstr ""
+
+#: java/jvspec.c:421
+#, c-format
+msgid "`%s' is not a valid class name"
+msgstr ""
+
+#: java/jvspec.c:427
+msgid "--resource requires -o"
+msgstr ""
+
+#: java/jvspec.c:434
+msgid "warning: already-compiled .class files ignored with -C"
+msgstr ""
+
+#: java/jvspec.c:441
+msgid "cannot specify both -C and -o"
+msgstr ""
+
+#: java/jvspec.c:453
+msgid "cannot create temporary file"
+msgstr ""
+
+#: java/jvspec.c:481
+msgid "using both @FILE with multiple files not implemented"
+msgstr ""
+
+#: java/jvspec.c:530
+msgid "cannot specify `main' class when not linking"
+msgstr ""
+
+#: java/lang.c:740
+msgid "can't do dependency tracking with input from stdin"
+msgstr ""
+
+#: java/lang.c:756
+msgid "couldn't determine target name for dependency tracking"
+msgstr ""
+
+#: java/lex.c:303
+#, c-format
+msgid ""
+"unknown encoding: `%s'\n"
+"This might mean that your locale's encoding is not supported\n"
+"by your system's iconv(3) implementation. If you aren't trying\n"
+"to use a particular encoding for your input file, try the\n"
+"`--encoding=UTF-8' option"
+msgstr ""
+
+#: java/mangle.c:89
+#, c-format
+msgid "can't mangle %s"
+msgstr ""
+
+#: java/mangle_name.c:140 java/mangle_name.c:210
+msgid "internal error - invalid Utf8 name"
+msgstr ""
+
+#: ../../gcc/java/parse-scan.y:880 ../../gcc/java/parse.y:949
+#: ../../gcc/java/parse.y:1290 ../../gcc/java/parse.y:1351
+#: ../../gcc/java/parse.y:1555 ../../gcc/java/parse.y:1777
+#: ../../gcc/java/parse.y:1786 ../../gcc/java/parse.y:1797
+#: ../../gcc/java/parse.y:1808 ../../gcc/java/parse.y:1820
+#: ../../gcc/java/parse.y:1835 ../../gcc/java/parse.y:1852
+#: ../../gcc/java/parse.y:1854 ../../gcc/java/parse.y:1935
+#: ../../gcc/java/parse.y:2106 ../../gcc/java/parse.y:2168
+#: ../../gcc/java/parse.y:2320 ../../gcc/java/parse.y:2332
+#: ../../gcc/java/parse.y:2339 ../../gcc/java/parse.y:2346
+#: ../../gcc/java/parse.y:2357 ../../gcc/java/parse.y:2359
+#: ../../gcc/java/parse.y:2397 ../../gcc/java/parse.y:2399
+#: ../../gcc/java/parse.y:2401 ../../gcc/java/parse.y:2422
+#: ../../gcc/java/parse.y:2424 ../../gcc/java/parse.y:2426
+#: ../../gcc/java/parse.y:2442 ../../gcc/java/parse.y:2444
+#: ../../gcc/java/parse.y:2465 ../../gcc/java/parse.y:2467
+#: ../../gcc/java/parse.y:2469 ../../gcc/java/parse.y:2497
+#: ../../gcc/java/parse.y:2499 ../../gcc/java/parse.y:2501
+#: ../../gcc/java/parse.y:2503 ../../gcc/java/parse.y:2521
+#: ../../gcc/java/parse.y:2523 ../../gcc/java/parse.y:2534
+#: ../../gcc/java/parse.y:2545 ../../gcc/java/parse.y:2556
+#: ../../gcc/java/parse.y:2567 ../../gcc/java/parse.y:2578
+#: ../../gcc/java/parse.y:2591 ../../gcc/java/parse.y:2595
+#: ../../gcc/java/parse.y:2597 ../../gcc/java/parse.y:2610
+msgid "Missing term"
+msgstr ""
+
+#: ../../gcc/java/parse-scan.y:882 ../../gcc/java/parse.y:721
+#: ../../gcc/java/parse.y:759 ../../gcc/java/parse.y:784
+#: ../../gcc/java/parse.y:970 ../../gcc/java/parse.y:1325
+#: ../../gcc/java/parse.y:1531 ../../gcc/java/parse.y:1533
+#: ../../gcc/java/parse.y:1762 ../../gcc/java/parse.y:1788
+#: ../../gcc/java/parse.y:1799 ../../gcc/java/parse.y:1810
+#: ../../gcc/java/parse.y:1822 ../../gcc/java/parse.y:1837
+msgid "';' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:719 ../../gcc/java/parse.y:757
+msgid "Missing name"
+msgstr ""
+
+#: ../../gcc/java/parse.y:782
+msgid "'*' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:796
+msgid "Class or interface declaration expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:833 ../../gcc/java/parse.y:835
+msgid "Missing class name"
+msgstr ""
+
+#: ../../gcc/java/parse.y:838 ../../gcc/java/parse.y:842
+#: ../../gcc/java/parse.y:850 ../../gcc/java/parse.y:1010
+#: ../../gcc/java/parse.y:1271 ../../gcc/java/parse.y:1273
+#: ../../gcc/java/parse.y:1597 ../../gcc/java/parse.y:1848
+#: ../../gcc/java/parse.y:1880 ../../gcc/java/parse.y:1942
+msgid "'{' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:852
+msgid "Missing super class name"
+msgstr ""
+
+#: ../../gcc/java/parse.y:862 ../../gcc/java/parse.y:878
+msgid "Missing interface name"
+msgstr ""
+
+#: ../../gcc/java/parse.y:964
+msgid "Missing variable initializer"
+msgstr ""
+
+#: ../../gcc/java/parse.y:981
+msgid "Invalid declaration"
+msgstr ""
+
+#: ../../gcc/java/parse.y:984 ../../gcc/java/parse.y:1069
+#: ../../gcc/java/parse.y:2143 ../../gcc/java/parse.y:2165
+#: ../../gcc/java/parse.y:2169 ../../gcc/java/parse.y:2204
+#: ../../gcc/java/parse.y:2281 ../../gcc/java/parse.y:2291
+msgid "']' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:988
+msgid "Unbalanced ']'"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1024
+msgid "Invalid method declaration, method name required"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1029 ../../gcc/java/parse.y:1034
+#: ../../gcc/java/parse.y:1039 ../../gcc/java/parse.y:2026
+msgid "Identifier expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1044
+msgid "Invalid method declaration, return type required"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1067 ../../gcc/java/parse.y:1511
+#: ../../gcc/java/parse.y:1518 ../../gcc/java/parse.y:1527
+#: ../../gcc/java/parse.y:1529 ../../gcc/java/parse.y:1557
+#: ../../gcc/java/parse.y:1665 ../../gcc/java/parse.y:1971
+#: ../../gcc/java/parse.y:2024
+msgid "')' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1083
+msgid "Missing formal parameter term"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1098 ../../gcc/java/parse.y:1103
+msgid "Missing identifier"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1123 ../../gcc/java/parse.y:1132
+msgid "Missing class type term"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1288
+msgid "Invalid interface type"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1475 ../../gcc/java/parse.y:1644
+#: ../../gcc/java/parse.y:1646
+msgid "':' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1497 ../../gcc/java/parse.y:1502
+#: ../../gcc/java/parse.y:1507
+msgid "Invalid expression statement"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1525 ../../gcc/java/parse.y:1553
+#: ../../gcc/java/parse.y:1593 ../../gcc/java/parse.y:1661
+#: ../../gcc/java/parse.y:1729 ../../gcc/java/parse.y:1850
+#: ../../gcc/java/parse.y:1928 ../../gcc/java/parse.y:2018
+#: ../../gcc/java/parse.y:2020 ../../gcc/java/parse.y:2028
+#: ../../gcc/java/parse.y:2264 ../../gcc/java/parse.y:2266
+msgid "'(' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1595
+msgid "Missing term or ')'"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1642
+msgid "Missing or invalid constant expression"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1663
+msgid "Missing term and ')' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1702
+msgid "Invalid control expression"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1704 ../../gcc/java/parse.y:1706
+msgid "Invalid update expression"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1731
+msgid "Invalid init statement"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1931
+msgid "Missing term or ')' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1973
+msgid "'class' or 'this' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:1975 ../../gcc/java/parse.y:1977
+msgid "'class' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2022
+msgid "')' or term expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2141
+msgid "'[' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2219
+msgid "Field expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2276 ../../gcc/java/parse.y:2286
+msgid "Missing term and ']' expected"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2390
+msgid "']' expected, invalid type expression"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2393
+msgid "Invalid type expression"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2505
+msgid "Invalid reference type"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2977
+msgid "Constructor invocation must be first thing in a constructor"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2979
+msgid "Only constructors can invoke constructors"
+msgstr ""
+
+#: ../../gcc/java/parse.y:2987
+#, c-format
+msgid ": `%s' JDK1.1(TM) feature"
+msgstr ""
+
+#: ../../gcc/java/parse.y:3046 ../../gcc/java/parse.y:3048
+#, c-format
+msgid ""
+"%s.\n"
+"%s"
+msgstr ""
+
+#: ../../gcc/java/parse.y:6909
+#, c-format
+msgid "malformed .zip archive in CLASSPATH: %s"
+msgstr ""
+
+#: ../../gcc/java/parse.y:6980
+#, c-format
+msgid "Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives"
+msgstr ""
+
+#: ../../gcc/java/parse.y:12193
+#, c-format
+msgid "missing static field `%s'"
+msgstr ""
+
+#: ../../gcc/java/parse.y:12198
+#, c-format
+msgid "not a static field `%s'"
+msgstr ""
+
+#: ../../gcc/java/parse.y:12241
+#, c-format
+msgid "No case for %s"
+msgstr ""
+
+#: ../../gcc/java/parse.y:13173
+#, c-format
+msgid "unregistered operator %s"
+msgstr ""
+
+#: java/typeck.c:530
+msgid "junk at end of signature string"
+msgstr ""
+
+#: java/verify.c:471
+msgid "bad pc in exception_table"
+msgstr ""
+
+#: java/verify.c:1384
+#, c-format
+msgid "unknown opcode %d@pc=%d during verification"
+msgstr ""
+
+#: java/verify.c:1454 java/verify.c:1467 java/verify.c:1471
+#, c-format
+msgid "verification error at PC=%d"
+msgstr ""
+
+#: objc/objc-act.c:689
+#, c-format
+msgid "object does not conform to the `%s' protocol"
+msgstr ""
+
+#: objc/objc-act.c:775 objc/objc-act.c:848
+#, c-format
+msgid "class `%s' does not implement the `%s' protocol"
+msgstr ""
+
+#: objc/objc-act.c:951
+#, c-format
+msgid "statically allocated instance of Objective-C class `%s'"
+msgstr ""
+
+#: objc/objc-act.c:998
+#, c-format
+msgid "unexpected type for `id' (%s)"
+msgstr ""
+
+#: objc/objc-act.c:1003
+msgid "undefined type `id', please import <objc/objc.h>"
+msgstr ""
+
+#: objc/objc-act.c:1052
+#, c-format
+msgid "protocol `%s' has circular dependency"
+msgstr ""
+
+#: objc/objc-act.c:1074 objc/objc-act.c:5982
+#, c-format
+msgid "cannot find protocol declaration for `%s'"
+msgstr ""
+
+#: objc/objc-act.c:1408 objc/objc-act.c:2645 objc/objc-act.c:6513
+#: objc/objc-act.c:6822 objc/objc-act.c:6875 objc/objc-act.c:6900
+#, c-format
+msgid "cannot find interface declaration for `%s'"
+msgstr ""
+
+#: objc/objc-act.c:1423
+#, fuzzy, c-format
+msgid "interface `%s' does not have valid constant string layout"
+msgstr "l'argument de \"asm\" no és una cadena constant"
+
+#: objc/objc-act.c:1439
+#, c-format
+msgid "cannot find reference tag for class `%s'"
+msgstr ""
+
+#: objc/objc-act.c:2179
+#, c-format
+msgid "creating selector for non existant method %s"
+msgstr ""
+
+#: objc/objc-act.c:2389
+#, fuzzy, c-format
+msgid "`%s' is not an Objective-C class name or alias"
+msgstr "\"%T\" no és una classa o un espai de noms"
+
+#: objc/objc-act.c:2500 objc/objc-act.c:2518 objc/objc-act.c:6769
+#: objc/objc-act.c:7059 objc/objc-act.c:7088
+msgid "Objective-C declarations may only appear in global scope"
+msgstr ""
+
+#: objc/objc-act.c:2505
+#, c-format
+msgid "cannot find class `%s'"
+msgstr ""
+
+#: objc/objc-act.c:2507
+#, c-format
+msgid "class `%s' already exists"
+msgstr ""
+
+#: objc/objc-act.c:2532 objc/objc-act.c:6791
+#, c-format
+msgid "`%s' redeclared as different kind of symbol"
+msgstr "\"%s\" redeclarat com un tipus diferent de símbol"
+
+#. fatal did not work with 2 args...should fix
+#: objc/objc-act.c:2680
+#, c-format
+msgid "cannot find interface declaration for `%s', superclass of `%s'"
+msgstr ""
+
+#: objc/objc-act.c:2687
+#, c-format
+msgid "circular inheritance in interface declaration for `%s'"
+msgstr ""
+
+#: objc/objc-act.c:2780 objc/objc-act.c:2924 objc/objc-act.c:3024
+#: objc/objc-act.c:3200 objc/objc-act.c:3240
+msgid "Use `-fobjc-exceptions' to enable Objective-C exception syntax"
+msgstr ""
+
+#: objc/objc-act.c:2787
+msgid "`@throw;' (rethrow) used outside of a `@catch' block"
+msgstr ""
+
+#: objc/objc-act.c:3027
+msgid "`@catch' parameter is not a known Objective-C class type"
+msgstr ""
+
+#: objc/objc-act.c:3036
+msgid "Exception already handled by preceding `@catch(id)'"
+msgstr ""
+
+#: objc/objc-act.c:3041
+#, fuzzy, c-format
+msgid "Exception of type `%s *' already handled by `@catch (%s *)'"
+msgstr "l'excepció del tipus \"%T\" serà atrapada"
+
+#: objc/objc-act.c:3206
+msgid "`@try' without `@catch' or `@finally'"
+msgstr ""
+
+#: objc/objc-act.c:3647
+msgid "%Jtype '%D' does not have a known size"
+msgstr ""
+
+#: objc/objc-act.c:4256
+#, fuzzy
+msgid "%J%s `%s'"
+msgstr "En %s \"%s\":"
+
+#: objc/objc-act.c:4281 objc/objc-act.c:4300
+msgid "inconsistent instance variable specification"
+msgstr ""
+
+#: objc/objc-act.c:5303
+msgid "can not use an object as parameter to a method\n"
+msgstr ""
+
+#: objc/objc-act.c:5504
+#, fuzzy, c-format
+msgid "multiple %s named `%c%s' found"
+msgstr "múltiples paràmetres nomenats \"%s\""
+
+#: objc/objc-act.c:5721
+#, fuzzy, c-format
+msgid "no super class declared in @interface for `%s'"
+msgstr "no hi ha declaració prèvia per a \"%s\""
+
+#: objc/objc-act.c:5809
+#, c-format
+msgid "invalid receiver type `%s'"
+msgstr ""
+
+#: objc/objc-act.c:5820
+#, fuzzy, c-format
+msgid "`%s' may not respond to `%c%s'"
+msgstr "\"%s\" no té suport per a %s"
+
+#: objc/objc-act.c:5825
+#, c-format
+msgid "`%c%s' not implemented by protocol(s)"
+msgstr ""
+
+#: objc/objc-act.c:5830
+msgid "(Messages without a matching method signature"
+msgstr ""
+
+#: objc/objc-act.c:5831
+msgid "will be assumed to return `id' and accept"
+msgstr ""
+
+#: objc/objc-act.c:5832
+#, fuzzy
+msgid "`...' as arguments.)"
+msgstr "sense arguments"
+
+#: objc/objc-act.c:6079
+#, c-format
+msgid "undeclared selector `%s'"
+msgstr "selector \"%s\" sense declarar"
+
+#. Historically, a class method that produced objects (factory
+#. method) would assign `self' to the instance that it
+#. allocated. This would effectively turn the class method into
+#. an instance method. Following this assignment, the instance
+#. variables could be accessed. That practice, while safe,
+#. violates the simple rule that a class method should not refer
+#. to an instance variable. It's better to catch the cases
+#. where this is done unknowingly than to support the above
+#. paradigm.
+#: objc/objc-act.c:6121
+#, c-format
+msgid "instance variable `%s' accessed in class method"
+msgstr ""
+
+#: objc/objc-act.c:6327
+#, fuzzy, c-format
+msgid "duplicate declaration of method `%c%s'"
+msgstr "declaració implícita de la funció \"%s\""
+
+#: objc/objc-act.c:6368
+#, c-format
+msgid "duplicate interface declaration for category `%s(%s)'"
+msgstr ""
+
+#: objc/objc-act.c:6398
+#, fuzzy, c-format
+msgid "illegal reference type specified for instance variable `%s'"
+msgstr "s'ignora el especificador asm per a la variable local no estàtica \"%s\""
+
+#: objc/objc-act.c:6414
+#, fuzzy, c-format
+msgid "instance variable `%s' has unknown size"
+msgstr "la variable estàtica \"%s\" està marcada com dllimport"
+
+#. vtable pointers are Real Bad(tm), since Obj-C cannot initialize them
+#: objc/objc-act.c:6428
+#, fuzzy, c-format
+msgid "type `%s' has virtual member functions"
+msgstr " ja que el tipus \"%T\" té funcions virtuals abstractes"
+
+#: objc/objc-act.c:6429
+#, fuzzy, c-format
+msgid "illegal aggregate type `%s' specified for instance variable `%s'"
+msgstr "s'ignora el especificador asm per a la variable local no estàtica \"%s\""
+
+#: objc/objc-act.c:6437
+#, fuzzy, c-format
+msgid "type `%s' has a user-defined constructor"
+msgstr "el tipus \"%T\" no té destructor"
+
+#: objc/objc-act.c:6439
+#, fuzzy, c-format
+msgid "type `%s' has a user-defined destructor"
+msgstr "el tipus \"%T\" no té destructor"
+
+#: objc/objc-act.c:6440
+msgid "C++ constructors and destructors will not be invoked for Objective-C fields"
+msgstr ""
+
+#: objc/objc-act.c:6490
+#, c-format
+msgid "instance variable `%s' is declared private"
+msgstr ""
+
+#: objc/objc-act.c:6539
+#, c-format
+msgid "instance variable `%s' is %s; this will be a hard error in the future"
+msgstr ""
+
+#: objc/objc-act.c:6546
+#, c-format
+msgid "instance variable `%s' is declared %s"
+msgstr ""
+
+#: objc/objc-act.c:6556
+msgid "static access to object of type `id'"
+msgstr ""
+
+#: objc/objc-act.c:6578 objc/objc-act.c:6666
+#, c-format
+msgid "incomplete implementation of class `%s'"
+msgstr ""
+
+#: objc/objc-act.c:6582 objc/objc-act.c:6671
+#, c-format
+msgid "incomplete implementation of category `%s'"
+msgstr ""
+
+#: objc/objc-act.c:6587 objc/objc-act.c:6676
+#, c-format
+msgid "method definition for `%c%s' not found"
+msgstr ""
+
+#: objc/objc-act.c:6717
+#, c-format
+msgid "%s `%s' does not fully implement the `%s' protocol"
+msgstr ""
+
+#: objc/objc-act.c:6775 objc/objc-act.c:8803
+msgid "`@end' missing in implementation context"
+msgstr ""
+
+#: objc/objc-act.c:6805
+#, c-format
+msgid "reimplementation of class `%s'"
+msgstr ""
+
+#: objc/objc-act.c:6836
+#, c-format
+msgid "conflicting super class name `%s'"
+msgstr ""
+
+#: objc/objc-act.c:6838
+#, c-format
+msgid "previous declaration of `%s'"
+msgstr "declaració prèvia de \"%s\""
+
+#: objc/objc-act.c:6852 objc/objc-act.c:6854
+#, c-format
+msgid "duplicate interface declaration for class `%s'"
+msgstr ""
+
+#: objc/objc-act.c:7121
+#, c-format
+msgid "duplicate declaration for protocol `%s'"
+msgstr ""
+
+#. Add a readable method name to the warning.
+#: objc/objc-act.c:7613
+#, fuzzy
+msgid "%J%s `%c%s'"
+msgstr "En %s \"%s\":"
+
+#: objc/objc-act.c:7908
+#, c-format
+msgid "no super class declared in interface for `%s'"
+msgstr ""
+
+#: objc/objc-act.c:7956
+msgid "[super ...] must appear in a method context"
+msgstr ""
+
+#: objc/objc-parse.y:2700
+msgid "`@end' must appear in an implementation context"
+msgstr ""
+
+#: objc/objc-parse.y:2913
+msgid "method definition not in class context"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:21
+#, fuzzy
+msgid "Display this information"
+msgstr " --help Mostra aquesta informació\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:27
+msgid "--param <param>=<value>\tSet paramter <param> to value. See below for a complete list of parameters"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:36
+msgid "-A<question>=<answer>\tAssert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:39
+#, fuzzy
+msgid "Do not discard comments"
+msgstr "No desactivar registres d'espai"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:42
+msgid "Do not discard comments in macro expansions"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:45
+msgid "-D<macro>[=<val>]\tDefine a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:51
+#, fuzzy
+msgid "-G<number>\tPut global and static data smaller than <number> bytes into a special section (on some targets)"
+msgstr ""
+" -G <nombre> Col·locar les dades globals i estàtics més petits que <nombre>\n"
+" octets en una secció especial (en alguns objectius)\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:54
+#, fuzzy
+msgid "Print the name of header files as they are used"
+msgstr "Mostrar els noms de les unitats de programa mentre són compilades"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:57
+msgid "-I <dir>\tAdd <dir> to the end of the main include path. -I- gives more include path control; see info documentation"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:60
+#, fuzzy
+msgid "Generate make dependencies"
+msgstr "dependències dinàmiques.\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:63
+#, fuzzy
+msgid "Generate make dependencies and compile"
+msgstr "Generar codi little endian"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:66
+msgid "-MF <file>\tWrite dependency output to the given file"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:69
+msgid "Treat missing header files as generated files"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:72
+msgid "Like -M but ignore system header files"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:75
+msgid "Like -MD but ignore system header files"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:78
+#, fuzzy
+msgid "Generate phony targets for all headers"
+msgstr "Generar codi com de Intel"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:81
+msgid "-MQ <target>\tAdd a MAKE-quoted target"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:84
+msgid "-MT <target>\tAdd an unquoted target"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:87
+#, fuzzy
+msgid "-O<number>\tSet optimization level to <number>"
+msgstr " -O[nombre] Establir el nivell d'optimització a [nombre]\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:90
+#, fuzzy
+msgid "Optimize for space rather than speed"
+msgstr " -Os Optimitzar per a espai en lloc de velocitat\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:93
+#, fuzzy
+msgid "Do not generate #line directives"
+msgstr "No generar directives .size"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:96
+msgid "-U<macro>\tUndefine <macro>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:99
+msgid "This switch is deprecated; use -Wextra instead"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:105
+msgid "Warn about returning structures, unions or arrays"
+msgstr "Avisar sobre la devolució d'estructures, unions o matrius"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:108
+msgid "Enable most warning messages"
+msgstr "Activar gairebé tots els missatges d'avís"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:111
+msgid "Warn about casting functions to incompatible types"
+msgstr "Avisar per funcions de conversió a tipus incompatibles"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:114
+msgid "Warn about pointer casts which increase alignment"
+msgstr "Avisar sobre conversió de punters que incrementi l'alineació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:117
+msgid "Warn about casts which discard qualifiers"
+msgstr "Avisar sobre conversions que descarten calificators"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:120
+#, fuzzy
+msgid "Warn about subscripts whose type is \"char\""
+msgstr "Avisar sobre subindicis el tipus del qual és \"char\""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:123
+msgid "Warn about possibly nested block comments, and C++ comments spanning more than one physical line"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:126
+msgid "Synonym for -Wcomment"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:129
+msgid "Warn about possibly confusing type conversions"
+msgstr "Avisar sobre la possibilitat de conversió de tipus confuses"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:132
+#, fuzzy
+msgid "Warn when all constructors and destructors are private"
+msgstr "No avisar quan tots els ctors/dtors són privats"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:135
+#, fuzzy
+msgid "Warn when a declaration is found after a statement"
+msgstr "Avisar quan una declaració no especifiqui un tipus"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:138
+#, fuzzy
+msgid "Warn about deprecated compiler features"
+msgstr "No anunciar característiques obsoletes del compilador"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:141
+msgid "Warn about uses of __attribute__((deprecated)) declarations"
+msgstr "Avisar sobre el ùs de declaracions __attribute__((deprecated))"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:144
+msgid "Warn when an optimization pass is disabled"
+msgstr "Avisar quan es va desactivar un pas d'optimització"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:147
+#, fuzzy
+msgid "Warn about compile-time integer division by zero"
+msgstr "No avisar sobre la divisió entera per zero en temps de compilació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:150
+msgid "Warn about violations of Effective C++ style rules"
+msgstr "Avisar violacions de regles d'estil de Effective C++"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:153
+msgid "Warn about stray tokens after #elif and #endif"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:156
+msgid "Treat all warnings as errors"
+msgstr "Tractar tots els avisos com errors"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:159
+#, fuzzy
+msgid "Make implicit function declarations an error"
+msgstr "Avisar sobre la declaració implícita de funcions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:162
+msgid "Print extra (possibly unwanted) warnings"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:165
+#, fuzzy
+msgid "Warn if testing floating point numbers for equality"
+msgstr "Avisar sobre l'equitat de proves de nombres de coma flotant"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:168
+#, fuzzy
+msgid "Warn about printf/scanf/strftime/strfmon format string anomalies"
+msgstr "Avisar sobre anomalies de format de printf/scanf/strftime/strfmon"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:171
+#, fuzzy
+msgid "Warn if passing too many arguments to a function for its format string"
+msgstr "massa arguments per a la funció \"va_start\""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:174
+#, fuzzy
+msgid "Warn about format strings that are not literals"
+msgstr "Avisar sobre l'ús de literals multicaràcters"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:177
+msgid "Warn about possible security problems with format functions"
+msgstr "Avisar sobre possibles problemes de seguretat amb funcions de format"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:180
+#, fuzzy
+msgid "Warn about strftime formats yielding 2-digit years"
+msgstr "No avisar sobre formats de strftime que produeixen dos dígits per a l'any"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:192
+msgid "Warn about implicit function declarations"
+msgstr "Avisar sobre la declaració implícita de funcions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:195
+msgid "Warn when a declaration does not specify a type"
+msgstr "Avisar quan una declaració no especifiqui un tipus"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:198
+msgid "Deprecated. This switch has no effect."
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:201
+msgid "Warn about variables which are initialized to themselves."
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:204
+msgid "Warn when an inlined function cannot be inlined"
+msgstr "Avisar quan una funció inline no pot ser inline"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:207
+#, fuzzy
+msgid "Warn about invalid uses of the \"offsetof\" macro"
+msgstr "Avisar sobre l'ús de la directiva #import"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:210
+msgid "Warn about PCH files that are found but not used"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:213
+#, fuzzy
+msgid "-Wlarger-than-<number>\tWarn if an object is larger than <number> bytes"
+msgstr " -Wlarger-than-<nombre> Avisar si un objecte és més gran que <nombre> octets\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:216
+#, fuzzy
+msgid "Do not warn about using \"long long\" when -pedantic"
+msgstr "No avisar sobre l'ús de \"long long\" quan s'usi -pedantic"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:219
+#, fuzzy
+msgid "Warn about suspicious declarations of \"main\""
+msgstr "Avisar sobre declaracions sospitoses de main"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:222
+msgid "Warn about possibly missing braces around initializers"
+msgstr "Avisar sobre possibles claus faltantes al voltant d'assignadorsº"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:225
+#, fuzzy
+msgid "Warn about global functions without previous declarations"
+msgstr "Avisar sobre funcions globals sense declaracions prèvies"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:228
+msgid "Warn about functions which might be candidates for format attributes"
+msgstr "Avisar per funcions que podrien ser candidates per a atributs de format"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:231
+#, fuzzy
+msgid "Warn about functions which might be candidates for __attribute__((noreturn))"
+msgstr "Avisar sobre funcions que podrien ser candidates per a l'atribut noreturn"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:234
+#, fuzzy
+msgid "Warn about global functions without prototypes"
+msgstr "Avisar sobre funcions globals sense prototips"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:237
+#, fuzzy
+msgid "Warn about use of multi-character character constants"
+msgstr "Avisar sobre l'ús de literals multicaràcters"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:240
+#, fuzzy
+msgid "Warn about \"extern\" declarations not at file scope"
+msgstr "Avisar sobre externs que no estan en el nivell de l'abast del fitxer"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:243
+#, fuzzy
+msgid "Warn when non-templatized friend functions are declared within a template"
+msgstr "No avisar quan les funcions friend sense patró són declarades dintre d'un patró"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:246
+#, fuzzy
+msgid "Warn about non-virtual destructors"
+msgstr "Avisar sobre destructors no virtuals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:252
+#, fuzzy
+msgid "Warn if a C-style cast is used in a program"
+msgstr "Avisar quan s'usi una conversió d'estil C en un programa"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:255
+#, fuzzy
+msgid "Warn if an old-style parameter definition is used"
+msgstr "Avisar quan no s'usi un paràmetre d'una funció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:258
+msgid "Warn about overloaded virtual function names"
+msgstr "Avisar sobre noms de funcions virtual sobrecarregades"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:261
+msgid "Warn when the packed attribute has no effect on struct layout"
+msgstr "Avisar quan l'atribut packed no té efecte en la disposició d'un struct"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:264
+#, fuzzy
+msgid "Warn when padding is required to align structure members"
+msgstr "Avisar quan es requereix farcit per a alinear als membres d'un struct"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:267
+#, fuzzy
+msgid "Warn about possibly missing parentheses"
+msgstr "Avisar sobre possibles parèntesis faltantes"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:270
+#, fuzzy
+msgid "Warn when converting the type of pointers to member functions"
+msgstr "avisar quan el tipus converteix punters a funcions membre"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:273
+msgid "Warn about function pointer arithmetic"
+msgstr "Avisar sobre l'aritmètica de punters de funcions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:276
+#, fuzzy
+msgid "Warn if inherited methods are unimplemented"
+msgstr "Avisar si es detecten comentaris niats"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:279
+msgid "Warn about multiple declarations of the same object"
+msgstr "Avisar sobre declaracions múltiples del mateix objecte"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:282
+msgid "Warn when the compiler reorders code"
+msgstr "Avisar quan el compilador reordeni codi"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:285
+#, fuzzy
+msgid "Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)"
+msgstr "Avisar quan el tipus de devolució per defecte d'una funció canvia a int"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:288
+msgid "Warn if a selector has multiple methods"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:291
+msgid "Warn about possible violations of sequence point rules"
+msgstr "Avisar sobre possibles violacions a les regles de seqüència de punt"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:294
+msgid "Warn when one local variable shadows another"
+msgstr "Avisar quan una variable local enfosque una altra"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:297
+#, fuzzy
+msgid "Warn about signed-unsigned comparisons"
+msgstr "Avisar sobre comparances signed/unsigned"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:300
+msgid "Warn when overload promotes from unsigned to signed"
+msgstr "Avisar quan la sobrecàrrega promogui de unsigned a signed"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:303
+#, fuzzy
+msgid "Warn about code which might break strict aliasing rules"
+msgstr "Avisar sobre codi que pugui trencar les regles estrictes d'aliessis"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:306
+#, fuzzy
+msgid "Warn about unprototyped function declarations"
+msgstr "Avisar sobre declaracions de funció sense prototip"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:309
+msgid "Warn about enumerated switches, with no default, missing a case"
+msgstr "Avisar sobre interruptors enumerats, sense valor per defecte, que manquin d'un casi"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:312
+#, fuzzy
+msgid "Warn about enumerated switches missing a \"default:\" statement"
+msgstr "Avisar sobre interruptors enumerats que manquin d'un casi per defecte"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:315
+msgid "Warn about all enumerated switches missing a specific case"
+msgstr "Avisar sobre tots els interruptors enumerats que manquin d'un casi específic"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:318
+msgid "Warn when synthesis behavior differs from Cfront"
+msgstr "Avisar quan el comportament de síntesi difereixi de Cfront"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:321
+msgid "Do not suppress warnings from system headers"
+msgstr "No suprimir els avisos dels encapçalats del sistema"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:324
+#, fuzzy
+msgid "Warn about features not present in traditional C"
+msgstr "es suggereix no usar #elif en C tradicional"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:327
+msgid "Warn if trigraphs are encountered that might affect the meaning of the program"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:333
+#, fuzzy
+msgid "Warn if an undefined macro is used in an #if directive"
+msgstr "directiva # no definida o invàlida"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:336
+msgid "Warn about uninitialized automatic variables"
+msgstr "Avisar sobre variables automàtiques sense iniciar"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:339
+msgid "Warn about unrecognized pragmas"
+msgstr "Avisar sobre pragmas no reconeguts"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:342
+msgid "Warn about code that will never be executed"
+msgstr "Avisar sobre codi que mai s'executarà"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:345
+msgid "Enable all -Wunused- warnings"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:348
+msgid "Warn when a function is unused"
+msgstr "Avisar quan no s'usi una funció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:351
+msgid "Warn when a label is unused"
+msgstr "Avisar quan no s'usi una etiqueta"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:354
+msgid "Warn about macros defined in the main file that are not used"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:357
+msgid "Warn when a function parameter is unused"
+msgstr "Avisar quan no s'usi un paràmetre d'una funció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:360
+msgid "Warn when an expression value is unused"
+msgstr "Avisar quan no s'usi un valor d'una expressió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:363
+msgid "Warn when a variable is unused"
+msgstr "Avisar quan no s'usi una variable"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:366
+msgid "Give strings the type \"array of char\""
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:369
+msgid "A synonym for -std=c89. In a future version of GCC it will become synonymous with -std=c99 instead"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:372
+#, fuzzy
+msgid "-aux-info <file>\tEmit declaration information into <file>"
+msgstr " -aux-info <fitxer> Emetre la informació de declaracions en el <fitxer>\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:384
+#, fuzzy
+msgid "-d<letters>\tEnable dumps from specific passes of the compiler"
+msgstr " -d[lletres] Activa els bolcats des de passos específics del compilador\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:387
+#, fuzzy
+msgid "-dumpbase <file>\tSet the file basename to be used for dumps"
+msgstr " -dumpbase <fitxer> Nom base a usar per als bolcats des de passos específics\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:399
+#, fuzzy
+msgid "Enforce class member access control semantics"
+msgstr "No obeir les semàntiques de control d'accés"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:402
+msgid "Align the start of functions"
+msgstr "Alinear l'inici de les funcions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:408
+msgid "Align labels which are only reached by jumping"
+msgstr "Alinear les etiquetes que solament s'arriben a saltant"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:414
+msgid "Align all labels"
+msgstr "Alinear totes les etiquetes"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:420
+msgid "Align the start of loops"
+msgstr "Alinear l'inici dels cicles"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:429
+msgid "Change when template instances are emitted"
+msgstr "Canviar quan s'emetin les instàncies del patró"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:432
+#, fuzzy
+msgid "Specify that arguments may alias each other and globals"
+msgstr "Especifica que els arguments poden ser alies de cada altre i dels globals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:435
+msgid "Assume arguments may alias globals but not each other"
+msgstr "Assumir que els arguments poden ser alies de globals però no de cada altre"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:438
+#, fuzzy
+msgid "Assume arguments alias neither each other nor globals"
+msgstr "Assumir que els arguments no poden ser alies de globals o de cada altre"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:441
+#, fuzzy
+msgid "Recognize the \"asm\" keyword"
+msgstr "No reconèixer la paraula clau \"asm\""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:444
+#, fuzzy
+msgid "Generate unwind tables that are exact at each instruction boundary"
+msgstr "Generar matrius de desembolico exactament en cada límit d'instrucció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:447
+msgid "Generate code to check bounds before indexing arrays"
+msgstr "Generar codi per a revisar els límits abans de matrius"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:450
+#, fuzzy
+msgid "Replace add, compare, branch with branch on count register"
+msgstr "Reemplaçar add,compare,branch per branch en el compte de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:453
+msgid "Use profiling information for branch probabilities"
+msgstr "Usar la informació d'anàlisi de perfil per a les probabilitats de ramificació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:456
+msgid "Perform branch target load optimization before prologue / epilogue threading"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:459
+msgid "Perform branch target load optimization after prologue / epilogue threading"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:462
+#, fuzzy
+msgid "Recognize built-in functions"
+msgstr "No reconèixer cap funció interna"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:468
+#, fuzzy
+msgid "-fcall-saved-<register>\tMark <register> as being preserved across functions"
+msgstr " -fcall-saved-<registre> Marca el <registre> com preservat entre funcions\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:471
+#, fuzzy
+msgid "-fcall-used-<register>\tMark <register> as being corrupted by function calls"
+msgstr " -fcall-used-<registre> Marca el <registre> com corrupte per a cridades de funció\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:474
+#, fuzzy
+msgid "Save registers around function calls"
+msgstr "Permetre guardar registres al voltant de cridades de funció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:477
+msgid "Check the return value of new"
+msgstr "Revisar el valor de retorn de new"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:480
+msgid "Do not put uninitialized globals in the common section"
+msgstr "No posar globals sense iniciar en la secció comuna"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:483
+#, fuzzy
+msgid "Allow the arguments of the '?' operator to have different types"
+msgstr "els operants de ?: tenen tipus diferents"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:486
+#, fuzzy
+msgid "Reduce the size of object files"
+msgstr "Reduir la grandària dels fitxers objecte"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:489
+#, fuzzy
+msgid "Make string literals \"const char[]\" not \"char[]\""
+msgstr "Fer que les cadenes literals siguin \"char[]\" en lloc de \"const char[]\""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:492
+msgid "-fconst-string-class=<name>\tUse class <name> for constant strings"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:495
+#, fuzzy
+msgid "Perform a register copy-propagation optimization pass"
+msgstr "Fer el pas d'optimització de còpia-propagació de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:498
+msgid "Perform cross-jumping optimization"
+msgstr "Realitzar optimitzacions de salts creuats"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:501
+msgid "When running CSE, follow jumps to their targets"
+msgstr "Quan s'estigui executant CSE, seguir als salts als seus objectius"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:504
+msgid "When running CSE, follow conditional jumps"
+msgstr "Quan s'estigui executant CSE, seguir als salts condicionals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:507
+#, fuzzy
+msgid "Place data items into their own section"
+msgstr "col·locar els elements de dades en la seva pròpia secció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:510
+#, fuzzy
+msgid "Inline member functions by default"
+msgstr "No fer inline per omissió a les funcions membre"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:513
+msgid "Defer popping functions args from stack until later"
+msgstr "Diferir l'extracció d'arguments de funcions de la pila fins més tard"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:516
+msgid "Attempt to fill delay slots of branch instructions"
+msgstr "Intentar emplenar les ranures de retard de les instruccions de ramificació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:519
+msgid "Delete useless null pointer checks"
+msgstr "Esborrar les revisions de punters nuls sense ús"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:522
+#, fuzzy
+msgid "-fdiagnostics-show-location=[once|every-line]\tHow often to emit source location at the beginning of line-wrapped diagnostics"
+msgstr " -fdiagnostics-show-location=[once | every-line] Indica que tan seguit es deu emetre la informació d'ubicació del codi, com prefix, a l'inici dels diagnòstics quan està activat el cort de línia\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:525
+#, fuzzy
+msgid "Permit '$' as an identifier character"
+msgstr "el format és una cadena de caràcter ampla"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:528
+msgid "-fdump-<type>\tDump various compiler internals to a file"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:531
+msgid "Suppress output of instruction numbers and line number notes in debugging dumps"
+msgstr "Suprimir la sortida de notes de nombres d'instrucció i nombres de línia en els bolcats de depuració"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:537
+msgid "Perform DWARF2 duplicate elimination"
+msgstr "Realitzar l'eliminació de DWARF2 duplicats"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:540
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:543
+msgid "Perform unused type elimination in debug info"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:546
+#, fuzzy
+msgid "Generate code to check exception specifications"
+msgstr "No generar codi per a revisar excepcions d'especificacions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:552
+msgid "Enable exception handling"
+msgstr "Activar el maneig d'excepcions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:555
+msgid "-fexec-charset=<cset>\tConvert all strings and character constants to character set <cset>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:558
+msgid "Perform a number of minor, expensive optimizations"
+msgstr "Realitzar un nombre menor d'optimitzacions costoses"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:567
+msgid "Assume no NaNs or infinities are generated"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:570
+#, fuzzy
+msgid "-ffixed-<register>\tMark <register> as being unavailable to the compiler"
+msgstr " -ffixed-<registre> Marca el <registre> com no disponible per al compilador\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:579
+msgid "Do not store floats in registers"
+msgstr "No guardar floats en els registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:582
+#, fuzzy
+msgid "Scope of for-init-statement variables is local to the loop"
+msgstr "L'àmbit de les variables de la declaració d'inici de for s'estén cap a fora"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:585
+#, fuzzy
+msgid "Copy memory address constants into registers before use"
+msgstr "Copiar les constants d'adreces de memòria en registres abans d'usar-los"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:588
+#, fuzzy
+msgid "Copy memory operands into registers before use"
+msgstr "Copiar els operants de memòria en registres abans d'usar-los"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:591
+#, fuzzy
+msgid "Do not assume that standard C libraries and \"main\" exist"
+msgstr "Assumir que podrien no existir les biblioteques estàndard i main"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:594
+msgid "Allow function addresses to be held in registers"
+msgstr "Permetre que les adreces de les funcions es conserven en registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:597
+#, fuzzy
+msgid "Place each function into its own section"
+msgstr "col·locar cada funció en la seva pròpia secció"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:600
+#, fuzzy
+msgid "Perform global common subexpression elimination"
+msgstr "Realitzar l'eliminació de subexpressions comuns globals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:603
+#, fuzzy
+msgid "Perform redundant load after store elimination in global common subexpression elimination"
+msgstr "Realitzar el moviment de càrrega millorada durant l'eliminació de subexpressions globals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:606
+#, fuzzy
+msgid "Perform enhanced load motion during global common subexpression elimination"
+msgstr "Realitzar el moviment de càrrega millorada durant l'eliminació de subexpressions globals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:609
+#, fuzzy
+msgid "Perform store motion after global common subexpression elimination"
+msgstr "Realitzar el moviment de guardat després de l'eliminació de subexpressions globals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:612
+#, fuzzy
+msgid "Recognize GNU-defined keywords"
+msgstr "No reconèixer les paraules claus definides per GNU"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:615
+msgid "Generate code for GNU runtime environment"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:618
+#, fuzzy
+msgid "Enable guessing of branch probabilities"
+msgstr "Activar la predicció de probabilitats de ramificació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:630
+msgid "Assume normal C execution environment"
+msgstr "Assumir l'ambient normal d'execució C"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:633
+msgid "Enable support for huge objects"
+msgstr "Activar el suport per a objectes enormes"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:636
+msgid "Process #ident directives"
+msgstr "Processar directives #ident"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:639
+msgid "Perform conversion of conditional jumps to branchless equivalents"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:642
+msgid "Perform conversion of conditional jumps to conditional execution"
+msgstr "Realitzar la conversió de salts condicionals a execució condicional"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:645
+msgid "Export functions even if they can be inlined"
+msgstr "Exportar funcions encara si poden ser inline"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:648
+#, fuzzy
+msgid "Emit implicit instantiations of inline templates"
+msgstr "Emetre solament instanciacions explícites de patrons inline"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:651
+#, fuzzy
+msgid "Emit implicit instantiations of templates"
+msgstr "Emetre solament instanciacions explícites de patrons inline"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:654
+msgid "Do not generate .size directives"
+msgstr "No generar directives .size"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:657
+#, fuzzy
+msgid "Pay attention to the \"inline\" keyword"
+msgstr "Parar esment a la paraula clau \"inline\""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:660
+msgid "Integrate simple functions into their callers"
+msgstr "Integrar les funcions simples en els seus invocators"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:666
+#, fuzzy
+msgid "-finline-limit=<number>\tLimit the size of inlined functions to <number>"
+msgstr " -finline-limit=<nombre> Limita la grandària de funcions inline a <nombre>\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:669
+msgid "-finput-charset=<cset> Specify the default character set for source files."
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:672
+#, fuzzy
+msgid "Instrument function entry and exit with profiling calls"
+msgstr "Instrumentar funcions entrada/sortida amb cridades d'anàlisi de perfil"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:675
+#, fuzzy
+msgid "Generate code for functions even if they are fully inlined"
+msgstr "Generar codi per a les funcions encara si estan completament inline"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:678
+msgid "Emit static const variables even if they are not used"
+msgstr "Emetre variables static const encara si no s'usen"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:684
+#, fuzzy
+msgid "Give external symbols a leading underscore"
+msgstr "Els símbols externs tenen un subratllat inicial"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:687
+#, fuzzy
+msgid "Perform loop optimizations"
+msgstr "Realitzar les optimitzacions de cicle"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:690
+msgid "Set errno after built-in math functions"
+msgstr "Establir errno després de les funcions matemàtiques internes"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:693
+#, fuzzy
+msgid "Report on permanent memory allocation"
+msgstr "Reportar l'allotjament en memòria permanent al final de l'execució"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:696
+msgid "Attempt to merge identical constants and constant variables"
+msgstr "Intentar barrejar constants idèntiques i variables constants"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:699
+msgid "Attempt to merge identical constants across compilation units"
+msgstr "Intentar barrejar constants idèntiques a través de les unitats de compilació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:702
+#, fuzzy
+msgid "-fmessage-length=<number>\tLimit diagnostics to <number> characters per line. 0 suppresses line-wrapping"
+msgstr " -fmessage-length=<nombre> Limita la longitud dels missatges de diagnòstic a <nombre> caràcters per línia. 0 suprimeix el cort de línia\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:705
+msgid "Force all loop invariant computations out of loops"
+msgstr "Forçar que totes les computacions invariantes del cicle siguin fora del cicle"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:708
+#, fuzzy
+msgid "Don't warn about uses of Microsoft extensions"
+msgstr "No avisar pedantment sobre els usos d'extensions Microsoft"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:717
+#, fuzzy
+msgid "Use graph-coloring register allocation"
+msgstr "Utilitzar coloració de grafes per a l'allotjament de registres."
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:720
+msgid "Generate code for NeXT (Apple Mac OS X) runtime environment"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:723
+msgid "Assume that receivers of Objective-C messages may be nil"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:726
+msgid "Support synchronous non-call exceptions"
+msgstr "Suport per a excepcions síncrones no de cridades"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:735
+msgid "Enable Objective-C exception and synchronization syntax"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:738
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:978
+msgid "Perform loop unrolling for all loops"
+msgstr "Realitzar el desenrollament del cicle per a tots els cicles"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:741
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:981
+msgid "Perform loop unrolling when iteration count is known"
+msgstr "Realitzar el desenrollament del cicle quan es coneix el compte d'iteració"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:744
+msgid "When possible do not generate stack frames"
+msgstr "Quan sigui possible no generar marcs de pila"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:747
+msgid "Recognize C++ kewords like \"compl\" and \"xor\""
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:750
+#, fuzzy
+msgid "Do the full register move optimization pass"
+msgstr "Fa el pas complet d'optimització de moviment de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:753
+msgid "Optimize sibling and tail recursive calls"
+msgstr "Optimitzar les cridades recursives germanades i d'extrem"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:756
+#, fuzzy
+msgid "Enable optional diagnostics"
+msgstr "Desactivar els diagnòstics opcionals"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:759
+msgid "Pack structure members together without holes"
+msgstr "Empaqueta junts als membres de l'estructura sense forats"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:762
+#, fuzzy
+msgid "Return small aggregates in memory, not registers"
+msgstr "Retornar els agregats \"short\" en memòria, no en registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:768
+#, fuzzy
+msgid "Perform loop peeling"
+msgstr "Realitzar les optimitzacions de cicle"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:771
+msgid "Enable machine specific peephole optimizations"
+msgstr "Activar les optimitzacions de forats específiques de la màquina"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:774
+#, fuzzy
+msgid "Enable an RTL peephole pass before sched2"
+msgstr "Activa una execució de passada de forats rtl abans de sched2"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:777
+msgid "Downgrade conformance errors to warnings"
+msgstr "Degradar els errors de concordança a advertiments"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:780
+#, fuzzy
+msgid "Generate position-independent code if possible"
+msgstr "Generar codi independent de posició, si és possible"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:783
+#, fuzzy
+msgid "Generate position-independent code for executables if possible"
+msgstr "Generar codi independent de posició, si és possible"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:786
+msgid "Generate prefetch instructions, if available, for arrays in loops"
+msgstr "Generar instruccions de precarregament, si estan disponibles, per a matrius en cicles"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:789
+msgid "Treat the input file as already preprocessed"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:792
+msgid "Enable basic program profiling code"
+msgstr "Activar el codi bàsic d'anàlisi de perfil del programa"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:795
+#, fuzzy
+msgid "Insert arc-based program profiling code"
+msgstr "Inserir codi d'anàlisi de perfil basat en el programa arc"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:798
+msgid "Enable common options for generating profile info for profile feedback directed optimizations"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:801
+msgid "Enable common options for performing profile feedback directed optimizations"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:804
+msgid "Insert code to profile values of expressions"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:810
+msgid "-frandom-seed=<string>\tMake compile reproducible using <string>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:813
+msgid "Strength reduce all loop general induction variables"
+msgstr "Enfortir la reducció de totes les variables generals d'inducció de cicle"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:816
+#, fuzzy
+msgid "Return small aggregates in registers"
+msgstr "Retornar els agregats \"short\" en registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:819
+msgid "Enables a register move optimization"
+msgstr "Permet una optimització de moviment de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:822
+#, fuzzy
+msgid "Perform a register renaming optimization pass"
+msgstr "Fer el pas d'optimització de renomenació de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:825
+msgid "Reorder basic blocks to improve code placement"
+msgstr "Reordenar els blocs bàsics per a millorar la ubicació del codi"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:828
+msgid "Reorder functions to improve code placement"
+msgstr "Reordenar les funcions per a millorar la ubicació del codi"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:831
+msgid "Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:834
+msgid "Enable automatic template instantiation"
+msgstr "Activar l'instanciació automàtica de patrons"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:837
+#, fuzzy
+msgid "Add a common subexpression elimination pass after loop optimizations"
+msgstr "Executar un pas CSE abans de les optimitzacions de cicles"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:840
+msgid "Run the loop optimizer twice"
+msgstr "Executar el optimizador de cicles dues vegades"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:843
+msgid "Disable optimizations that assume default FP rounding behavior"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:846
+#, fuzzy
+msgid "Generate run time type descriptor information"
+msgstr "No generar informació del tipus de descriptor en temps d'execució"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:849
+msgid "Enable scheduling across basic blocks"
+msgstr "Activar la calendarització entre blocs bàsics"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:852
+msgid "Allow speculative motion of non-loads"
+msgstr "Permetre el moviment especulatiu de cap càrrega"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:855
+msgid "Allow speculative motion of some loads"
+msgstr "Permetre el moviment especulatiu d'unes càrregues"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:858
+msgid "Allow speculative motion of more loads"
+msgstr "Permetre el moviment especulatiu de més càrregues"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:861
+msgid "Allow premature scheduling of queued insns"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:864
+msgid "Set dependence distance checking in premature scheduling of queued insns"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:867
+msgid "-fsched-stalled-insns-dep=<number> Set dependence distance checking in premature scheduling of queued insns"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:870
+msgid "-fsched-stalled-insns=<number> Set number of queued insns that can be prematurely scheduled"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:873
+#, fuzzy
+msgid "-fsched-verbose=<number>\tSet the verbosity level of the scheduler"
+msgstr " -fsched-verbose=<nombre> Estableix el nivell de detall del calendaritzador\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:876
+msgid "If scheduling post reload, do superblock scheduling"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:879
+msgid "If scheduling post reload, do trace scheduling"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:882
+msgid "Reschedule instructions before register allocation"
+msgstr "Recalendaritzar les instruccions abans de l'allotjament de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:885
+msgid "Reschedule instructions after register allocation"
+msgstr "Recalendaritzar les instruccions després de l'allotjament de registres"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:888
+msgid "Mark data as shared rather than private"
+msgstr "Marcar dades com compartits en lloc de privats"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:891
+msgid "Use the same size for double as for float"
+msgstr "Usar la mateixa grandària per a double que per a float"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:894
+msgid "Use the narrowest integer type possible for enumeration types"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:897
+#, fuzzy
+msgid "Force the underlying type for \"wchar_t\" to be \"unsigned short\""
+msgstr "Fer de costat el tipus sota wchar_t per \"unsigned short\""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:903
+msgid "Disable optimizations observable by IEEE signaling NaNs"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:906
+msgid "When \"signed\" or \"unsigned\" is not given make the bitfield signed"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:909
+#, fuzzy
+msgid "Make \"char\" signed by default"
+msgstr "Fer que \"char\" sigui signed per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:912
+#, fuzzy
+msgid "Convert floating point constants to single precision constants"
+msgstr "Convertir constants de coma flotant a constants de precisió simple"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:918
+msgid "Insert stack checking code into the program"
+msgstr "Insereix codi de revisió de la pila en el programa"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:924
+msgid "-fstack-limit-register=<register>\tTrap if the stack goes past <register>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:927
+msgid "-fstack-limit-symbol=<name>\tTrap if the stack goes past symbol <name>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:930
+msgid "Display statistics accumulated during compilation"
+msgstr "Mostrar les estadístiques acumulades durant la compilació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:933
+msgid "Perform strength reduction optimizations"
+msgstr "Realitzar optimitzacions de reducció de força"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:936
+msgid "Assume strict aliasing rules apply"
+msgstr "Assumir que s'apliquen les regles estrictes d'alies"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:942
+msgid "Check for syntax errors, then stop"
+msgstr "Buscar errors de sintaxi, i aleshores detenir-se"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:945
+msgid "-ftabstop=<number>\tDistance between tab stops for column reporting"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:948
+#, fuzzy
+msgid "-ftemplate-depth-<number>\tSpecify maximum template instantiation depth"
+msgstr "Especificar la profunditat màxima d'instanciació de patrons"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:951
+#, fuzzy
+msgid "Create data files needed by \"gcov\""
+msgstr "Crear fitxers de dades necessàries per a gcov"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:957
+msgid "Perform jump threading optimizations"
+msgstr "Realitzar optimitzacions de filat de salts"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:960
+#, fuzzy
+msgid "Report the time taken by each compiler pass"
+msgstr "Reportar el temps pres per cada pas del compilador al final de l'execució"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:963
+msgid "-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec]\tSet the default thread-local storage code generation model"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:966
+msgid "Perform superblock formation via tail duplication"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:969
+#, fuzzy
+msgid "Assume floating-point operations can trap"
+msgstr "Les operacions de coma flotant poden capturar"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:972
+#, fuzzy
+msgid "Trap for signed overflow in addition, subtraction and multiplication"
+msgstr "Atrapar desbordaments signed en addició / substracció / multiplicació"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:975
+#, fuzzy
+msgid "Compile whole compilation unit at a time"
+msgstr "Buidar la unitat de traducció completa a un fitxer"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:984
+#, fuzzy
+msgid "Allow math optimizations that may violate IEEE or ISO standards"
+msgstr "Permetre optimitzacions matemàtiques que poden violar els estàndards IEEE o ANSI"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:987
+msgid "When \"signed\" or \"unsigned\" is not given make the bitfield unsigned"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:990
+#, fuzzy
+msgid "Make \"char\" unsigned by default"
+msgstr "Fer que \"char\" sigui unsigned per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:993
+#, fuzzy
+msgid "Perform loop unswitching"
+msgstr "Realitzar les optimitzacions de cicle"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:996
+msgid "Just generate unwind tables for exception handling"
+msgstr "Només generar matrius de desembolico per a maneig d'excepcions"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:999
+msgid "Use __cxa_atexit to register destructors"
+msgstr "Usar __cxa_atexit per a registrar destructors"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1002
+msgid "Add extra commentary to assembler output"
+msgstr "Agregar comentaris extra a la sortida del ensemblador"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1005
+#, fuzzy
+msgid "Use expression value profiles in optimizations"
+msgstr "Activar les optimitzacions del enllaçador"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1008
+msgid "Discard unused virtual functions"
+msgstr "Descartar funcions virtual sense usar"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1011
+msgid "Implement vtables using thunks"
+msgstr "Implementar vtables usant thunks"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1014
+msgid "Emit common-like symbols as weak symbols"
+msgstr "Emetre símbols comuns com símbols febles"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1017
+msgid "Construct webs and split unrelated uses of single variable"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1020
+msgid "-fwide-exec-charset=<cset>\tConvert all wide strings and character constants to character set <cset>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1023
+msgid "Generate a #line directive pointing at the current working directory"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1026
+msgid "Assume signed arithmetic overflow wraps around"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1029
+msgid "Store strings in writable data section"
+msgstr "Guardar les cadenes en la secció de dades modificables"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1032
+msgid "Emit cross referencing information"
+msgstr "Emetre informació de referència creuada"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1035
+msgid "Put zero initialized data in the bss section"
+msgstr "Posar dades inicialitzades a zero en la secció bss"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1038
+msgid "Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1041
+#, fuzzy
+msgid "Generate debug information in default format"
+msgstr "Generar informació de depuració en el format per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1044
+#, fuzzy
+msgid "Generate debug information in COFF format"
+msgstr "Generar informació de depuració en el format per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1047
+#, fuzzy
+msgid "Generate debug information in DWARF v2 format"
+msgstr "Generar informació de depuració en el format per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1050
+#, fuzzy
+msgid "Dump declarations to a .decl file"
+msgstr "la declaració no declara res"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1053
+#, fuzzy
+msgid "Generate debug information in default extended format"
+msgstr "Generar informació de depuració en el format estès per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1056
+#, fuzzy
+msgid "Generate debug information in STABS format"
+msgstr "Generar informació de depuració en el format per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1059
+#, fuzzy
+msgid "Generate debug information in extended STABS format"
+msgstr "Generar informació de depuració en el format estès per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1062
+#, fuzzy
+msgid "Generate debug information in VMS format"
+msgstr "Generar informació de depuració en el format per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1065
+#, fuzzy
+msgid "Generate debug information in XCOFF format"
+msgstr "Generar informació de depuració en el format per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1068
+#, fuzzy
+msgid "Generate debug information in extended XCOFF format"
+msgstr "Generar informació de depuració en el format estès per omissió"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1071
+msgid "-idirafter <dir>\tAdd <dir> to the end of the system include path"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1074
+msgid "-imacros <file>\tAccept definition of macros in <file>"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1077
+msgid "-include <file>\tInclude the contents of <file> before other files"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1080
+msgid "-iprefix <path>\tSpecify <path> as a prefix for next two options"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1083
+msgid "-isysroot <dir>\tSet <dir> to be the system root directory"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1086
+msgid "-isystem <dir>\tAdd <dir> to the start of the system include path"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1089
+msgid "-iwithprefix <dir>\tAdd <dir> to the end of the system include path"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1092
+msgid "-iwithprefixbefore <dir>\tAdd <dir> to the end of the main include path"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1104
+msgid "Do not search standard system include directories (those specified with -isystem will still be used)"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1107
+msgid "Do not search standard system include directories for C++"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1110
+#, fuzzy
+msgid "-o <file>\tPlace output into <file>"
+msgstr " -o <fitxer> Situar la sortida en el <fitxer> \n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1113
+#, fuzzy
+msgid "Enable function profiling"
+msgstr "anàlisi de perfil de les funcions mips16"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1116
+#, fuzzy
+msgid "Issue warnings needed for strict compliance to the standard"
+msgstr " -pedantic Activar els avisos necessaris per a complir estrictament amb ISO C\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1119
+msgid "Like -pedantic but issue them as errors"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1122
+msgid "Generate C header of platform-specific features"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1125
+#, fuzzy
+msgid "Do not display functions compiled or elapsed time"
+msgstr " -quiet No mostrar les funcions compilades o el temps transcorregut\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1128
+#, fuzzy
+msgid "Remap file names when including files"
+msgstr "nom de fitxer buit en #%s"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1131
+msgid "Conform to the ISO 1998 C++ standard"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1134
+msgid "Conform to the ISO 1990 C standard"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1137
+msgid "Conform to the ISO 1999 C standard"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1140
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1161
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1164
+msgid "Deprecated in favor of -std=c99"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1143
+msgid "Conform to the ISO 1998 C++ standard with GNU extensions"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1146
+msgid "Conform to the ISO 1990 C standard with GNU extensions"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1149
+msgid "Conform to the ISO 1999 C standard with GNU extensions"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1152
+msgid "Deprecated in favor of -std=gnu99"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1155
+msgid "Deprecated in favor of -std=c89"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1158
+msgid "Conform to the ISO 1990 C standard as amended in 1994"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1167
+#, fuzzy
+msgid "Enable traditional preprocessing"
+msgstr "Habilitar la prova de la pila"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1170
+msgid "-trigraphs\tSupport ISO C trigraphs"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1173
+msgid "Do not predefine system-specific and GCC-specific macros"
+msgstr ""
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1176
+#, fuzzy
+msgid "Enable verbose output"
+msgstr "Activar la sortida de depuració"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1179
+#, fuzzy
+msgid "Display the compiler's version"
+msgstr " -version Mostra la versió del compilador\n"
+
+#: /home/mitchell/dev/gcc-3.4/objdir/gcc/options.c:1182
+msgid "Suppress warnings"
+msgstr ""
+
+#: config/i386/freebsd-aout.h:215 config/rs6000/sysv4.h:1094
+msgid "`-p' not supported; use `-pg' and gprof(1)"
+msgstr ""
+
+#: f/lang-specs.h:38
+#, fuzzy
+msgid "GCC does not support -C without using -E"
+msgstr "GNU C no dóna suport a -CC sense usar -E"
+
+#: f/lang-specs.h:39
+#, fuzzy
+msgid "GCC does not support -CC without using -E"
+msgstr "GNU C no dóna suport a -CC sense usar -E"
+
+#: config/sparc/linux64.h:208 config/sparc/linux64.h:219
+#: config/sparc/netbsd-elf.h:140 config/sparc/netbsd-elf.h:159
+#: config/sparc/sol2-bi.h:195 config/sparc/sol2-bi.h:205
+msgid "may not use both -m32 and -m64"
+msgstr ""
+
+#: config/i386/mingw32.h:58 config/i386/cygwin.h:70
+msgid "shared and mdll are not compatible"
+msgstr ""
+
+#: config/darwin.h:215
+msgid "-current_version only allowed with -dynamiclib"
+msgstr ""
+
+#: config/darwin.h:218
+msgid "-install_name only allowed with -dynamiclib"
+msgstr ""
+
+#: config/darwin.h:223
+msgid "-bundle not allowed with -dynamiclib"
+msgstr "no es permet -bundle amb -dynamiclib"
+
+#: config/darwin.h:224
+msgid "-bundle_loader not allowed with -dynamiclib"
+msgstr "no es permet -bundle_loader amb -dynamiclib"
+
+#: config/darwin.h:225
+msgid "-client_name not allowed with -dynamiclib"
+msgstr "no es permet -client_name amb -dynamiclib"
+
+#: config/darwin.h:228
+msgid "-force_cpusubtype_ALL not allowed with -dynamiclib"
+msgstr ""
+
+#: config/darwin.h:229
+msgid "-force_flat_namespace not allowed with -dynamiclib"
+msgstr ""
+
+#: config/darwin.h:231
+msgid "-keep_private_externs not allowed with -dynamiclib"
+msgstr ""
+
+#: config/darwin.h:232
+msgid "-private_bundle not allowed with -dynamiclib"
+msgstr "no es permet -private_bundle amb -dynamiclib"
+
+#: config/vax/netbsd-elf.h:42
+msgid "The -shared option is not currently supported for VAX ELF."
+msgstr "L'opció -shared no se suporta actualment per a ELF de VAX."
+
+#: config/vax/vax.h:50 config/vax/vax.h:51
+msgid "profiling not supported with -mg\n"
+msgstr ""
+
+#: config/arc/arc.h:63 config/mips/mips.h:1143
+msgid "may not use both -EB and -EL"
+msgstr ""
+
+#: config/mips/mips.h:988
+msgid "-pipe is not supported"
+msgstr ""
+
+#: java/jvspec.c:80 ada/lang-specs.h:34 gcc.c:767
+msgid "-pg and -fomit-frame-pointer are incompatible"
+msgstr ""
+
+#: java/lang-specs.h:34
+msgid "-fjni and -femit-class-files are incompatible"
+msgstr ""
+
+#: java/lang-specs.h:35
+msgid "-fjni and -femit-class-file are incompatible"
+msgstr ""
+
+#: java/lang-specs.h:36 java/lang-specs.h:37
+msgid "-femit-class-file should used along with -fsyntax-only"
+msgstr ""
+
+#: treelang/lang-specs.h:52
+msgid "-pg or -p and -fomit-frame-pointer are incompatible"
+msgstr "punters -pg o -p i -fomit-frame són incompatibles"
+
+#: config/sparc/sol2-bi.h:167 config/sparc/sol2-bi.h:172
+#: config/sparc/sol2-gld-bi.h:17 config/sparc/sol2-gld-bi.h:22
+#, fuzzy
+msgid "does not support multilib"
+msgstr "%s no té suport per a %s"
+
+#: config/i386/sco5.h:191
+msgid "-pg not supported on this platform"
+msgstr "-pg no té suport en aquesta plataforma"
+
+#: config/i386/sco5.h:192
+msgid "-p and -pp specified - pick one"
+msgstr "-p i -pp especificats - tria un"
+
+#: config/i386/sco5.h:266
+msgid "-G and -static are mutually exclusive"
+msgstr "-G·i·-static són mútuament exclusius"
+
+#: config/arm/arm.h:198
+msgid "-mapcs-26 and -mapcs-32 may not be used together"
+msgstr ""
+
+#: config/arm/arm.h:200
+msgid "-msoft-float and -mhard_float may not be used together"
+msgstr ""
+
+#: config/arm/arm.h:202
+msgid "-mbig-endian and -mlittle-endian may not be used together"
+msgstr ""
+
+#: config/mcore/mcore.h:65
+msgid "the m210 does not have little endian support"
+msgstr ""
+
+#: ada/lang-specs.h:36
+msgid "one of -c, -S, -gnatc, -gnatz, or -gnats is required for Ada"
+msgstr ""
+
+#: config/mips/r3900.h:35
+msgid "-mhard-float not supported"
+msgstr ""
+
+#: config/mips/r3900.h:37
+msgid "-msingle-float and -msoft-float can not both be specified"
+msgstr ""
+
+#: config/rs6000/darwin.h:98
+msgid " conflicting code gen style switches are used"
+msgstr ""
+
+#: gcc.c:743
+#, fuzzy
+msgid "GCC does not support -C or -CC without -E"
+msgstr "GNU C no dóna suport a -CC sense usar -E"
+
+#: gcc.c:915
+msgid "-E required when input is from standard input"
+msgstr ""
+
+#: config/i386/cygwin.h:29
+msgid "mno-cygwin and mno-win32 are not compatible"
+msgstr ""
+
+#~ msgid "concatenation of string literals with __FUNCTION__ is deprecated"
+#~ msgstr "us depreciada de la concatenació de cadenes literals amb __FUNCTION__"
+
+#~ msgid "pointer to a member used in arithmetic"
+#~ msgstr "es va usar un punter a un membre en l'aritmètica"
+
+#~ msgid "ISO C++ forbids range expressions in switch statements"
+#~ msgstr "ISO C++ prohibeix un rang d'expressions en les declaracions switch"
+
+#~ msgid "ISO C++ forbids taking the address of a label"
+#~ msgstr "ISO C++ prohibeix prendre l'adreça d'una etiqueta"
+
+#~ msgid "declaration of `%s' shadows %s"
+#~ msgstr "la declaració de \"%s\" enfosque \"%s\""
+
+#~ msgid "`struct %s' incomplete in scope ending here"
+#~ msgstr "el \"struct %s\" incomplet en l'àmbit acaba aquí"
+
+#~ msgid "`union %s' incomplete in scope ending here"
+#~ msgstr "el \"union %s\" incomplet en l'àmbit acaba aquí"
+
+#~ msgid "`enum %s' incomplete in scope ending here"
+#~ msgstr "el \"enum %s\" incomplet en l'àmbit acaba aquí"
+
+#~ msgid "label `%s' defined but not used"
+#~ msgstr "l'etiqueta \"%s\" està definida però no s'usa"
+
+#~ msgid "shadowing library function `%s'"
+#~ msgstr "enfosquin la funció de biblioteca \"%s\""
+
+#~ msgid "library function `%s' declared as non-function"
+#~ msgstr "la funció de biblioteca \"%s\" no és declarada com funció"
+
+#~ msgid "conflicting types for `%s'"
+#~ msgstr "tipus en conflicte per a \"%s\""
+
+#~ msgid "redeclaration of `%s'"
+#~ msgstr "re declaració de \"%s\""
+
+#~ msgid "prototype for `%s' follows"
+#~ msgstr "el prototip per a \"%s\" a continuació"
+
+#~ msgid "non-prototype definition here"
+#~ msgstr "la definició del no prototip aquí"
+
+#~ msgid "prototype for `%s' follows and number of arguments doesn't match"
+#~ msgstr "el prototip per a \"%s\" a continuació i el nombre d'arguments no coincideixen"
+
+#~ msgid "prototype for `%s' follows and argument %d doesn't match"
+#~ msgstr "el prototip per a \"%s\" a continuació i l'argument %d no coincideixen"
+
+#~ msgid "type qualifiers for `%s' conflict with previous decl"
+#~ msgstr "qualificators de tipus per a \"%s\" generen conflicte amb la declaració prèvia"
+
+#~ msgid "redundant redeclaration of `%s' in same scope"
+#~ msgstr "declaració redundant de \"%s\" en el mateix àmbit"
+
+#~ msgid "a parameter"
+#~ msgstr "un paràmetre"
+
+#~ msgid "a previous local"
+#~ msgstr "una declaració local prèvia"
+
+#~ msgid "a global declaration"
+#~ msgstr "una declaració global"
+
+#~ msgid "`%s' used prior to declaration"
+#~ msgstr "s'usa \"%s\" previ a la declaració"
+
+#~ msgid "`%s' was declared implicitly `extern' and later `static'"
+#~ msgstr "\"%s\" es va declarar implícitament \"extern\" i després \"static\""
+
+#~ msgid "previous external decl of `%s'"
+#~ msgstr "declaració externa prèvia de \"%s\""
+
+#~ msgid "type mismatch with previous implicit declaration"
+#~ msgstr "no coincideixen els tipus amb la declaració implícita prèvia"
+
+#~ msgid "`%s' was previously implicitly declared to return `int'"
+#~ msgstr "\"%s\" va ser declarat prèvia i implícitament per a retornar \"int\""
+
+#~ msgid "`%s' was declared `extern' and later `static'"
+#~ msgstr "\"%s\" va ser declarat \"extern\" i després \"static\""
+
+#~ msgid "`%s' locally external but globally static"
+#~ msgstr "\"%s\" és externa localment però estàtica globalment"
+
+#~ msgid "function `%s' was previously declared within a block"
+#~ msgstr "la funció \"%s\" va ser declarada prèviament dintre d'un bloc"
+
+#~ msgid "declaration of `%s' has `extern' and is initialized"
+#~ msgstr "la declaració de \"%s\" té \"extern\" i té valor inicial"
+
+#~ msgid "initializer fails to determine size of `%s'"
+#~ msgstr "el iniciador no va poder determinar la grandària de \"%s\""
+
+#~ msgid "array size missing in `%s'"
+#~ msgstr "falta la grandària de la matriu en %s"
+
+#~ msgid "storage size of `%s' isn't known"
+#~ msgstr "no es coneix la grandària d'emmagatzematge de \"%s\""
+
+#~ msgid "storage size of `%s' isn't constant"
+#~ msgstr "la grandària d'emmagatzematge de \"%s\" no és constant"
+
+#~ msgid "ISO C forbids parameter `%s' shadowing typedef"
+#~ msgstr "ISO C prohibeix l'enfosquiment del paràmetre \"%s\" de typedef"
+
+#~ msgid "parameter `%s' points to incomplete type"
+#~ msgstr "el paràmetre \"%s\" apunta a un tipus incomplet"
+
+#~ msgid "parameter points to incomplete type"
+#~ msgstr "el paràmetre punta a un tipus incomplet"
+
+#~ msgid "`void' in parameter list must be the entire list"
+#~ msgstr "\"void\" en la llista de paràmetres deu ser la llista completa"
+
+#~ msgid "`union %s' declared inside parameter list"
+#~ msgstr "\"union %s\" declarat dintre d'una llista de paràmetres"
+
+#~ msgid "`enum %s' declared inside parameter list"
+#~ msgstr "\"enum %s\" declarat dintre d'una llista de paràmetres"
+
+#~ msgid "anonymous union declared inside parameter list"
+#~ msgstr "union anònim declarat dintre d'una llista de paràmetres"
+
+#~ msgid "anonymous enum declared inside parameter list"
+#~ msgstr "enum anònim declarat dintre d'una llista de paràmetres"
+
+#~ msgid "bit-field `%s' type invalid in ISO C"
+#~ msgstr "el tipus de camp de bit \"%s\" és invàlid en ISO C"
+
+#~ msgid "duplicate member `%s'"
+#~ msgstr "membre duplicat \"%s\""
+
+#~ msgid "parm types given both in parmlist and separately"
+#~ msgstr "es van donar els tipus dels paràmetres en la llista de paràmetres i per separat"
+
+#~ msgid "parameter `%s' declared void"
+#~ msgstr "el paràmetre \"%s\" es va declarar void"
+
+#~ msgid "universal-character-name '\\u%04x' not valid in identifier"
+#~ msgstr "universal-character-name \"\\u%04x\" no és vàlid en l'identificador"
+
+#~ msgid "ignoring invalid multibyte character"
+#~ msgstr "ignorant els caràcters multibyte invàlids"
+
+#~ msgid "options array incorrectly sorted: %s is before %s"
+#~ msgstr "opcions de matriu ordenades incorrectament: %s està abans de %s"
+
+#~ msgid "-Wno-strict-prototypes is not supported in C++"
+#~ msgstr "no és dona suport a -Wno-strict-prototypes en C++"
+
+#~ msgid ""
+#~ "Switches:\n"
+#~ " -include <file> Include the contents of <file> before other files\n"
+#~ " -imacros <file> Accept definition of macros in <file>\n"
+#~ " -iprefix <path> Specify <path> as a prefix for next two options\n"
+#~ " -iwithprefix <dir> Add <dir> to the end of the system include path\n"
+#~ " -iwithprefixbefore <dir> Add <dir> to the end of the main include path\n"
+#~ " -isystem <dir> Add <dir> to the start of the system include path\n"
+#~ msgstr ""
+#~ "Interruptors:\n"
+#~ " -include <fitxer> Inclou el contingut de <fitxer> abans altres fitxers\n"
+#~ " -imacros <fitxer> Accepta la definició de macros en <fitxer>\n"
+#~ " -iprefix <camí> Especifica <camí> com a prefix per a les dues opcions\n"
+#~ " següentes\n"
+#~ " -iwithprefix <dir> Afegeix <dir> al final del camí d'inclusió del sistema\n"
+#~ " -iwithprefixbefore <dir> Afegeix <dir> al final del camí d'inclusió principal\n"
+#~ " -isystem <dir> Afegeix <dir> a l'inicí del camí d'inclusió del sistema\n"
+
+#~ msgid ""
+#~ " -idirafter <dir> Add <dir> to the end of the system include path\n"
+#~ " -I <dir> Add <dir> to the end of the main include path\n"
+#~ " -I- Fine-grained include path control; see info docs\n"
+#~ " -nostdinc Do not search system include directories\n"
+#~ " (dirs specified with -isystem will still be used)\n"
+#~ " -nostdinc++ Do not search system include directories for C++\n"
+#~ " -o <file> Put output into <file>\n"
+#~ msgstr ""
+#~ " -idirafter <dir> Afegeix <dir> al final del camí d'inclusió del sistema\n"
+#~ " -I <dir> Afegeix <dir> al final del camí d'inclusió principal\n"
+#~ " -I- afinar el control del camí d'inclusió; consulta la doc\n"
+#~ " -nostdinc No cerca els directoris d'inclusió\n"
+#~ " (dirs especificats amb -isystem seran encara utilitzats)\n"
+#~ " -nostdinc++ No cerca els directoris d'inclusió per a C++\n"
+#~ " -o <fitxer> Posa la sortida en <fitxer>\n"
+
+#~ msgid ""
+#~ " -trigraphs Support ISO C trigraphs\n"
+#~ " -std=<std name> Specify the conformance standard; one of:\n"
+#~ " gnu89, gnu99, c89, c99, iso9899:1990,\n"
+#~ " iso9899:199409, iso9899:1999, c++98\n"
+#~ " -w Inhibit warning messages\n"
+#~ " -W[no-]trigraphs Warn if trigraphs are encountered\n"
+#~ " -W[no-]comment{s} Warn if one comment starts inside another\n"
+#~ msgstr ""
+#~ " -trigraphs Permetre trigrafes ISO/ C\n"
+#~ " -std=<nom std> Especificar el estándard de concordança; una de:\n"
+#~ " gnu89, gnu99, c89, c99, iso/9899:1990,\n"
+#~ " iso9899:199409, iso9899:1999, c++98\n"
+#~ " -w Inhibir els missatges d'avís\n"
+#~ " -W[no-]trigraphs Avisar si es troben trigrafes\n"
+#~ " -W[no-]comment{s} Avisar si un comentari inicia dintre d'altre\n"
+
+#~ msgid ""
+#~ " -W[no-]traditional Warn about features not present in traditional C\n"
+#~ " -W[no-]undef Warn if an undefined macro is used by #if\n"
+#~ " -W[no-]import Warn about the use of the #import directive\n"
+#~ msgstr ""
+#~ " -W[no-]traditional Avisar a propòsit de funccionalitats que no\n"
+#~ " són presentes en tradicional C\n"
+#~ " -W[no-]undef Avisar si #if utilitza una macro no definida\n"
+#~ " -W[no-]import Avisar a propòsit de l'ùs de directives #import\n"
+
+#~ msgid ""
+#~ " -W[no-]error Treat all warnings as errors\n"
+#~ " -W[no-]system-headers Do not suppress warnings from system headers\n"
+#~ " -W[no-]all Enable most preprocessor warnings\n"
+#~ msgstr ""
+#~ " -W[no-]error Tractar tots els avís com a errors\n"
+#~ " -W[no-]system-headers No supprimir les avís de les capçaleres sistema\n"
+#~ " -W[no-]all Autoritzar tots els avís del preprocessador\n"
+
+#~ msgid ""
+#~ " -M Generate make dependencies\n"
+#~ " -MM As -M, but ignore system header files\n"
+#~ " -MD Generate make dependencies and compile\n"
+#~ " -MMD As -MD, but ignore system header files\n"
+#~ " -MF <file> Write dependency output to the given file\n"
+#~ " -MG Treat missing header file as generated files\n"
+#~ msgstr ""
+#~ " -M Generar les dependencies de make\n"
+#~ " -MM Com -M, però ignorales capçaleres sistema\n"
+#~ " -MD Generar les dependencies de make i compilar\n"
+#~ " -MMD Com -MD, però ignorales capçaleres sistema\n"
+#~ " -MF <fitxer> Escriu les dependencies de sortida a el fitxer donat\n"
+#~ " -MG Tractar les fitxers de capçalera com a fitxers generats\n"
+
+#~ msgid ""
+#~ " -MP\t\t\t Generate phony targets for all headers\n"
+#~ " -MQ <target> Add a MAKE-quoted target\n"
+#~ " -MT <target> Add an unquoted target\n"
+#~ msgstr ""
+#~ " -MP\t\t\t Generar objectius facticis per a totes les capçaleres\n"
+#~ " -MQ <objectiu> Afegir un objectiu MAKE-quoted\n"
+#~ " -MT <objectiu> Afegir un objectiu sense parèntesis\n"
+
+#~ msgid ""
+#~ " -D<macro> Define a <macro> with string '1' as its value\n"
+#~ " -D<macro>=<val> Define a <macro> with <val> as its value\n"
+#~ " -A<question>=<answer> Assert the <answer> to <question>\n"
+#~ " -A-<question>=<answer> Disable the <answer> to <question>\n"
+#~ " -U<macro> Undefine <macro> \n"
+#~ " -v Display the version number\n"
+#~ msgstr ""
+#~ " -D<macro> Definir una <macro> amb la cadena '1' com valor\n"
+#~ " -D<macro>=<val> Definir una <macro> amb <val> com valor\n"
+#~ " -A<pregunta>=<resposta> Associar <resposta> a <pregunta>\n"
+#~ " -A-<pregunta>=<resposta> Dissociar <resposta> de <pregunta>\n"
+#~ " -U<macro> Només definir <macro> \n"
+#~ " -v Mostrar el numero de versió\n"
+
+#~ msgid ""
+#~ " -H Print the name of header files as they are used\n"
+#~ " -C Do not discard comments\n"
+#~ " -dM Display a list of macro definitions active at end\n"
+#~ " -dD Preserve macro definitions in output\n"
+#~ " -dN As -dD except that only the names are preserved\n"
+#~ " -dI Include #include directives in the output\n"
+#~ msgstr ""
+#~ " -H Mostrar les noms de fitxers de capçalera quan estan utilitzats\n"
+#~ " -C Posar les comentaris de costat\n"
+#~ " -dM Mostrar al final una llista de les definicions de macro actives\n"
+#~ " -dD Preservar les definicions de macro a la sortida\n"
+#~ " -dN Com -dD excepte nomès les noms són preservats\n"
+#~ " -dI Incloure les directives #include a la sortida\n"
+
+#~ msgid ""
+#~ " -f[no-]preprocessed Treat the input file as already preprocessed\n"
+#~ " -ftabstop=<number> Distance between tab stops for column reporting\n"
+#~ " -P Do not generate #line directives\n"
+#~ " -remap Remap file names when including files\n"
+#~ " --help Display this information\n"
+#~ msgstr ""
+#~ " -f[no-]preprocessed Tractar el fitxer d'entrada com a ja preprocessat\n"
+#~ " -ftabstop=<nombre> Seleccionar l'amplitud de tabulació per a les rapports\n"
+#~ " -P No generar directives #line\n"
+#~ " -remap Remapar les noms de fitxer quan s'inclouen fitxers\n"
+#~ " -help Mostra aquesta informació\n"
+
+#~ msgid "ISO C forbids the address of a cast expression"
+#~ msgstr "ISO C prohibeix l'adreça d'una expressió cast"
+
+#~ msgid "initializer for static variable is not constant"
+#~ msgstr "el valor inicial assignat per a la variable estàtica no es constant"
+
+#~ msgid "initializer for static variable uses complicated arithmetic"
+#~ msgstr "el valor inicial assignat per a la variable estàtica usa aritmètica complicada"
+
+#~ msgid "aggregate initializer is not constant"
+#~ msgstr "el inicialitzador agregat no és una constant"
+
+#~ msgid "aggregate initializer uses complicated arithmetic"
+#~ msgstr "el inicialitzador agregat usa aritmètica complicada"
+
+#~ msgid "open %s"
+#~ msgstr "obrir %s"
+
+#~ msgid "incompatibilities between object file & expected values"
+#~ msgstr "incompatibilitats entre el fitxer objecte i els valors esperats"
+
+#~ msgid ""
+#~ "\n"
+#~ "Processing symbol table #%d, offset = 0x%.8lx, kind = %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Processant la matriu de símbols #%d, desplacament = 0x%.8lx, tipus = %s\n"
+
+#~ msgid "string section missing"
+#~ msgstr "falta la secció de cadenes"
+
+#~ msgid "section pointer missing"
+#~ msgstr "falta la secció de punters"
+
+#~ msgid "no symbol table found"
+#~ msgstr "no es troba la matriu de símbols"
+
+#~ msgid ""
+#~ "\n"
+#~ "Updating header and load commands.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Actualitzant les ordres d'encapçalat i càrrega.\n"
+#~ "\n"
+
+#~ msgid "load command map, %d cmds, new size %ld.\n"
+#~ msgstr "carregar mapa d'ordres, %d ordres, nova grandària %ld.\n"
+
+#~ msgid ""
+#~ "writing load commands.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "escrivint les ordres de càrrega.\n"
+#~ "\n"
+
+#~ msgid "close %s"
+#~ msgstr "tancar %s"
+
+#~ msgid "could not convert 0x%l.8x into a region"
+#~ msgstr "no es pot convertir 0x%l.8x en una regió"
+
+#~ msgid "%s function, region %d, offset = %ld (0x%.8lx)\n"
+#~ msgstr "funció %s, regió %d, desfasament = %ld (0x%.8lx)\n"
+
+#~ msgid "bad magic number"
+#~ msgstr "nombre màgic erroni"
+
+#~ msgid "bad header version"
+#~ msgstr "versió d'encapçalat errònia"
+
+#~ msgid "bad raw header version"
+#~ msgstr "versió d'encapçalat textual errònia"
+
+#~ msgid "raw header buffer too small"
+#~ msgstr "emmagatzematge temporal d'encapçalat textual massa petit"
+
+#~ msgid "old raw header file"
+#~ msgstr "fitxer d'encapçalat textual antic"
+
+#~ msgid "unsupported version"
+#~ msgstr "versió sense suport"
+
+#~ msgid "unknown {de,en}code_mach_o_hdr return value %d"
+#~ msgstr "valor de devolució {de,en}code_mach_o_hdr %d desconegut"
+
+#~ msgid "fstat %s"
+#~ msgstr "fstat %s"
+
+#~ msgid "lseek %s 0"
+#~ msgstr "lseek %s 0"
+
+#~ msgid "read %s"
+#~ msgstr "read %s"
+
+#~ msgid "read %ld bytes, expected %ld, from %s"
+#~ msgstr "%ld octets llegits, s'esperaven %ld, de %s"
+
+#~ msgid "msync %s"
+#~ msgstr "msync %s"
+
+#~ msgid "munmap %s"
+#~ msgstr "munmap %s"
+
+#~ msgid "write %s"
+#~ msgstr "write %s"
+
+#~ msgid "wrote %ld bytes, expected %ld, to %s"
+#~ msgstr "%ld octets escrits, s'esperaven %ld, a %s"
+
+#~ msgid "ISO C++ does not permit \"%s\" in #if"
+#~ msgstr "ISO C++ no permet \"%s\" en #if"
+
+#~ msgid "invalid character '%c' in #if"
+#~ msgstr "caracter invàlid \"%c\" en #if"
+
+#~ msgid "invalid character '\\%03o' in #if"
+#~ msgstr "caracter invàlid \"\\%03o\" en #if"
+
+#~ msgid "absolute file name in remap_filename"
+#~ msgstr "nom de fitxer absolut en remap_filename"
+
+#~ msgid "%s: Not a directory"
+#~ msgstr "%s: No és un directori"
+
+#~ msgid "directory name missing after %s"
+#~ msgstr "nom de directori faltant deprés de %s"
+
+#~ msgid "file name missing after %s"
+#~ msgstr "nom de fitxer faltant deprés de %s"
+
+#~ msgid "path name missing after %s"
+#~ msgstr "nom de camí faltant deprés de %s"
+
+#~ msgid "trigraph ??%c converted to %c"
+#~ msgstr "trigraph ??%c convertit a %c"
+
+#~ msgid "trigraph ??%c ignored"
+#~ msgstr "s'ignora el trigraph ??%c"
+
+#~ msgid "backslash and newline separated by space"
+#~ msgstr "barra invertida i fi de línia separats per espai"
+
+#~ msgid "backslash-newline at end of file"
+#~ msgstr "barra invertida al final del fitxer"
+
+#~ msgid "\"/*\" within comment"
+#~ msgstr "\"/*\" dintre un comentari"
+
+#~ msgid "%s in preprocessing directive"
+#~ msgstr "%s en directiva de preprocessament"
+
+#~ msgid "no newline at end of file"
+#~ msgstr "no hi ha caràcter de fi de línia"
+
+#~ msgid "unknown string token %s\n"
+#~ msgstr "Element de cadena %s desconegut\n"
+
+#~ msgid "non-hex digit '%c' in universal-character-name"
+#~ msgstr "dígit no hexadecimal \"%c\" en universal-character-name"
+
+#~ msgid "universal-character-name on EBCDIC target"
+#~ msgstr "universal-character-name en l'objectiu EBCDIC"
+
+#~ msgid "universal-character-name out of range"
+#~ msgstr "universal-character-name fora de rang"
+
+#~ msgid "escape sequence out of range for its type"
+#~ msgstr "seqüència d'escapi fora de rang per a el seu tipus"
+
+#~ msgid "#import is obsolete, use an #ifndef wrapper in the header file"
+#~ msgstr "#import és obsolet, usi un embolcall #ifndef en el fitxer d'encapçalat"
+
+#~ msgid "#pragma once is obsolete"
+#~ msgstr "#pragma una vegada és obsolet"
+
+#~ msgid "the conditional began here"
+#~ msgstr "el condicional va començar aquí"
+
+#~ msgid "unterminated #%s"
+#~ msgstr "#%s sense acabar"
+
+#~ msgid "\"%s\" redefined"
+#~ msgstr "\"%s\" re-definit"
+
+#~ msgid "this is the location of the previous definition"
+#~ msgstr "aquesta és la ubicació de la definició prèvia"
+
+#~ msgid "((anonymous))"
+#~ msgstr "((anònim))"
+
+#~ msgid "%s: warnings being treated as errors\n"
+#~ msgstr "%s: els avisos són tractats com errors\n"
+
+#~ msgid "At top level:"
+#~ msgstr "En el nivell principal:"
+
+#~ msgid "In member function `%s':"
+#~ msgstr "en la funció membre \"%s\":"
+
+#~ msgid "In function `%s':"
+#~ msgstr "En la funció \"%s\":"
+
+#~ msgid ""
+#~ "Please submit a full bug report,\n"
+#~ "with preprocessed source if appropriate.\n"
+#~ "See %s for instructions.\n"
+#~ msgstr ""
+#~ "Si us plau, envieu un informe d'error complet,\n"
+#~ "amd la font preprocessada si és oportú.\n"
+#~ "Consulta %s per a les instruccions.\n"
+
+#~ msgid "In file included from %s:%d"
+#~ msgstr "En el fitxer inclòs de %s:%d"
+
+#~ msgid ""
+#~ ",\n"
+#~ " from %s:%d"
+#~ msgstr ""
+#~ ",\n"
+#~ " de %s:%d"
+
+#~ msgid "internal regno botch: `%s' has regno = %d\n"
+#~ msgstr "regno intern mal fet: \"%s\" té regno = %d\n"
+
+#~ msgid "unsupported wide integer operation"
+#~ msgstr "operació d'enters amples sense suport"
+
+#~ msgid "Copyright (C) 2003 Free Software Foundation, Inc.\n"
+#~ msgstr "Copyright (C) 2003 Free Software Foundation, Inc.\n"
+
+#~ msgid "mismatched braces in specs"
+#~ msgstr "claus sense coincidència en especificacions"
+
+#~ msgid "Copyright (C) 2001 Free Software Foundation, Inc.\n"
+#~ msgstr "Copyright (C) 2001 Free Software Foundation, Inc.\n"
+
+#~ msgid "Could not open basic block file %s.\n"
+#~ msgstr "No es pot obrir fitxer de bloc bàsic %s.\n"
+
+#~ msgid "Could not open program flow graph file %s.\n"
+#~ msgstr "No es pot obrir el fitxer del graf de fluix del programa %s.\n"
+
+#~ msgid "Could not open data file %s.\n"
+#~ msgstr "No es pot obrir fitxer de dades %s.\n"
+
+#~ msgid "Assuming that all execution counts are zero.\n"
+#~ msgstr "Assumint que tots els comptes d'execició estan a zero.\n"
+
+#~ msgid "No executable code associated with file %s.\n"
+#~ msgstr "No hi ha codi executable associat al fitxer %s.\n"
+
+#~ msgid "didn't use all bb entries of graph, function %s\n"
+#~ msgstr "no es van usar totes les entrades bb del graf, funció %s\n"
+
+#~ msgid "block_num = %ld, num_blocks = %d\n"
+#~ msgstr "block_num = %ld, num_blocks = %d\n"
+
+#~ msgid "ERROR: too many basic blocks in function %s\n"
+#~ msgstr "ERROR: massa blocs bàsics en la funció %s\n"
+
+#~ msgid "ERROR: out of range line number in function %s\n"
+#~ msgstr "ERROR: nombre de línies fora de rang en la funció %s\n"
+
+#~ msgid "Could not open source file %s.\n"
+#~ msgstr "No es pot obrir el fitxer de codi font %s.\n"
+
+#~ msgid "Unexpected EOF while reading source file %s.\n"
+#~ msgstr "EOF inesperat mentre es llegia el fitxer de codi font %s.\n"
+
+#~ msgid "Creating %s.\n"
+#~ msgstr "Creant %s.\n"
+
+#~ msgid "invalid string `%s' in define_cpu_unit"
+#~ msgstr "cadena \"%s\" invàlida en define_cpu_unit"
+
+#~ msgid "invalid string `%s' in define_query_cpu_unit"
+#~ msgstr "cadena \"%s\" invàlida en define_query_cpu_unit"
+
+#~ msgid "invalid string `%s' in define_bypass"
+#~ msgstr "cadena \"%s\" invàlida en define_bypass"
+
+#~ msgid "invalid first string `%s' in exclusion_set"
+#~ msgstr "primera cadena \"%s\" invàlida en exclusion_set"
+
+#~ msgid "invalid second string `%s' in exclusion_set"
+#~ msgstr "segona cadena \"%s\" invàlida en exclusion_set"
+
+#~ msgid "invalid first string `%s' in presence_set"
+#~ msgstr "primera cadena \"%s\" invàlida en presence_set"
+
+#~ msgid "invalid first string `%s' in absence_set"
+#~ msgstr "primera cadena \"%s\" invàlida en absence_set"
+
+#~ msgid "invalid option `%s' in automata_option"
+#~ msgstr "opció·\"%s\" invàlida en automata_option"
+
+#~ msgid "invalid `%s' in reservation `%s'"
+#~ msgstr "\"%s\" invàlid en la reservació \"%s\""
+
+#~ msgid "unit `%s' excludes itself"
+#~ msgstr "la unitat \"%s\" s'exclou a ella mateixa"
+
+#~ msgid "repeated declaration of automaton `%s'"
+#~ msgstr "declaració repetida de l'autòmat \"%s\""
+
+#~ msgid "`%s' is already used as insn reservation name"
+#~ msgstr "\"%s\" ja es va utilitzar com un nom de reservació de insn"
+
+#~ msgid "automaton `%s' is not declared"
+#~ msgstr "l'autòmat \"%s\" no es va declarar"
+
+#~ msgid "`%s' is declared as cpu unit"
+#~ msgstr "\"%s\" es declarat com una unitat de cpu"
+
+#~ msgid "`%s' is declared as cpu reservation"
+#~ msgstr "\"%s\" està declarat com una reservació de cpu"
+
+#~ msgid "repeated declaration of unit `%s'"
+#~ msgstr "declaració repetida de la unitat \"%s\""
+
+#~ msgid "repeated declaration of reservation `%s'"
+#~ msgstr "declaració repetida de la reservació \"%s\""
+
+#~ msgid "there is no insn reservation `%s'"
+#~ msgstr "no hi ha reservació de insn \"%s\""
+
+#~ msgid "the same bypass `%s - %s' is already defined"
+#~ msgstr "el mateix bypass \"%s - %s\" ja està definit"
+
+#~ msgid "bypass `%s - %s' is already defined"
+#~ msgstr "el bypass \"%s - %s\" ja està definit"
+
+#~ msgid "unit `%s' is not used"
+#~ msgstr "la unitat \"%s\" no s'utilitza"
+
+#~ msgid "reservation `%s' is not used"
+#~ msgstr "la reservació \"%s\" no s'utilitza"
+
+#~ msgid "cycle in definition of reservation `%s'"
+#~ msgstr "cicle en la definició de la reservació \"%s\""
+
+#~ msgid "-split has no argument."
+#~ msgstr "-split no té arguments"
+
+#~ msgid "option `-split' has not been implemented yet\n"
+#~ msgstr "l'opció \"-split\" encara no s'ha implementat\n"
+
+#~ msgid "Errors in DFA description"
+#~ msgstr "Errors en la descripció DFA"
+
+#~ msgid "Error in writing DFA description file %s"
+#~ msgstr "Error a l'escriure el fitxer de descripció DFA %s"
+
+#~ msgid "No input file name."
+#~ msgstr "No hi ha fitxers d'entrada"
+
+#~ msgid ".da file corrupted"
+#~ msgstr "fitxer .da corrupte"
+
+#~ msgid "Generate STABS format debug info"
+#~ msgstr "Generar informació de depuració en el format STABS"
+
+#~ msgid "Generate extended STABS format debug info"
+#~ msgstr "Generar informació de depuració en el format STABS estès"
+
+#~ msgid "Generate DWARF-1 format debug info"
+#~ msgstr "Generar informació de depuració en el format DWARF-1"
+
+#~ msgid "Generate extended DWARF-1 format debug info"
+#~ msgstr "Generar informació de depuració en el format DWARF-1 estès"
+
+#~ msgid "Generate DWARF-2 debug info"
+#~ msgstr "Generar informació de depuració en el format DWARF-2"
+
+#~ msgid "Generate XCOFF format debug info"
+#~ msgstr "Generar informació de depuració en el format XCOFF"
+
+#~ msgid "Generate extended XCOFF format debug info"
+#~ msgstr "Generar informació de depuració en el format XCOFF estès"
+
+#~ msgid "Generate COFF format debug info"
+#~ msgstr "Generar informació de depuració en el format COFF"
+
+#~ msgid "Generate VMS format debug info"
+#~ msgstr "Generar informació de depuració en el format VMS"
+
+#~ msgid "Consider all mem refs through pointers as volatile"
+#~ msgstr "Considerar totes les referències a memòria a través de punters com volatile"
+
+#~ msgid "Consider all mem refs to global data to be volatile"
+#~ msgstr "Considerar totes les referències a dades globals com volatile"
+
+#~ msgid "Consider all mem refs to static data to be volatile"
+#~ msgstr "Considerar totes les referències a dades static com volatile"
+
+#~ msgid "Output GNU ld formatted global initializers"
+#~ msgstr "Obtenir iniciators globals amb format per a ld de GNU"
+
+#~ msgid "Enable SSA optimizations"
+#~ msgstr "Activar les optimitzacions SSA"
+
+#~ msgid "Enable SSA conditional constant propagation"
+#~ msgstr "Activar la propagació de les constants condicionals SSA"
+
+#~ msgid "Enable aggressive SSA dead code elimination"
+#~ msgstr "Activar l'eliminació agressiva de codi mort SSA"
+
+#~ msgid "Compile just for ISO C90"
+#~ msgstr "Compilar només per a ISO C90"
+
+#~ msgid "Determine language standard"
+#~ msgstr "Determinar el estàndard de llenguatge"
+
+#~ msgid "Make bit-fields by unsigned by default"
+#~ msgstr "Fer per omissió unsigned els camps de bit"
+
+#~ msgid "Allow different types as args of ? operator"
+#~ msgstr "Permetre tipus diferents com arguments de l'operador ?"
+
+#~ msgid "Allow the use of $ inside identifiers"
+#~ msgstr "Permetre l'ús de $ dintre dels identificadors"
+
+#~ msgid "Use the smallest fitting integer to hold enums"
+#~ msgstr "Usar l'enter adequat més petit per a contenir enumerats"
+
+#~ msgid "Don't warn about too many arguments to format functions"
+#~ msgstr "No avisar sobre massa arguments per a les funcions de format"
+
+#~ msgid "Warn about non-string-literal format strings"
+#~ msgstr "Avisar sobre cadenes de format que no són cadenes literals"
+
+#~ msgid "Warn about constructs whose meanings change in ISO C"
+#~ msgstr "Avisar sobre construccions el significat de les quals canvia en ISO C"
+
+#~ msgid "Warn when trigraphs are encountered"
+#~ msgstr "Avisar si es troben trigrafes"
+
+#~ msgid "Mark strings as 'const char *'"
+#~ msgstr "Marcar les cadenes com \"const char *\""
+
+#~ msgid " -pedantic-errors Like -pedantic except that errors are produced\n"
+#~ msgstr " -pedantic-errors Com -pedantic excepte que es produeixen errors\n"
+
+#~ msgid " -w Suppress warnings\n"
+#~ msgstr " -w Suprimir avisos\n"
+
+#~ msgid " -W Enable extra warnings\n"
+#~ msgstr " -W Activar avisos extra\n"
+
+#~ msgid " -Wunused Enable unused warnings\n"
+#~ msgstr " -Wunused Activar avisos sense usar\n"
+
+#~ msgid " -p Enable function profiling\n"
+#~ msgstr " -p Activar l'anàlisi de perfil de funcions\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "Language specific options:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Opcions específiques del llenguatge:\n"
+
+#~ msgid " %-23.23s [undocumented]\n"
+#~ msgstr " %-23.23s [sense documentar]\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "There are undocumented %s specific options as well.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "A més hi ha opcions específiques de %s sense documentar.\n"
+
+#~ msgid ""
+#~ "\n"
+#~ " Options for %s:\n"
+#~ msgstr ""
+#~ "\n"
+#~ " Opcions per a %s:\n"
+
+#~ msgid "unrecognized option `%s'"
+#~ msgstr "Opció \"%s\" no reconeguda"
+
+#~ msgid "-Wid-clash-LEN is no longer supported"
+#~ msgstr "-Wid-clash-LEN ja no té suport"
+
+#~ msgid "use -gdwarf -g%d for DWARF v1, level %d"
+#~ msgstr "usi -gdwarf -g%d per a DWARF v1, nivell %d"
+
+#~ msgid "use -gdwarf-2 for DWARF v2"
+#~ msgstr "usi -ddwarf-2 per a DWARF v2"
+
+#~ msgid "ignoring option `%s' due to invalid debug level specification"
+#~ msgstr "ignorant l'opció \"%s\" a causa de l'especificació d'un nivell de depuració invàlid"
+
+#~ msgid "`%s': unknown or unsupported -g option"
+#~ msgstr "\"%s\": opció -g desconeguda o sense suport"
+
+#~ msgid "`%s' ignored, conflicts with `-g%s'"
+#~ msgstr "\"%s\" ignorat, té conflicte amb \"-g%s\""
+
+#~ msgid "-param option missing argument"
+#~ msgstr "falta l'argument per a l'opció -param"
+
+#~ msgid "invalid --param option: %s"
+#~ msgstr "opció de --param invàlida: %s"
+
+#~ msgid "(it is valid for %s but not the selected language)"
+#~ msgstr "(és vàlida per a %s però no per al llenguatge seleccionat)"
+
+#~ msgid "#`%s' not supported by %s#"
+#~ msgstr "#\"%s\" no té suport per a %s#"
+
+#~ msgid "The maximum number of instructions by repeated inlining before gcc starts to throttle inlining"
+#~ msgstr "El nombre màxim d'instruccions per inlining repetit abans que gcc comenci a descartar inlining"
+
+#~ msgid "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining"
+#~ msgstr "El nombre d'instruccions en una sola funció per a ser encara elegible per a inlining després de molt inlining recursiu"
+
+#~ msgid "Use the 26-bit version of the APCS"
+#~ msgstr "Usar la versió 26-bit del APCS"
+
+#~ msgid "Use Mingw32 interface"
+#~ msgstr "Usar la interfície Mingw32"
+
+#~ msgid "Use Cygwin interface"
+#~ msgstr "Usar la interfície Cygwin"
+
+#~ msgid "Use bare Windows interface"
+#~ msgstr "Usar la interfície nua Windows"
+
+#~ msgid "const objects cannot go in .sdata/.sbss"
+#~ msgstr "els objectes cons no poden anar a .sdata/.sbss"
+
+#~ msgid "Generate code for a Sun FPA"
+#~ msgstr "Generar codi per a un Sun FPA"
+
+#~ msgid "Generate code for a Sun Sky board"
+#~ msgstr "Generar codi per a un Sun Sky board"
+
+#~ msgid "Do not use Sky linkage convention"
+#~ msgstr "No usar la convenció d'enllaç Sky"
+
+#~ msgid "Generate code for a 68881"
+#~ msgstr "Generar codi per a un 68881"
+
+#~ msgid "internal gcc monitor: short-branch(%x)"
+#~ msgstr "monitor intern de gcc: short-branch(%x)"
+
+#~ msgid "internal gcc error: Can't express symbolic location"
+#~ msgstr "error intern de gcc: No es pot expressar la ubicació simbòlica"
+
+#~ msgid "argument #%d is a structure"
+#~ msgstr "l'argument #%d és una estructura"
+
+#~ msgid "%%R not followed by %%B/C/D/E"
+#~ msgstr "%%R no és seguit per %%B/C/D/E"
+
+#~ msgid "invalid %%Q value"
+#~ msgstr "valor %%Q invàlid"
+
+#~ msgid "invalid %%o value"
+#~ msgstr "valor invàlid per a %%o"
+
+#~ msgid "invalid %%s/S value"
+#~ msgstr "valor invàlid per a %%s/S"
+
+#~ msgid "invalid %%B value"
+#~ msgstr "valor invàlid per a %%B"
+
+#~ msgid "`%%d' operand isn't a register"
+#~ msgstr "l'operand \"%%d\" no és un registre"
+
+#~ msgid "operand is r0"
+#~ msgstr "l'operand és r0"
+
+#~ msgid "operand is const_double"
+#~ msgstr "l'operand és const_double"
+
+#~ msgid "-mtrap-large-shift and -mhandle-large-shift are incompatible"
+#~ msgstr "-mtrap-large-shift i -mhandle-large-shift no són compatibles"
+
+#~ msgid "invalid option `-mshort-data-%s'"
+#~ msgstr "opció invàlida \"-mshort-data-%s\""
+
+#~ msgid "-mshort-data-%s is too large "
+#~ msgstr "-mshort-data-%s és massa gran"
+
+#~ msgid "-mshort-data-%s and PIC are incompatible"
+#~ msgstr "-mshort-data-%s i PIC són incompatibles"
+
+#~ msgid "bad value (%s) for -mips switch"
+#~ msgstr "valor erroni (%s) per a l'interruptor -mips"
+
+#~ msgid "invalid option `entry%s'"
+#~ msgstr "opció invàlid \"entry%s\""
+
+#~ msgid "-mentry is only meaningful with -mips-16"
+#~ msgstr "-mentry només té significat amb -mips-16"
+
+#~ msgid "MIPS ECOFF format does not allow changing filenames within functions with #line"
+#~ msgstr "el format ECOFF de MIPS no permet el canvi de noms de fitxer dintre de funcions amb #line"
+
+#~ msgid "fp_offset (%ld) or end_offset (%ld) is less than zero"
+#~ msgstr "fp_offset (%ld) o end_offset (%ld) és menor a zero"
+
+#~ msgid "Trap on integer divide overflow"
+#~ msgstr "Atrapar desbordaments en la divisió entera"
+
+#~ msgid "Don't trap on integer divide overflow"
+#~ msgstr "No atrapar desbordaments en la divisió entera"
+
+#~ msgid "Use mips16 entry/exit psuedo ops"
+#~ msgstr "Usar pseudo ops mips16 de entrada/sortida"
+
+#~ msgid "Don't use MIPS16 instructions"
+#~ msgstr "No usar instruccions MIPS16"
+
+#~ msgid "invalid %%z value"
+#~ msgstr "valor %%z invàlid"
+
+#~ msgid "invalid %%Z value"
+#~ msgstr "valor %%Z invàlid"
+
+#~ msgid "invalid %%j value"
+#~ msgstr "valor %%j invàlid"
+
+#~ msgid "can't have varargs with -mfp-arg-in-fp-regs"
+#~ msgstr "no es pot tenir varargs amb -mfp-arg-in-fp-regs"
+
+#~ msgid "unknown -mvrsave= option specified: '%s'"
+#~ msgstr "opció -mvrsave= especificada desconeguda: \"%s\""
+
+#~ msgid "64 bit mode"
+#~ msgstr "moda 64 bits"
+
+#~ msgid "31 bit mode"
+#~ msgstr "moda 31 bits"
+
+#~ msgid "Use the Xtensa code density option"
+#~ msgstr "Usar l'opció de densitat del codi Xtensa"
+
+#~ msgid "Do not use the Xtensa code density option"
+#~ msgstr "No usar l'opció de densitat del codi Xtensa"
+
+#~ msgid "Use the Xtensa MAC16 option"
+#~ msgstr "Usar l'opció MAC16 de Xtensa"
+
+#~ msgid "Do not use the Xtensa MAC16 option"
+#~ msgstr "No usar l'opció MAC16 de Xtensa"
+
+#~ msgid "Use the Xtensa MUL16 option"
+#~ msgstr "Usar l'opció MUL16 de Xtensa"
+
+#~ msgid "Do not use the Xtensa MUL16 option"
+#~ msgstr "No usar l'opció MUL16 de Xtensa"
+
+#~ msgid "Use the Xtensa MUL32 option"
+#~ msgstr "Usar l'opció MUL32 de Xtensa"
+
+#~ msgid "Do not use the Xtensa MUL32 option"
+#~ msgstr "No usar l'opció MUL32 de Xtensa"
+
+#~ msgid "Use the Xtensa NSA option"
+#~ msgstr "Usar l'opció NSA de Xtensa"
+
+#~ msgid "Do not use the Xtensa NSA option"
+#~ msgstr "No usar l'opció NSA de Xtensa"
+
+#~ msgid "Use the Xtensa MIN/MAX option"
+#~ msgstr "Usar l'opció MIN/MAX de Xtensa"
+
+#~ msgid "Do not use the Xtensa MIN/MAX option"
+#~ msgstr "No usar l'opció MIN/MAX de Xtensa"
+
+#~ msgid "Use the Xtensa SEXT option"
+#~ msgstr "Usar l'opció SEXT de Xtensa"
+
+#~ msgid "Do not use the Xtensa SEXT option"
+#~ msgstr "No usar l'opció SEXT de Xtensa"
+
+#~ msgid "Use the Xtensa boolean register option"
+#~ msgstr "Usar l'opció de registre booleà de Xtensa"
+
+#~ msgid "Do not use the Xtensa boolean register option"
+#~ msgstr "No usar l'opció de registre booleà de Xtensa"
+
+#~ msgid "Use the Xtensa floating-point unit"
+#~ msgstr "Usar la unitat de coma flotant de Xtensa"
+
+#~ msgid "Do not use the Xtensa floating-point unit"
+#~ msgstr "No usar la unitat de coma flotant de Xtensa"
+
+#~ msgid "Serialize volatile memory references with MEMW instructions"
+#~ msgstr "Serialitzar les referències a memòria volàtil amb instruccions MEMW"
+
+#~ msgid "Do not serialize volatile memory references with MEMW instructions"
+#~ msgstr "No serialitzar les referències a memòria volàtil amb instruccions MEMW"
+
+#~ msgid "type of `%E' does not match destructor type `%T' (type was `%T')"
+#~ msgstr "el tipus de \"%E\" no coincideix amb el tipus del destructor \"%T\" (el tipus era \"%T\")"
+
+#~ msgid "`%D' is a namespace"
+#~ msgstr "\"%D\" és un nom d'espai"
+
+#~ msgid "base object `%E' of scoped method call is of non-aggregate type `%T'"
+#~ msgstr "l'objecte base \"%E\" de la cridada de mètode de l'ambient és del tipus no agregat \"%T\""
+
+#~ msgid "destructors take no parameters"
+#~ msgstr "els destructors no prenen paràmetres"
+
+#~ msgid "destructor name `~%T' does not match type `%T' of expression"
+#~ msgstr "el nom del destructor \"%T\" no coincideix amb el tipus \"%T\" de l'expressió"
+
+#~ msgid "%s %+#D%s"
+#~ msgstr "%s %+#D%s"
+
+#~ msgid "`%D' must be declared before use"
+#~ msgstr "es deu declarar \"%D\" abans del seu ús"
+
+#~ msgid " initializing argument %P of `%D' from result of `%D'"
+#~ msgstr " inicialitzant l'argument %P de \"%D\" a partir del resultat de \"%D\""
+
+#~ msgid " initializing temporary from result of `%D'"
+#~ msgstr " inicialitzant el temporal a partir del resultat de \"%D\""
+
+#~ msgid "cannot receive objects of non-POD type `%#T' through `...'"
+#~ msgstr "no es pot rebre objectes de tipus \"%#T\" que no és POD a través de \"...\""
+
+#~ msgid "duplicate enum value `%D'"
+#~ msgstr "valor enum duplicat \"%D\""
+
+#~ msgid "duplicate field `%D' (as enum and non-enum)"
+#~ msgstr "camp duplicat \"%D\" (com enum i non-enum)"
+
+#~ msgid "duplicate nested type `%D'"
+#~ msgstr "tipus niat duplicat \"%D\""
+
+#~ msgid "duplicate field `%D' (as type and non-type)"
+#~ msgstr "camp duplicat \"%D\" (com tipus i no tipus)"
+
+#~ msgid "ISO C++ forbids member `%D' with same name as enclosing class"
+#~ msgstr "ISO C++ prohibeix que el membre \"%D\" tingui el mateix nom que la classe que ho conté"
+
+#~ msgid "field `%D' invalidly declared offset type"
+#~ msgstr "el camp \"%D\" és declarat invàlidament com un tipus de desplaçament"
+
+#~ msgid "field `%D' declared static in union"
+#~ msgstr "el camp \"%D\" és declarat com static en la unió"
+
+#~ msgid "lookup of `%D' finds `%#D'"
+#~ msgstr "la recerca de \"%D\" troba a \"%#D\""
+
+#~ msgid " instead of `%D' from dependent base class"
+#~ msgstr " en lloc de \"%D\" de la classe base depenent"
+
+#~ msgid "lookup of `%D' in the scope of `%#T' (`%#D') does not match lookup in the current scope (`%#D')"
+#~ msgstr "la recerca de \"%D\" en l'àmbit de \"%#T\" (\"%#D\") no coincideix amb la recerca en l'àmbit actual (\"%#D\")"
+
+#~ msgid "`%T' is implicitly a typename"
+#~ msgstr "\"%T\" implícitament és un nom de tipus"
+
+#~ msgid "ISO C++ forbids static data member `%D' with same name as enclosing class"
+#~ msgstr "ISO C++ prohibeix que el membre de dades static \"%D\" tingui el mateix nom que la classe que ho conté"
+
+#~ msgid "parameter `%D' invalidly declared offset type"
+#~ msgstr "el paràmetre \"%D\" es va declarar invàlidament com tipus de desplaçament"
+
+#~ msgid "`%s %T' declares a new type at namespace scope"
+#~ msgstr "\"%s %T\" declara un tipus nou en l'àmbit del nom d'espai"
+
+#~ msgid " names from dependent base classes are not visible to unqualified name lookup - to refer to the inherited type, say `%s %T::%T'"
+#~ msgstr " els noms de les classes bases depenents no són visibles per a la recerca de noms sense qualificar - per a referir-se al tipus heretat, utilitzi \"%s %T::%T\""
+
+#~ msgid "base class `%T' has incomplete type"
+#~ msgstr "la classe base \"%T\" té tipus de dada incompleta"
+
+#~ msgid "semicolon missing after declaration of `%#T'"
+#~ msgstr "manca punt i coma després de la declaració de \"%#T\""
+
+#~ msgid "template `%#D' instantiated in file without #pragma interface"
+#~ msgstr "es va instanciar el patró \"%#D\" en el fitxer sense #pragma interface"
+
+#~ msgid "template `%#D' defined in file without #pragma interface"
+#~ msgstr "es va definir el patró \"%#D\" en el fitxer sense #pragma interface"
+
+#~ msgid "parser may be lost: is there a '{' missing somewhere?"
+#~ msgstr "el decodificador tal vegada es va perdre: falta algun \"{\" en algun lloc?"
+
+#~ msgid "anachronistic use of array size in vector delete"
+#~ msgstr "ús anacrònic de la grandària de la matriu desconeguda en vector delete"
+
+#~ msgid "invalid data member initialization"
+#~ msgstr "inicialització de la dada membre invàlida"
+
+#~ msgid "(use `=' to initialize static data members)"
+#~ msgstr "(usi \"=\" per a inicialitzar membres de dades static)"
+
+#~ msgid "too many initialization functions required"
+#~ msgstr "es requereixen massa funcions d'inicialització"
+
+#~ msgid "`%D' is not a namespace"
+#~ msgstr "\"%D\" no és un nom d'espai"
+
+#~ msgid "a using-declaration cannot specify a template-id. Try `using %T::%D'"
+#~ msgstr "una declaració d'ús no pot especificar un aneu de patró. Intenti \"using %T::%D\""
+
+#~ msgid "`%T' does not have a class or union named `%D'"
+#~ msgstr "\"%T\" no té una classe o union cridat \"%D\""
+
+#~ msgid "`%T' is not a class or union type"
+#~ msgstr "\"%T\" no és una classe o tipus union"
+
+#~ msgid "(static %s for %s)"
+#~ msgstr "(%s static per a %s)"
+
+#~ msgid "%s: In instantiation of `%s':\n"
+#~ msgstr "%s: En la instanciació de \"%s\":\n"
+
+#~ msgid "%s:%d: instantiated from `%s'\n"
+#~ msgstr "%s:%d: instanciat des de \"%s\"\n"
+
+#~ msgid "%s:%d: instantiated from here\n"
+#~ msgstr "%s:%d: instanciat des d'aquí\n"
+
+#~ msgid "previous friend declaration of `%D'"
+#~ msgstr "declaració friend prèvia de \"%D\""
+
+#~ msgid "cannot call destructor `%T::~%T' without object"
+#~ msgstr "no es pot cridar al destructor \"%T::%T\" sense un objecte"
+
+#~ msgid "invalid use of member `%D'"
+#~ msgstr "ús invàlid del membre \"%D\""
+
+#~ msgid "no method `%T::%D'"
+#~ msgstr "no hi ha un mètode \"%T::%D\""
+
+#~ msgid "object missing in use of pointer-to-member construct"
+#~ msgstr "manca objecte en l'ús d'una consctrucció que punta a membres"
+
+#~ msgid "member `%D' is non-static but referenced as a static member"
+#~ msgstr "el membre \"%D\" no és static però és referenciat com un membre static"
+
+#~ msgid "object missing in `%E'"
+#~ msgstr "falta un objecte en \"%E\""
+
+#~ msgid "initializer list being treated as compound expression"
+#~ msgstr "es tracta la llista d'inicialitzadors com una expressió composada"
+
+#~ msgid "ISO C++ forbids aggregate initializer to new"
+#~ msgstr "ISO C++ prohibeix un inicialitzador agregat per a new"
+
+#~ msgid "cannot declare references to references"
+#~ msgstr "no es poden declarar referències a referències"
+
+#~ msgid "cannot declare pointers to references"
+#~ msgstr "no es poden declarar punter a referències"
+
+#~ msgid "type name expected before `&'"
+#~ msgstr "s'esperava nom de tipus abans de \"&\""
+
+#~ msgid "semicolon missing after %s declaration"
+#~ msgstr "manca punt i coma després de la declaració %s"
+
+#~ msgid "semicolon missing after declaration of `%T'"
+#~ msgstr "manca punt i coma després de la declaració de \"%T\""
+
+#~ msgid "`::%D' undeclared (first use here)"
+#~ msgstr "\"::%D\" sense declarar (primer ús aquí)"
+
+#~ msgid "use of linkage spec `%D' is different from previous spec `%D'"
+#~ msgstr "l'ús de l'especificació d'enllaçat \"%D\" és diferent de l'especificació prèvia \"%D\""
+
+#~ msgid "use of template qualifier outside template"
+#~ msgstr "ús del qualificador de patró fora del patró"
+
+#~ msgid "ISO C++ forbids an empty condition for `%s'"
+#~ msgstr "ISO C++ prohibeix una condició buida per a \"%s\""
+
+#~ msgid "definition of class `%T' in condition"
+#~ msgstr "definició de la classe \"%T\" en una condició"
+
+#~ msgid "definition of enum `%T' in condition"
+#~ msgstr "definició del enum \"%T\" en una condició"
+
+#~ msgid "definition of array `%#D' in condition"
+#~ msgstr "definició de la matriu \"%#D\" en una condició"
+
+#~ msgid "old style placement syntax, use () instead"
+#~ msgstr "sintaxi d'ubicació d'estil antic, usi en el seu lloc ()"
+
+#~ msgid "`%T' is not a valid expression"
+#~ msgstr "\"%T\" no és una expressió vàlida"
+
+#~ msgid "initialization of new expression with `='"
+#~ msgstr "inicialització de l'expressió new amb \"=\""
+
+#~ msgid "invalid use of template `%D'"
+#~ msgstr "ús invàlid del patró \"%D\""
+
+#~ msgid "sigof type specifier"
+#~ msgstr "especificador de tipus sigof"
+
+#~ msgid "`sigof' applied to non-aggregate expression"
+#~ msgstr "\"sigof\" aplicat a una expressió no agregada"
+
+#~ msgid "`sigof' applied to non-aggregate type"
+#~ msgstr "\"sigof\" aplicat a un tipus no agregat"
+
+#~ msgid "storage class specifier `%s' not allowed after struct or class"
+#~ msgstr "no es permet el especificador de classe d'emmagatzematge \"%s\" després de struct o class"
+
+#~ msgid "type specifier `%s' not allowed after struct or class"
+#~ msgstr "no es permet el especificador de tipus \"%s\" després de struct o class"
+
+#~ msgid "type qualifier `%s' not allowed after struct or class"
+#~ msgstr "no es permet el qualificador de tipus \"%s\" després de struct o class"
+
+#~ msgid "no body nor ';' separates two class, struct or union declarations"
+#~ msgstr "no hi ha cos ni \";\" separant dues declaracions class, struct o union"
+
+#~ msgid "no bases given following `:'"
+#~ msgstr "no hi ha bases donat seguint \":\""
+
+#~ msgid "multiple access specifiers"
+#~ msgstr "specificadors d'accés múltiples"
+
+#~ msgid "multiple `virtual' specifiers"
+#~ msgstr "specificadors \"virtual\" múltiples"
+
+#~ msgid "missing ';' before right brace"
+#~ msgstr "falta \";\" abans de la clau dreta"
+
+#~ msgid "ISO C++ forbids array dimensions with parenthesized type in new"
+#~ msgstr "ISO C++ prohibeix les dimensions de matriu amb tipus amb parèntesi en new"
+
+#~ msgid "ISO C++ forbids label declarations"
+#~ msgstr "ISO C++ prohibeix declaracions d'etiquetes"
+
+#~ msgid "label must be followed by statement"
+#~ msgstr "l'etiqueta deu ser seguida d'una declaració"
+
+#~ msgid "must have at least one catch per try block"
+#~ msgstr "es deu tenir almenys un catch per cada bloc try"
+
+#~ msgid "ISO C++ forbids compound statements inside for initializations"
+#~ msgstr "ISO C++ prohibeix les declaracions compostoses internes per a inicialitzacions"
+
+#~ msgid "possibly missing ')'"
+#~ msgstr "possible \")\" faltant"
+
+#~ msgid "type specifier omitted for parameter"
+#~ msgstr "especificador de tipus omès per al paràmetre"
+
+#~ msgid "`%E' is not a type, use `typename %E' to make it one"
+#~ msgstr "\"%E\" no és un tipus, usi \"typename %E\" per a fer-lo un tipus"
+
+#~ msgid "no type `%D' in `%T'"
+#~ msgstr "no hi ha un tipus \"%D\" en \"%T\""
+
+#~ msgid "type specifier omitted for parameter `%E'"
+#~ msgstr "es va ometre el especificador per al paràmetre \"%E\""
+
+#~ msgid "type `%T' composed from a local class is not a valid template-argument"
+#~ msgstr "el tipus \"%T\" composat des d'una classe local no és un argument de patró vàlid"
+
+#~ msgid "adjusting pointers for covariant returns"
+#~ msgstr "ajustant els punters per a retorns covariants"
+
+#~ msgid " overriding `%#D' (must be pointer or reference to class)"
+#~ msgstr " substituint a \"%#D\" (deu ser punter o referència a una classe)"
+
+#~ msgid " overriding `%#D' (must use pointer or reference)"
+#~ msgstr " substituint a \"%#D\" (deu ser punter o referència)"
+
+#~ msgid "ISO C++ does not permit named return values"
+#~ msgstr "ISO C++ no permet valors de retorn nomenats"
+
+#~ msgid "return identifier `%D' already in place"
+#~ msgstr "l'identificador de retorn \"%D\" ja està en el seu lloc"
+
+#~ msgid "can't redefine default return value for constructors"
+#~ msgstr "no es pot redefinir el valor per omissió de retorn pels constructors"
+
+#~ msgid "calling type `%T' like a method"
+#~ msgstr "cridant al tipus \"%T\" com un mètode"
+
+#~ msgid "destructor specifier `%T::~%T()' must have matching names"
+#~ msgstr "el especificador del destructor \"%T::%T()\" deu tenir noms coincidents"
+
+#~ msgid "identifier name `%s' conflicts with GNU C++ internal naming strategy"
+#~ msgstr "el nom d'identificador \"%s\" causa conflictes amb l'estratègia interna de nomenatge del C++ de GNU"
+
+#~ msgid "parse error at end of saved function text"
+#~ msgstr "error de decodificació al final del text de la funció guardada"
+
+#~ msgid "parse error in method specification"
+#~ msgstr "error de decodificació en l'especificació del mètode"
+
+#~ msgid "function body for constructor missing"
+#~ msgstr "falta el cos de la funció pel constructor"
+
+#~ msgid "circular dependency in default args of `%#D'"
+#~ msgstr "dependència circular en els arguments per omissió de \"%#D\""
+
+#~ msgid "invalid type `%T' for default argument to `%T'"
+#~ msgstr "tipus \"%T\" invàlid per a l'argument per omissió de \"%T\""
+
+#~ msgid "%s before `%c'"
+#~ msgstr "%s abans de \"%c\""
+
+#~ msgid "%s before `\\%o'"
+#~ msgstr "%s abans de \"\\%o\""
+
+#~ msgid "%s before `%s' token"
+#~ msgstr "%s abans del testimoni \"%s\""
+
+#~ msgid "ISO C++ prohibits conversion from `%#T' to `(...)'"
+#~ msgstr "ISO C++ prohibeix la conversió de \"%#T\" a \"(...)\""
+
+#~ msgid "invalid application of `%s' to non-static member"
+#~ msgstr "ús invàlid de \"%s\" en un membre no static"
+
+#~ msgid "sizeof applied to a bit-field"
+#~ msgstr "sizeof aplicat a un camp de bits"
+
+#~ msgid "destructor specifier `%T::~%T' must have matching names"
+#~ msgstr "el especificador del destructor \"%T::~%T\" deu tenir noms coincidents"
+
+#~ msgid "parameter type of called function is incomplete"
+#~ msgstr "el tipus del paràmetre de la funció cridada és incomplet"
+
+#~ msgid "ISO C++ forbids using pointer to a member in subtraction"
+#~ msgstr "ISO C++ prohibeix l'ús d'un punter a un membre en la substracció"
+
+#~ msgid "reinterpret_cast from `%T' to `%T' casts away const (or volatile)"
+#~ msgstr "reinterpret_cast de \"%T\" a \"%T\" proscriu a const (o volatile)"
+
+#~ msgid "return-statement with no value, in function declared with a non-void return type"
+#~ msgstr "return-statement sense valor, en una funció declarada amb un tipus de retorn non-void"
+
+#~ msgid "return-statement with a value, in function declared with a void return type"
+#~ msgstr "return-statement amb un valor, en una funció declarada amb un tipus de retorn void"
+
+#~ msgid "comma expression used to initialize return value"
+#~ msgstr "es va usar una expressió coma per a inicialitzar el valor de retorn"
+
+#~ msgid "`%T' fails to be a typedef or built-in type"
+#~ msgstr "\"%T\" falla al ser un typedef o un tipus built-in"
+
+#~ msgid "ISO C++ forbids defining types within %s"
+#~ msgstr "ISO C++ prohibeix la definició de tipus dintre de %s"
+
+#~ msgid "Only emit explicit template instantiations"
+#~ msgstr "Emetre solament instanciacions explícites de patrons"
+
+#~ msgid "Recognize and/bitand/bitor/compl/not/or/xor"
+#~ msgstr "Reconèixer and/bitand/bitor/compl/not/or/xor"
+
+#~ msgid "Warn about inconsistent return types"
+#~ msgstr "Avisar sobre tipus inconsistents de retorn"
+
+#~ msgid "Warn when a function is declared extern, then inline"
+#~ msgstr "Avisar quan una funció és declarada extern i després inline"
+
+#~ msgid "directory name must immediately follow -I"
+#~ msgstr "el nom del directori deu seguir immediatament a -I"
+
+#~ msgid "ignoring pragma: %s"
+#~ msgstr "ignorant el pragma: %s"
+
+#~ msgid "Print g77-specific compiler version info, run internal tests"
+#~ msgstr "Imprimeix informació de la versió específica del compilador g77, executa proves internes"
+
+#~ msgid "Program is written in typical FORTRAN 66 dialect"
+#~ msgstr "El programa està escrit en el dialecte típic FORTRAN 66"
+
+#~ msgid "Program is written in typical Unix f77 dialect"
+#~ msgstr "El programa està escrit en el dialecte típic Unix f77"
+
+#~ msgid "Program does not use Unix-f77 dialectal features"
+#~ msgstr "El programa no utilitza les característiques del dialecte Unix-f77"
+
+#~ msgid "Program is written in Fortran-90-ish dialect"
+#~ msgstr "El programa en un dialecte proper a Fortran-90"
+
+#~ msgid "Treat local vars and COMMON blocks as if they were named in SAVE statements"
+#~ msgstr "Tractar les variables locals i els blocs COMMON com si fossin nomenats en declaracions SAVE"
+
+#~ msgid "Allow $ in symbol names"
+#~ msgstr "Permetre $ en els noms de símbols"
+
+#~ msgid "f2c-compatible code need not be generated"
+#~ msgstr "No es necessita generar codi compatible amb f2c"
+
+#~ msgid "Unsupported; do not generate libf2c-calling code"
+#~ msgstr "Sense suport; no genera codi de cridada a libf2c"
+
+#~ msgid "Unsupported; affects code-generation of arrays"
+#~ msgstr "Sense suport; afecta la generació de codi de les matrius"
+
+#~ msgid "Program is written in Fortran-90-ish free form"
+#~ msgstr "El programa està escrit en una forma lliure propera a Fortran-90"
+
+#~ msgid "Warn about use of (only a few for now) Fortran extensions"
+#~ msgstr "Avisar sobre l'ús d' (només algunes per ara) extensions Fortran"
+
+#~ msgid "Program is written in VXT (Digital-like) FORTRAN"
+#~ msgstr "El programa està escrit en VXT (com Digital) FORTRAN"
+
+#~ msgid "Disallow all ugly features"
+#~ msgstr "Desactiva totes les característiques lletjes"
+
+#~ msgid "Hollerith and typeless constants not passed as arguments"
+#~ msgstr "No es passen les constants Hollerith i sense tipus com arguments"
+
+#~ msgid "Allow ordinary copying of ASSIGN'ed vars"
+#~ msgstr "Permet la còpia ordinària de variables ASSIGN'ed"
+
+#~ msgid "Dummy array dimensioned to (1) is assumed-size"
+#~ msgstr "La matriu faltament dimensionada a (1) és de grandària assumida"
+
+#~ msgid "Trailing comma in procedure call denotes null argument"
+#~ msgstr "Coma al final de la cridada al procediment denota un argument null"
+
+#~ msgid "Allow REAL(Z) and AIMAG(Z) given DOUBLE COMPLEX Z"
+#~ msgstr "Permet que REAL(Z) i AIMAG(Z) rebin DOUBLE COMPLEX Z"
+
+#~ msgid "Initialization via DATA and PARAMETER is type-compatible"
+#~ msgstr "L'inicialització a través de DATA i PARAMETER és de tipus compatible"
+
+#~ msgid "Allow INTEGER and LOGICAL interchangeability"
+#~ msgstr "Permet l'intercanvi entre INTEGER i LOGICAL"
+
+#~ msgid "Print internal debugging-related info"
+#~ msgstr "Mostra la informació interna relacionada amb la depuració"
+
+#~ msgid "Initialize local vars and arrays to zero"
+#~ msgstr "Inicialitza les variables locals i matrius a zero"
+
+#~ msgid "Backslashes in character/hollerith constants not special (C-style)"
+#~ msgstr "Les barres invertides en constants de caràcter/hollerith no són especials (estil C)"
+
+#~ msgid "Have front end emulate COMPLEX arithmetic to avoid bugs"
+#~ msgstr "Fa que el front emuli aritmètica COMPLEX per a evitar errors"
+
+#~ msgid "Disable the appending of underscores to externals"
+#~ msgstr "Desactiva l'agregació de subratllats als externs"
+
+#~ msgid "Never append a second underscore to externals"
+#~ msgstr "Mai agregar un segon subratllat als externs"
+
+#~ msgid "Intrinsics spelled as e.g. SqRt"
+#~ msgstr "Intrínsecs lletrejats com p.e. SqRt"
+
+#~ msgid "Intrinsics in uppercase"
+#~ msgstr "Intrínsecs en majúscules"
+
+#~ msgid "Intrinsics letters in arbitrary cases"
+#~ msgstr "Lletres d'intrínsecs amb majúscules/minúscules indistintes"
+
+#~ msgid "Language keywords spelled as e.g. IOStat"
+#~ msgstr "Paraules claus del llenguatge lletrejades com p.e. IOStat"
+
+#~ msgid "Language keywords in uppercase"
+#~ msgstr "Paraules claus del llenguatge en majúscules"
+
+#~ msgid "Language keyword letters in arbitrary cases"
+#~ msgstr "Paraules claus del llenguatge amb majúscules/minúscules indistintes"
+
+#~ msgid "Internally convert most source to uppercase"
+#~ msgstr "Convertir internament gairebé tot el codi a majúscules"
+
+#~ msgid "Internally preserve source case"
+#~ msgstr "Preservar internament les majúscules i minúscules del codi font"
+
+#~ msgid "Symbol names spelled in mixed case"
+#~ msgstr "Noms de símbol lletrejats amb majúscules/minúscules barrejades"
+
+#~ msgid "Symbol names in uppercase"
+#~ msgstr "Noms de símbol en majúscules"
+
+#~ msgid "Symbol names in lowercase"
+#~ msgstr "Noms de símbol en minúscules"
+
+#~ msgid "Program written in uppercase"
+#~ msgstr "Programa escrit en majúscules"
+
+#~ msgid "Program written in lowercase"
+#~ msgstr "Programa escrit en minúscules"
+
+#~ msgid "Program written in strict mixed-case"
+#~ msgstr "Programa escrit estrictament amb majúscules i minúscules barrejades"
+
+#~ msgid "Compile as if program written in uppercase"
+#~ msgstr "Compilar com si el programa estigués escrit en majúscules"
+
+#~ msgid "Compile as if program written in lowercase"
+#~ msgstr "Compilar com si el programa estigués escrit en minúscules"
+
+#~ msgid "Preserve all spelling (case) used in program"
+#~ msgstr "Preservar tot el lletrejo (majúscules/minúscules) usat en el programa"
+
+#~ msgid "Delete libU77 intrinsics with bad interfaces"
+#~ msgstr "Esborrar els intrínsecs libU77 amb interfícies errònies"
+
+#~ msgid "Disable libU77 intrinsics with bad interfaces"
+#~ msgstr "Desactivar els intrínsecs libU77 amb interfícies errònies"
+
+#~ msgid "Hide libU77 intrinsics with bad interfaces"
+#~ msgstr "Amagar els intrínsecs libU77 amb interfícies errònies"
+
+#~ msgid "Delete non-FORTRAN-77 intrinsics f2c supports"
+#~ msgstr "Esborrar els intrínsecs de FORTRAN que no és 77 que f2c suporta"
+
+#~ msgid "Disable non-FORTRAN-77 intrinsics f2c supports"
+#~ msgstr "Desactivar els intrínsecs de FORTRAN que no és 77 que f2c suporta"
+
+#~ msgid "Hide non-FORTRAN-77 intrinsics f2c supports"
+#~ msgstr "Amagar els intrínsecs de FORTRAN que no és 77 que f2c suporta"
+
+#~ msgid "Delete non-FORTRAN-77 intrinsics F90 supports"
+#~ msgstr "Esborrar els intrínsecs de FORTRAN que no és 77 que F90 suporta"
+
+#~ msgid "Disable non-FORTRAN-77 intrinsics F90 supports"
+#~ msgstr "Desactivar els intrínsecs de FORTRAN que no és 77 que F90 suporta"
+
+#~ msgid "Hide non-FORTRAN-77 intrinsics F90 supports"
+#~ msgstr "Amagar els intrínsecs de FORTRAN que no és 77 que F90 suporta"
+
+#~ msgid "Delete non-FORTRAN-77 intrinsics g77 supports"
+#~ msgstr "Esborrar els intrínsecs de FORTRAN que no és 77 que g77 suporta"
+
+#~ msgid "Disable non-FORTRAN 77 intrinsics F90 supports"
+#~ msgstr "Desactivar els intrínsecs de FORTRAN que no és 77 que g77 suporta"
+
+#~ msgid "Hide non-FORTRAN 77 intrinsics F90 supports"
+#~ msgstr "Amagar els intrínsecs de FORTRAN que no és 77 que g77 suporta"
+
+#~ msgid "Delete MIL-STD 1753 intrinsics"
+#~ msgstr "Esborrar els intrínsecs MIL-STD 1753"
+
+#~ msgid "Disable MIL-STD 1753 intrinsics"
+#~ msgstr "Desactivar els intrínsecs MIL-STD 1753"
+
+#~ msgid "Hide MIL-STD 1753 intrinsics"
+#~ msgstr "Amagar els intrínsecs MIL-STD 1753"
+
+#~ msgid "Delete libU77 intrinsics"
+#~ msgstr "Esborrar els intrínsecs libU77"
+
+#~ msgid "Disable libU77 intrinsics"
+#~ msgstr "Desactivar els intrínsecs libU77"
+
+#~ msgid "Hide libU77 intrinsics"
+#~ msgstr "Amagar els intrínsecs libU77"
+
+#~ msgid "Delete non-FORTRAN-77 intrinsics VXT FORTRAN supports"
+#~ msgstr "Esborrar els intrínsecs de FORTRAN que no és 77 que VXT FORTRAN suporta"
+
+#~ msgid "Disable non-FORTRAN-77 intrinsics VXT FORTRAN supports"
+#~ msgstr "Desactivar els intrínsecs de FORTRAN que no és 77 que VXT FORTRAN suporta"
+
+#~ msgid "Hide non-FORTRAN-77 intrinsics VXT FORTRAN supports"
+#~ msgstr "Amagar els intrínsecs de FORTRAN que no és 77 que VXT FORTRAN suporta"
+
+#~ msgid "Treat initial values of 0 like non-zero values"
+#~ msgstr "Tractar els valors inicials de 0 com valors que no són zero"
+
+#~ msgid "Emit special debugging information for COMMON and EQUIVALENCE (disabled)"
+#~ msgstr "Emetre informació especial de depuració per a COMMON i EQUIVALENCE (desactivat)"
+
+#~ msgid "Take at least one trip through each iterative DO loop"
+#~ msgstr "Prendre almenys un viatge a través de cada cicle DO iteratiu"
+
+#~ msgid "Disable fatal diagnostics about inter-procedural problems"
+#~ msgstr "Desactivar els diagnòstics fatals sobre problemes interprocedurals"
+
+#~ msgid "Make prefix-radix non-decimal constants be typeless"
+#~ msgstr "Fer que no tinguin tipus les constants amb prefix-radical que no és decimal"
+
+#~ msgid "Generate code to check subscript and substring bounds"
+#~ msgstr "Generar codi per a revisar els límits de subíndicis i subcadenes"
+
+#~ msgid "Fortran-specific form of -fbounds-check"
+#~ msgstr "Forma específica de Fortran de -fbounds-check"
+
+#~ msgid "Disable warnings about inter-procedural problems"
+#~ msgstr "Desactivar els avisos sobre problemes interprocedurals"
+
+#~ msgid "Warn about constructs with surprising meanings"
+#~ msgstr "Avisar sobre constructors amb significats sorprenents"
+
+#~ msgid "Add a directory for INCLUDE searching"
+#~ msgstr "Agregar un directori per a la recerca de INCLUDE"
+
+#~ msgid "Set the maximum line length"
+#~ msgstr "Establir la longitud màxima de línia"
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 717489f3216..ecab52b68ee 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -293,12 +293,12 @@ struct elim_table
{
int from; /* Register number to be eliminated. */
int to; /* Register number used as replacement. */
- HOST_WIDE_INT initial_offset; /* Initial difference between values. */
+ int initial_offset; /* Initial difference between values. */
int can_eliminate; /* Nonzero if this elimination can be done. */
int can_eliminate_previous; /* Value of CAN_ELIMINATE in previous scan over
insns made by reload. */
- HOST_WIDE_INT offset; /* Current offset between the two regs. */
- HOST_WIDE_INT previous_offset;/* Offset at end of previous insn. */
+ int offset; /* Current offset between the two regs. */
+ int previous_offset; /* Offset at end of previous insn. */
int ref_outside_mem; /* "to" has been referenced outside a MEM. */
rtx from_rtx; /* REG rtx for the register to be eliminated.
We cannot simply compare the number since
@@ -352,7 +352,7 @@ static int num_eliminable_invariants;
static int first_label_num;
static char *offsets_known_at;
-static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
+static int (*offsets_at)[NUM_ELIMINABLE_REGS];
/* Number of labels in the current function. */
@@ -816,7 +816,7 @@ reload (rtx first, int global)
allocate would occasionally cause it to exceed the stack limit and
cause a core dump. */
offsets_known_at = xmalloc (num_labels);
- offsets_at = xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (HOST_WIDE_INT));
+ offsets_at = xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (int));
/* Alter each pseudo-reg rtx to contain its hard reg number.
Assign stack slots to the pseudos that lack hard regs or equivalents.
@@ -2897,7 +2897,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
{
rtx base = SET_SRC (old_set);
rtx base_insn = insn;
- HOST_WIDE_INT offset = 0;
+ int offset = 0;
while (base != ep->to_rtx)
{
@@ -2980,7 +2980,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
&& REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
{
rtx reg = XEXP (SET_SRC (old_set), 0);
- HOST_WIDE_INT offset = INTVAL (XEXP (SET_SRC (old_set), 1));
+ int offset = INTVAL (XEXP (SET_SRC (old_set), 1));
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
if (ep->from_rtx == reg && ep->can_eliminate)
@@ -3263,7 +3263,7 @@ mark_not_eliminable (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
static void
verify_initial_elim_offsets (void)
{
- HOST_WIDE_INT t;
+ int t;
#ifdef ELIMINABLE_REGS
struct elim_table *ep;
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/rtlhooks-def.h b/gcc/rtlhooks-def.h
new file mode 100644
index 00000000000..aaae80cab8c
--- /dev/null
+++ b/gcc/rtlhooks-def.h
@@ -0,0 +1,46 @@
+/* Default macros to initialize an rtl_hooks data structure.
+ 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. */
+
+#ifndef GCC_RTL_HOOKS_DEF_H
+#define GCC_RTL_HOOKS_DEF_H
+
+#include "rtl.h"
+
+#define RTL_HOOKS_GEN_LOWPART gen_lowpart_general
+#define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general
+#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general
+
+/* The structure is defined in rtl.h. */
+#define RTL_HOOKS_INITIALIZER { \
+ RTL_HOOKS_GEN_LOWPART, \
+ RTL_HOOKS_REG_NONZERO_REG_BITS, \
+ RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES, \
+}
+
+extern rtx gen_lowpart_general (enum machine_mode, rtx);
+extern rtx reg_nonzero_bits_general (rtx, enum machine_mode, rtx,
+ enum machine_mode,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT *);
+extern rtx reg_num_sign_bit_copies_general (rtx, enum machine_mode, rtx,
+ enum machine_mode,
+ unsigned int, unsigned int *);
+
+#endif /* GCC_RTL_HOOKS_DEF_H */
diff --git a/gcc/rtlhooks.c b/gcc/rtlhooks.c
new file mode 100644
index 00000000000..5cb14efd140
--- /dev/null
+++ b/gcc/rtlhooks.c
@@ -0,0 +1,103 @@
+/* Generic hooks for the RTL middle-end.
+ 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 "rtl.h"
+#include "rtlhooks-def.h"
+#include "expr.h"
+
+
+/* For speed, we will copy the RTX hooks struct member-by-member
+ instead of doing indirect calls. For these reason, we initialize
+ *two* struct rtl_hooks globals: rtl_hooks is the one that is used
+ to actually call the hooks, while general_rtl_hooks is used
+ to restore the hooks by passes that modify them. */
+
+const struct rtl_hooks general_rtl_hooks = RTL_HOOKS_INITIALIZER;
+struct rtl_hooks rtl_hooks = RTL_HOOKS_INITIALIZER;
+
+rtx
+gen_lowpart_general (enum machine_mode mode, rtx x)
+{
+ rtx result = gen_lowpart_common (mode, x);
+
+ if (result)
+ return result;
+ else if (REG_P (x))
+ {
+ /* Must be a hard reg that's not valid in MODE. */
+ result = gen_lowpart_common (mode, copy_to_reg (x));
+ if (result == 0)
+ abort ();
+ return result;
+ }
+ else if (MEM_P (x))
+ {
+ /* The only additional case we can do is MEM. */
+ int offset = 0;
+
+ /* The following exposes the use of "x" to CSE. */
+ if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
+ && SCALAR_INT_MODE_P (GET_MODE (x))
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+ GET_MODE_BITSIZE (GET_MODE (x)))
+ && ! no_new_pseudos)
+ return gen_lowpart_general (mode, force_reg (GET_MODE (x), x));
+
+ if (WORDS_BIG_ENDIAN)
+ offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
+ - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
+
+ if (BYTES_BIG_ENDIAN)
+ /* Adjust the address so that the address-after-the-data
+ is unchanged. */
+ offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
+ - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
+
+ return adjust_address (x, mode, offset);
+ }
+ else
+ abort ();
+}
+
+rtx
+reg_num_sign_bit_copies_general (rtx x ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx known_x ATTRIBUTE_UNUSED,
+ enum machine_mode known_mode ATTRIBUTE_UNUSED,
+ unsigned int known_ret ATTRIBUTE_UNUSED,
+ unsigned int *result ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+rtx
+reg_nonzero_bits_general (rtx x ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx known_x ATTRIBUTE_UNUSED,
+ enum machine_mode known_mode ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT known_ret ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT *nonzero ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
diff --git a/gcc/statistics.h b/gcc/statistics.h
new file mode 100644
index 00000000000..2b0656574dd
--- /dev/null
+++ b/gcc/statistics.h
@@ -0,0 +1,34 @@
+/* Memory statistics helpers.
+ Copyright (C) 2004
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#ifndef GCC_STATISTICS
+#define GCC_STATISTICS
+#ifdef GATHER_STATISTICS
+#define MEM_STAT_DECL , const char *_loc_name ATTRIBUTE_UNUSED, int _loc_line ATTRIBUTE_UNUSED, const char *_loc_function ATTRIBUTE_UNUSED
+#define PASS_MEM_STAT , _loc_name, _loc_line, _loc_function
+#define MEM_STAT_INFO , __FILE__, __LINE__, __FUNCTION__
+#else
+#define MEM_STAT_DECL
+#define PASS_MEM_STAT
+#define MEM_STAT_INFO
+#endif
+#endif
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 51638375633..47a7512c64f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,10 +1,3 @@
-2003-10-27 Jakub Jelinek <jakub@redhat.com>
-
- * gcc.c-torture/compile/20031023-1.c: New test.
- * gcc.c-torture/compile/20031023-2.c: New test.
- * gcc.c-torture/compile/20031023-3.c: New test.
- * gcc.c-torture/compile/20031023-4.c: New test.
-
2003-10-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/10371
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/norun.lst b/gcc/testsuite/ada/acats/norun.lst
index c0b08e42c07..6da22250000 100644
--- a/gcc/testsuite/ada/acats/norun.lst
+++ b/gcc/testsuite/ada/acats/norun.lst
@@ -1,2 +1,4 @@
+cdd2a03
templat
# Tests must be sorted in alphabetical order
+# cdd2a03: new Ada ruling not supported yet.
diff --git a/gcc/testsuite/ada/acats/run_acats b/gcc/testsuite/ada/acats/run_acats
index c69a4e1fe3e..24d87853e13 100755
--- a/gcc/testsuite/ada/acats/run_acats
+++ b/gcc/testsuite/ada/acats/run_acats
@@ -7,17 +7,41 @@ fi
# Set up environment to use the Ada compiler from the object tree
-host_gnatmake=`which gnatmake`
-host_gcc=`which gcc`
-ROOT=`pwd`
-BASE=`cd $ROOT/../../..; pwd`
+host_gnatchop=`type gnatchop | awk '{print $3}'`
+host_gnatmake=`type gnatmake | awk '{print $3}'`
+ROOT=`${PWDCMD-pwd}`
+BASE=`cd $ROOT/../../..; ${PWDCMD-pwd}`
+
PATH=$BASE:$ROOT:$PATH
ADA_INCLUDE_PATH=$BASE/ada/rts
ADA_OBJECTS_PATH=$ADA_INCLUDE_PATH
-export PATH ADA_INCLUDE_PATH ADA_OBJECTS_PATH
-echo '#!/bin/sh' > gcc
-echo exec $BASE/xgcc -B$BASE/ '"$@"' >> gcc
+if [ ! -d $ADA_INCLUDE_PATH ]; then
+ echo gnatlib missing, exiting.
+ exit 1
+fi
+
+if [ ! -f $BASE/gnatchop ]; then
+ echo gnattools missing, exiting.
+ exit 1
+fi
+
+if [ ! -f $BASE/gnatmake ]; then
+ echo gnattools missing, exiting.
+ exit 1
+fi
+
+GCC_DRIVER="$BASE/xgcc"
+GCC="$BASE/xgcc -B$BASE/"
+export PATH ADA_INCLUDE_PATH ADA_OBJECTS_PATH GCC_DRIVER GCC
+
+echo '#!/bin/sh' > host_gnatchop
+echo PATH=`dirname $host_gnatchop`:'$PATH' >> host_gnatchop
+echo unset ADA_INCLUDE_PATH ADA_OBJECTS_PATH GCC_EXEC_PREFIX >> host_gnatchop
+echo export PATH >> host_gnatchop
+echo exec $host_gnatchop '"$@"' >> host_gnatchop
+
+chmod +x host_gnatchop
echo '#!/bin/sh' > host_gnatmake
echo PATH=`dirname $host_gnatmake`:'$PATH' >> host_gnatmake
@@ -25,11 +49,6 @@ echo unset ADA_INCLUDE_PATH ADA_OBJECTS_PATH GCC_EXEC_PREFIX >> host_gnatmake
echo export PATH >> host_gnatmake
echo exec $host_gnatmake '"$@"' >> host_gnatmake
-echo '#!/bin/sh' > host_gcc
-echo PATH=`dirname $host_gcc`:'$PATH' >> host_gcc
-echo export PATH >> host_gcc
-echo exec $host_gcc '"$@"' >> host_gcc
-
-chmod +x gcc host_gnatmake host_gcc
+chmod +x host_gnatmake
exec $testdir/run_all.sh "$@"
diff --git a/gcc/testsuite/ada/acats/run_all.sh b/gcc/testsuite/ada/acats/run_all.sh
index 4c0619959b6..b317aa73f4c 100755
--- a/gcc/testsuite/ada/acats/run_all.sh
+++ b/gcc/testsuite/ada/acats/run_all.sh
@@ -9,8 +9,8 @@
# gccflags="-O3 -fomit-frame-pointer -funroll-all-loops -finline-functions"
# gnatflags="-gnatN"
-gccflags=""
-gnatflags="-q -gnatws"
+gccflags="-O2"
+gnatflags="-gnatws"
target_run () {
$*
@@ -18,7 +18,24 @@ $*
# End of customization section.
-dir=`pwd`
+display_noeol () {
+ printf "$@"
+ printf "$@" >> $dir/acats.sum
+ printf "$@" >> $dir/acats.log
+}
+
+display () {
+ echo "$@"
+ echo "$@" >> $dir/acats.sum
+ echo "$@" >> $dir/acats.log
+}
+
+log () {
+ echo "$@" >> $dir/acats.sum
+ echo "$@" >> $dir/acats.log
+}
+
+dir=`${PWDCMD-pwd}`
if [ "$testdir" = "" ]; then
echo You must use make check or make check-ada
@@ -30,12 +47,17 @@ if [ "$dir" = "$testdir" ]; then
exit 1
fi
+target_gnatchop () {
+ gnatchop --GCC="$GCC_DRIVER" $*
+}
+
target_gnatmake () {
- gnatmake $gnatflags $gccflags $* -largs $EXTERNAL_OBJECTS
+ echo gnatmake --GCC=\"$GCC\" $gnatflags $gccflags $* -largs $EXTERNAL_OBJECTS --GCC=\"$GCC\"
+ gnatmake --GCC="$GCC" $gnatflags $gccflags $* -largs $EXTERNAL_OBJECTS --GCC="$GCC"
}
target_gcc () {
- gcc $gccflags $*
+ $GCC $gccflags $*
}
clean_dir () {
@@ -45,31 +67,55 @@ clean_dir () {
EXTERNAL_OBJECTS=""
# Global variable to communicate external objects to link with.
-echo ""
-echo ==== CONFIGURATION ==== `date`
+rm -f $dir/acats.sum $dir/acats.log
+
+display " === acats configuration ==="
+
+target=`$GCC -dumpmachine`
-type gcc
-gcc -v 2>&1
-echo host=`host_gcc -dumpmachine`
-echo target=`gcc -dumpmachine`
-type gnatmake
-gnatls -v
-echo acats src=$testdir
-echo acats obj=$dir
-echo ""
+display target gcc is $GCC
+display `$GCC -v 2>&1`
+display host=`gcc -dumpmachine`
+display target=$target
+display `type gnatmake`
+gnatls -v >> $dir/acats.log
+display ""
-echo ==== SUPPORT ==== `date`
-printf "Generating support files..."
+display " === acats support ==="
+display_noeol "Generating support files..."
rm -rf $dir/support
mkdir -p $dir/support
cd $dir/support
-cp $testdir/support/{*.ada,*.a,*.tst} $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
@@ -78,87 +124,88 @@ cp $testdir/tests/cd/*.c $dir/support
cp $testdir/tests/cxb/*.c $dir/support
rm -rf $dir/run
-mv $dir/tests $dir/tests.$$
+mv $dir/tests $dir/tests.$$ 2> /dev/null
rm -rf $dir/tests.$$ &
mkdir -p $dir/run
cp -pr $testdir/tests $dir/
-for i in $dir/support/{*.ada,*.a}; do
- gnatchop $i > /dev/null 2>&1
+for i in $dir/support/*.ada $dir/support/*.a; do
+ host_gnatchop $i >> $dir/acats.log 2>&1
done
# These tools are used to preprocess some ACATS sources
# they need to be compiled native on the host.
-host_gnatmake -q -gnatws macrosub
+host_gnatmake -q -gnatws macrosub.adb
if [ $? -ne 0 ]; then
- echo "**** Failed to compile macrosub"
+ display "**** Failed to compile macrosub"
exit 1
fi
./macrosub > macrosub.out 2>&1
-host_gcc -c cd300051.c
-host_gnatmake -q -gnatws widechr
+gcc -c cd300051.c
+host_gnatmake -q -gnatws widechr.adb
if [ $? -ne 0 ]; then
- echo "**** Failed to compile widechr"
+ display "**** Failed to compile widechr"
exit 1
fi
./widechr > widechr.out 2>&1
-rm -f $dir/support/{macrosub,widechr,*.ali,*.o}
+rm -f $dir/support/macrosub
+rm -f $dir/support/widechr
+rm -f $dir/support/*.ali
+rm -f $dir/support/*.o
-echo " done."
+display " done."
# From here, all compilations will be made by the target compiler
-printf "Compiling support files..."
+display_noeol "Compiling support files..."
target_gcc -c *.c
if [ $? -ne 0 ]; then
- echo "**** Failed to compile C code"
+ display "**** Failed to compile C code"
exit 1
fi
-gnatchop *.adt > gnatchop.out 2>&1
+target_gnatchop *.adt >> $dir/acats.log 2>&1
-target_gnatmake -c -gnato -gnatE *.ads > /dev/null 2>&1
-target_gnatmake -c -gnato -gnatE *.adb
+target_gnatmake -c -gnato -gnatE *.ads >> $dir/acats.log 2>&1
+target_gnatmake -c -gnato -gnatE *.adb >> $dir/acats.log 2>&1
-echo " done."
-echo ""
-echo ==== TESTS ==== `date`
+display " done."
+display ""
+display " === acats tests ==="
if [ $# -eq 0 ]; then
- chapters=`cd $dir/tests; echo *`
+ chapters=`cd $dir/tests; echo [a-z]*`
else
chapters=$*
fi
glob_countn=0
glob_countok=0
+glob_countu=0
for chapter in $chapters; do
- echo ==== CHAPTER $chapter ==== `date`
+ display Running chapter $chapter ...
if [ ! -d $dir/tests/$chapter ]; then
- echo "**** CHAPTER $chapter does not exist, skipping."
- echo ""
+ display "*** CHAPTER $chapter does not exist, skipping."
+ display ""
continue
fi
cd $dir/tests/$chapter
- ls *.{a,ada,adt,am,dep} 2> /dev/null | sed -e 's/\(.*\)\..*/\1/g' | \
+ ls *.a *.ada *.adt *.am *.dep 2> /dev/null | sed -e 's/\(.*\)\..*/\1/g' | \
cut -c1-7 | sort | uniq | comm -23 - $testdir/norun.lst \
> $dir/tests/$chapter/${chapter}.lst
countn=`wc -l < $dir/tests/$chapter/${chapter}.lst`
- countok=0
+ glob_countn=`expr $glob_countn + $countn`
counti=0
for i in `cat $dir/tests/$chapter/${chapter}.lst`; do
counti=`expr $counti + 1`
- echo ""
- echo ""
- echo ==== $i === `date` === $counti / $countn
extraflags=""
grep $i $testdir/overflow.lst > /dev/null 2>&1
if [ $? -eq 0 ]; then
@@ -168,15 +215,23 @@ for chapter in $chapters; do
if [ $? -eq 0 ]; then
extraflags="$extraflags -gnatE"
fi
- mkdir $dir/tests/$chapter/$i
- cd $dir/tests/$chapter/$i
- gnatchop -c -w `ls $dir/tests/${chapter}/${i}*.{a,ada,adt,am,dep} 2> /dev/null` > /dev/null 2>&1
+ test=$dir/tests/$chapter/$i
+ mkdir $test && cd $test >> $dir/acats.log 2>&1
+
+ if [ $? -ne 0 ]; then
+ display "FAIL: $i"
+ failed="${failed}${i} "
+ clean_dir
+ continue
+ fi
+
+ target_gnatchop -c -w `ls ${test}*.a ${test}*.ada ${test}*.adt ${test}*.am ${test}*.dep 2> /dev/null` >> $dir/acats.log 2>&1
ls ${i}?.adb > ${i}.lst 2> /dev/null
ls ${i}*m.adb >> ${i}.lst 2> /dev/null
ls ${i}.adb >> ${i}.lst 2> /dev/null
main=`tail -1 ${i}.lst`
binmain=`echo $main | sed -e 's/\(.*\)\..*/\1/g'`
- echo "BUILD $main"
+ echo "BUILD $main" >> $dir/acats.log
EXTERNAL_OBJECTS=""
case $i in
cxb30*) EXTERNAL_OBJECTS="$dir/support/cxb30040.o $dir/support/cxb30060.o $dir/support/cxb30130.o $dir/support/cxb30131.o";;
@@ -185,47 +240,55 @@ for chapter in $chapters; do
cxh1001) extraflags="-a -f"; echo "pragma Normalize_Scalars;" > gnat.adc
esac
if [ "$main" = "" ]; then
- echo "**** SCRIPT-MAIN FAILED $i"
+ display "FAIL: $i"
failed="${failed}${i} "
clean_dir
continue
fi
- target_gnatmake $extraflags -I$dir/support $main
+ target_gnatmake $extraflags -I$dir/support $main >> $dir/acats.log 2>&1
if [ $? -ne 0 ]; then
- echo "**** SCRIPT-BUILD FAILED $i"
+ display "FAIL: $i"
failed="${failed}${i} "
clean_dir
continue
fi
- echo "RUN $binmain"
+ echo "RUN $binmain" >> $dir/acats.log
cd $dir/run
- target_run $dir/tests/$chapter/$i/$binmain | tee $dir/tests/$chapter/$i/${i}.log 2>&1
+ target_run $dir/tests/$chapter/$i/$binmain > $dir/tests/$chapter/$i/${i}.log 2>&1
cd $dir/tests/$chapter/$i
+ cat ${i}.log >> $dir/acats.log
egrep -e '(==== |\+\+\+\+ |\!\!\!\! )' ${i}.log > /dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "**** SCRIPT-RUN FAILED $i"
- failed="${failed}${i} "
+ grep 'Tasking not implemented' ${i}.log > /dev/null 2>&1
+
+ if [ $? -ne 0 ]; then
+ display "FAIL: $i"
+ failed="${failed}${i} "
+ else
+ log "UNSUPPORTED: $i"
+ glob_countn=`expr $glob_countn - 1`
+ glob_countu=`expr $glob_countu + 1`
+ fi
else
- countok=`expr $countok + 1`
+ log "PASS: $i"
+ glob_countok=`expr $glob_countok + 1`
fi
clean_dir
done
-
- echo ""
- echo ==== CHAPTER $chapter results: $countok / $countn
- echo ""
- glob_countok=`expr $glob_countok + $countok`
- glob_countn=`expr $glob_countn + $countn`
done
-echo ==== ACATS results: $glob_countok / $glob_countn
+display " === acats Summary ==="
+display "# of expected passes $glob_countok"
+display "# of unexpected failures `expr $glob_countn - $glob_countok`"
-if [ $glob_countok -ne $glob_countn ]; then
- echo "**** FAILURES: $failed"
+if [ $glob_countu -ne 0 ]; then
+ display "# of unsupported tests $glob_countu"
fi
-echo "#### ACATS done. #### `date`"
+if [ $glob_countok -ne $glob_countn ]; then
+ display "*** FAILURES: $failed"
+fi
exit 0
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/impdefc.a b/gcc/testsuite/ada/acats/support/impdefc.a
deleted file mode 100644
index f59a3a60838..00000000000
--- a/gcc/testsuite/ada/acats/support/impdefc.a
+++ /dev/null
@@ -1,153 +0,0 @@
--- Version of IMPDEFC.A modified for ACT interrupt support
---
--- IMPDEFC.A
---
--- Grant of Unlimited Rights
---
--- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
--- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
--- to do so.
---
--- DISCLAIMER
---
--- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
--- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
--- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--- PARTICULAR PURPOSE OF SAID MATERIAL.
---*
---
--- DESCRIPTION:
--- This package provides tailorable entities for a particular
--- implementation. Each entity may be modified to suit the needs
--- of the implementation. Default values are provided to act as
--- a guide.
---
--- The entities in this package are those which are used exclusively
--- in tests for Annex C (Systems Programming).
---
--- APPLICABILITY CRITERIA:
--- This package is only required for implementations validating the
--- Systems Programming Annex.
---
--- CHANGE HISTORY:
--- 29 Jan 96 SAIC Initial version for ACVC 2.1.
---
---!
-
-with Ada.Interrupts.Names;
-
-package ImpDef.Annex_C is
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
- -- Interrupt_To_Generate should identify a non-reserved interrupt
- -- that can be predictably generated within a reasonable time interval
- -- (as specified by the constant Wait_For_Interrupt) during testing.
-
- Interrupt_To_Generate: constant Ada.Interrupts.Interrupt_ID :=
- Ada.Interrupts.Names.SIGPIPE; -- to allow trivial compilation
- -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- MODIFY HERE AS NEEDED
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
- -- Wait_For_Interrupt should specify the reasonable time interval during
- -- which the interrupt identified by Interrupt_To_Generate can be
- -- expected to be generated.
-
- Wait_For_Interrupt : constant := 0.1;
- -- ^^^^ --- MODIFY HERE AS NEEDED
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
- -- The procedure Enable_Interrupts should enable interrupts, if this
- -- is required by the implementation. [See additional notes on this
- -- procedure in the package body.]
-
- procedure Enable_Interrupts;
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
- -- The procedure Generate_Interrupt should generate the interrupt
- -- identified by Interrupt_To_Generate within the time interval
- -- specified by Wait_For_Interrupt. [See additional notes on this
- -- procedure in the package body.]
-
- procedure Generate_Interrupt;
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
-end ImpDef.Annex_C;
-
-
-
- --==================================================================--
-
-
-package body ImpDef.Annex_C is
-
- -- NOTE: These are example bodies. It is expected that implementors
- -- will write their own versions of these routines.
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
- -- The procedure Enable_Interrupts should enable interrupts, if this
- -- is required by the implementation.
- --
- -- The default body is null, since it is expected that most implementations
- -- will not need to perform this step.
- --
- -- Note that Enable_Interrupts will be called only once per test.
-
- procedure Enable_Interrupts is
- begin
- null;
-
- -- ^^^^^^^^^^^^^^^^^^^^ MODIFY THIS BODY AS NEEDED ^^^^^^^^^^^^^^^^^^^^
-
- end Enable_Interrupts;
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
- -- The procedure Generate_Interrupt should generate the interrupt
- -- identified by Interrupt_To_Generate within the time interval
- -- specified by Wait_For_Interrupt.
- --
- -- The default body assumes that an interrupt will be generated by some
- -- physical act during testing. While this approach is acceptable, the
- -- interrupt should ideally be generated by appropriate code in the
- -- procedure body.
- --
- -- Note that Generate_Interrupt may be called multiple times by a single
- -- test. The code used to implement this procedure should account for this
- -- possibility.
-
- procedure Generate_Interrupt is
-
- procedure c_kill (pid : Integer; sig : in Ada.Interrupts.Interrupt_ID);
- pragma Import (C, c_kill, "kill");
-
- function c_getpid return Integer;
- pragma Import (C, c_getpid, "getpid");
-
- Pid : integer := c_getpid;
- begin
- Report.Comment (". >>>>> GENERATE THE INTERRUPT NOW <<<<< " & integer'image (pid) & " " & Ada.Interrupts.Interrupt_ID'image (Interrupt_To_Generate));
- c_kill (pid, Interrupt_To_Generate);
-
- -- ^^^^^^^^^^^^^^^^^^^^ MODIFY THIS BODY AS NEEDED ^^^^^^^^^^^^^^^^^^^^
-
- end Generate_Interrupt;
-
---=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
-
-end ImpDef.Annex_C;
-
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/abi/covariant2.C b/gcc/testsuite/g++.dg/abi/covariant2.C
new file mode 100644
index 00000000000..87eb2a2708c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/covariant2.C
@@ -0,0 +1,32 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 12 Dec 2003 <nathan@codesourcery.com>
+// Origin: grigory@stl.sarov.ru
+
+// PR c++/12881. ICE in thunk generation
+
+struct c1 {};
+
+struct c3 : virtual c1
+{
+ virtual c1* f6() {};
+ int i;
+};
+
+struct c6 : virtual c3 { };
+
+struct c7 : c3
+{
+ virtual c3* f6() {};
+};
+
+struct c24 : virtual c7
+{
+ virtual c6* f6();
+};
+
+c6* c24::f6() { return 0; }
+
+struct c31 : c24 {};
+
diff --git a/gcc/testsuite/g++.dg/abi/covariant3.C b/gcc/testsuite/g++.dg/abi/covariant3.C
new file mode 100644
index 00000000000..178157c58b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/covariant3.C
@@ -0,0 +1,85 @@
+// { dg-do run }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 12 Dec 2003 <nathan@codesourcery.com>
+// Origin: grigory@stl.sarov.ru
+
+// PR c++/13118. Missing covariant thunk.
+
+struct c0 {};
+struct c1 : virtual c0 {
+ virtual c0* f6();
+};
+
+struct c5 {
+ virtual void foo();
+};
+
+struct c10 : virtual c1 {
+ virtual void foo();
+};
+
+struct c1a : c1 {}; // disambiguation
+
+struct c11 : virtual c10, c1a {
+ int i;
+ virtual c1* f6 () = 0;
+};
+
+struct c18 : c5, virtual c1 {
+ virtual void bar();
+};
+
+struct c28 : virtual c0, virtual c11 {
+ virtual c18* f6();
+};
+
+c0 *c1::f6 () {}
+void c5::foo () {}
+void c10::foo () {}
+void c18::bar () {}
+
+c18 ret;
+
+c18 *c28::f6 ()
+{
+ return &ret;
+}
+
+bool check_c1 (c1 *ptr)
+{
+ c0 *r = ptr->f6 ();
+ return r != &ret;
+}
+bool check_c10 (c10 *ptr)
+{
+ c0 *r = ptr->f6 ();
+ return r != &ret;
+}
+bool check_c11 (c11 *ptr)
+{
+ c1 *r = ptr->f6 ();
+ return r != &ret;
+}
+bool check_c28 (c28 *ptr)
+{
+ c18 *r = ptr->f6 ();
+ return r != &ret;
+}
+
+int main ()
+{
+ c28 obj;
+
+ if (check_c1 (static_cast<c1a *> (&obj)))
+ return 1;
+ if (check_c1 (static_cast<c10 *> (&obj)))
+ return 2;
+ if (check_c10 (&obj))
+ return 3;
+ if (check_c11 (&obj))
+ return 4;
+ if (check_c28 (&obj))
+ return 5;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/abi/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C
new file mode 100644
index 00000000000..6c391e6891b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/macro0.C
@@ -0,0 +1,5 @@
+// { dg-options "-fabi-version=0" }
+
+#if __GXX_ABI_VERSION != 999999
+#error "Incorrect value of __GXX_ABI_VERSION"
+#endif
diff --git a/gcc/testsuite/g++.dg/abi/macro1.C b/gcc/testsuite/g++.dg/abi/macro1.C
new file mode 100644
index 00000000000..871208da3ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/macro1.C
@@ -0,0 +1,5 @@
+// { dg-options "-fabi-version=1" }
+
+#if __GXX_ABI_VERSION != 102
+#error "Incorrect value of __GXX_ABI_VERSION"
+#endif
diff --git a/gcc/testsuite/g++.dg/abi/macro2.C b/gcc/testsuite/g++.dg/abi/macro2.C
new file mode 100644
index 00000000000..9f0af9cff34
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/macro2.C
@@ -0,0 +1,5 @@
+// { dg-options "-fabi-version=2" }
+
+#if __GXX_ABI_VERSION != 1002
+#error "Incorrect value of __GXX_ABI_VERSION"
+#endif
diff --git a/gcc/testsuite/g++.dg/abi/mangle18-1.C b/gcc/testsuite/g++.dg/abi/mangle18-1.C
new file mode 100644
index 00000000000..a1be5e48c33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle18-1.C
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=2" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com>
+
+// PR 13241
+// mangled template arguments that are external objects incorrectly
+
+extern "C" void Foo ();
+namespace NMS
+{
+ extern "C" int V;
+}
+
+template <void (*)()> struct S {};
+template <int *> struct T {};
+
+void f (S<Foo>){}
+// { dg-final { scan-assembler "\n_?_Z1f1SIXadL_Z3FooEEE\[: \t\n\]" } }
+
+void g (T<&NMS::V>){}
+// { dg-final { scan-assembler "\n_?_Z1g1TIXadL_Z1VEEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle18-2.C b/gcc/testsuite/g++.dg/abi/mangle18-2.C
new file mode 100644
index 00000000000..a231d495fef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle18-2.C
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=1 -Wabi" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com>
+
+// PR 13241
+// mangled template arguments that are external objects incorrectly
+
+extern "C" void Foo ();
+namespace NMS
+{
+ extern "C" int V;
+}
+
+template <void (*)()> struct S {};
+template <int *> struct T {};
+
+void f (S<Foo>){} // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_?_Z1f1SIXadL3FooEEE\[: \t\n\]" } }
+
+void g (T<&NMS::V>){} // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_?_Z1g1TIXadL_ZN3NMS1VEEEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle19-1.C b/gcc/testsuite/g++.dg/abi/mangle19-1.C
new file mode 100644
index 00000000000..c7ab2cbb9b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle19-1.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=2" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com>
+
+// PR 13242
+// mangled template arguments that are external objects incorrectly
+
+extern int N;
+template <int &> struct S {};
+void n (S<N>) {}
+// { dg-final { scan-assembler "\n_?_Z1n1SILZ1NEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle19-2.C b/gcc/testsuite/g++.dg/abi/mangle19-2.C
new file mode 100644
index 00000000000..f0855e69d34
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle19-2.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=1 -Wabi" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com>
+
+// PR 13242
+// mangled template arguments that are external objects incorrectly
+
+extern int N;
+template <int &> struct S {};
+void n (S<N>) {} // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_?_Z1n1SIXadL_Z1NEEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle20-1.C b/gcc/testsuite/g++.dg/abi/mangle20-1.C
new file mode 100644
index 00000000000..1985fe3c941
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle20-1.C
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=2" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com>
+
+// PR 9043
+// mangled array types in templates
+
+template <int I> void f(int (*)[2]) {}
+template <int I> void g(int (*)[I+2]) {}
+
+static const int I=1;
+static const int J=2;
+
+template void f<1>(int (*)[2]);
+// { dg-final { scan-assembler "\n_?_Z1fILi1EEvPA2_i\[: \t\n\]" } }
+template void g<1>(int (*)[3]);
+// { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle20-2.C b/gcc/testsuite/g++.dg/abi/mangle20-2.C
new file mode 100644
index 00000000000..bf3d189bf0c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle20-2.C
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=1 -Wabi" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com>
+
+// PR 9043
+// mangled array types in templates
+
+template <int I> void f(int (*)[2]) {}
+template <int I> void g(int (*)[I+2]) {}
+
+template void f<1>(int (*)[2]); // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_?_Z1fILi1EEvPALi2E_i\[: \t\n\]" } }
+template void g<1>(int (*)[3]);
+// { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle21.C b/gcc/testsuite/g++.dg/abi/mangle21.C
new file mode 100644
index 00000000000..f457d600cd8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle21.C
@@ -0,0 +1,13 @@
+// PR c++/14324
+// { dg-do assemble }
+
+extern "C" {
+
+void fun1(void)
+{
+ do { static int xyz __attribute__((unused)) = 1; } while (0);
+ do { static int xyz __attribute__((unused)) = 2; } while (0);
+ do { static int xyz __attribute__((unused)) = 3; } while (0);
+}
+
+}
diff --git a/gcc/testsuite/g++.dg/abi/mangle22.C b/gcc/testsuite/g++.dg/abi/mangle22.C
new file mode 100644
index 00000000000..93ddd1e8740
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle22.C
@@ -0,0 +1,9 @@
+// PR c++/16240
+// { dg-options "-fabi-version=3" }
+
+void foo(char);
+template<void (&)(char)> struct CB {};
+
+void g(CB<foo> i) {}
+
+// { dg-final { scan-assembler "\n_?_Z1g2CBIL_Z3foocEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle23.C b/gcc/testsuite/g++.dg/abi/mangle23.C
new file mode 100644
index 00000000000..c17f54b4a72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle23.C
@@ -0,0 +1,9 @@
+// PR c++/16240
+// { dg-options "-fabi-version=2" }
+
+void foo(char);
+template<void (&)(char)> struct CB {};
+
+void g(CB<foo> i) {}
+
+// { dg-final { scan-assembler "\n_?_Z1g2CBILZ3foocEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/structret1.C b/gcc/testsuite/g++.dg/abi/structret1.C
new file mode 100644
index 00000000000..e9d4fd0ff9f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/structret1.C
@@ -0,0 +1,31 @@
+// { dg-do run { target ia64-*-* } }
+// { dg-options "-fabi-version=0" }
+
+extern "C" void abort ();
+
+struct ConstructedObject {
+ ConstructedObject() {};
+ ~ConstructedObject() {};
+ ConstructedObject(const ConstructedObject &from) {};
+};
+
+struct FrameworkObject {
+ ConstructedObject action();
+};
+
+ConstructedObject FrameworkObject::action() {
+ void *r32, *r33;
+
+ asm("mov %0 = r32\nmov %1 = r33" : "=r"(r32), "=r"(r33) : );
+ if (this != r33) {
+ abort ();
+ }
+}
+
+int main()
+{
+ FrameworkObject slawa;
+ slawa.action();
+ return 0;
+}
+
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/gcc.c-torture/compile/20031023-1.c b/gcc/testsuite/gcc.c-torture/compile/20031023-1.c
deleted file mode 100644
index 67f8ea9181a..00000000000
--- a/gcc/testsuite/gcc.c-torture/compile/20031023-1.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef ASIZE
-# define ASIZE 0x10000000000UL
-#endif
-
-#include <limits.h>
-
-#if LONG_MAX < 8 * ASIZE
-# undef ASIZE
-# define ASIZE 4096
-#endif
-
-extern void abort (void);
-
-int __attribute__((noinline))
-foo (const char *s)
-{
- if (!s)
- return 1;
- if (s[0] != 'a')
- abort ();
- s += ASIZE - 1;
- if (s[0] != 'b')
- abort ();
- return 0;
-}
-
-int (*fn) (const char *) = foo;
-
-int __attribute__((noinline))
-bar (void)
-{
- char s[ASIZE];
- s[0] = 'a';
- s[ASIZE - 1] = 'b';
- foo (s);
- foo (s);
- return 0;
-}
-
-int __attribute__((noinline))
-baz (long i)
-{
- if (i)
- return fn (0);
- else
- {
- char s[ASIZE];
- s[0] = 'a';
- s[ASIZE - 1] = 'b';
- foo (s);
- foo (s);
- return fn (0);
- }
-}
-
-int
-main (void)
-{
- if (bar ())
- abort ();
- if (baz (0) != 1)
- abort ();
- if (baz (1) != 1)
- abort ();
- return 0;
-}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-2.c b/gcc/testsuite/gcc.c-torture/compile/20031023-2.c
deleted file mode 100644
index 663e447157e..00000000000
--- a/gcc/testsuite/gcc.c-torture/compile/20031023-2.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define ASIZE 0x1000000000UL
-#include "20031023-1.c"
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-3.c b/gcc/testsuite/gcc.c-torture/compile/20031023-3.c
deleted file mode 100644
index f4a16c73c0d..00000000000
--- a/gcc/testsuite/gcc.c-torture/compile/20031023-3.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define ASIZE 0x100000000UL
-#include "20031023-1.c"
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-4.c b/gcc/testsuite/gcc.c-torture/compile/20031023-4.c
deleted file mode 100644
index 5c61f3743d4..00000000000
--- a/gcc/testsuite/gcc.c-torture/compile/20031023-4.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define ASIZE 0x80000000UL
-#include "20031023-1.c"
diff --git a/gcc/tree-alias-ander.c b/gcc/tree-alias-ander.c
new file mode 100644
index 00000000000..471a7fd99f3
--- /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..4af8b2c99d6
--- /dev/null
+++ b/gcc/tree-alias-ander.h
@@ -0,0 +1,29 @@
+/* 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
+*/
+
+#ifndef TREE_ALIAS_ANDER
+#define TREE_ALIAS_ANDER
+
+#include "tree-alias-common.h"
+
+extern struct tree_alias_ops *andersen_alias_ops;
+
+#endif /* TREE_ALIAS_ANDER */
diff --git a/gcc/tree-alias-common.c b/gcc/tree-alias-common.c
new file mode 100644
index 00000000000..790d70aa79f
--- /dev/null
+++ b/gcc/tree-alias-common.c
@@ -0,0 +1,1270 @@
+/* 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:
+ case ARRAY_RANGE_REF:
+ {
+ /* Find the first non-array ref, and return its alias variable. */
+ tree p;
+
+ for (p = expr;
+ TREE_CODE (p) == ARRAY_REF || TREE_CODE (p) == ARRAY_RANGE_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..ec93ce3dad2
--- /dev/null
+++ b/gcc/tree-alias-common.h
@@ -0,0 +1,123 @@
+/* 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
+*/
+
+#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. */
+ unsigned int ip:1;
+
+ /* Can do conservative interprocedural analysis if we save the
+ * info. */
+ unsigned 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 /* TREE_ALIAS_COMMON */
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..5c81af76463
--- /dev/null
+++ b/gcc/tree-alias-type.h
@@ -0,0 +1,68 @@
+/* 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
+*/
+
+#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 /* TREE_ALIAS_TYPE_H */
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..8600a99e412
--- /dev/null
+++ b/gcc/tree-cfg.c
@@ -0,0 +1,4899 @@
+/* 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);
+
+/* 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 group_case_labels (void);
+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);
+
+ /* To speed up statement iterator walks, we first purge dead labels. */
+ cleanup_dead_labels ();
+
+ /* Group case nodes to reduce the number of edges.
+ We do this after cleaning up dead labels because otherwise we miss
+ a lot of obvious case merging opportunities. */
+ group_case_labels ();
+
+ /* 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;
+
+ /* 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);
+ }
+
+ /* We do not care about fake edges, so remove any that the CFG
+ builder inserted for completeness. */
+ remove_fake_edges ();
+
+ /* 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)
+{
+ int uid = LABEL_DECL_UID (dest);
+
+ /* We would die hard when faced by undefined label. Emit label to
+ very first basic block. This will hopefully make even the dataflow
+ and undefined variable warnings quite right. */
+ if ((errorcount || sorrycount) && uid < 0)
+ {
+ block_stmt_iterator bsi = bsi_start (BASIC_BLOCK (0));
+ tree stmt;
+
+ stmt = build1 (LABEL_EXPR, void_type_node, dest);
+ bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ uid = LABEL_DECL_UID (dest);
+ }
+ return VARRAY_BB (label_to_block_map, uid);
+}
+
+
+/* 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))
+ {
+ edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
+#ifdef USE_MAPPED_LOCATION
+ e->goto_locus = EXPR_LOCATION (goto_t);
+#else
+ e->goto_locus = EXPR_LOCUS (goto_t);
+#endif
+ 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 in basic blocks. This is something we wish
+ to do early because it allows us to group case labels before creating
+ the edges for the CFG, and it speeds up block statement iterators in
+ all passes later on.
+ We only run this pass once, running it more than once is probably not
+ profitable. */
+
+/* A map from basic block index to the leading label of that block. */
+static tree *label_for_bb;
+
+/* Callback for for_each_eh_region. Helper for cleanup_dead_labels. */
+static void
+update_eh_label (struct eh_region *region)
+{
+ tree old_label = get_eh_region_tree_label (region);
+ if (old_label)
+ {
+ tree new_label = label_for_bb[label_to_block (old_label)->index];
+ set_eh_region_tree_label (region, new_label);
+ }
+}
+
+/* Given LABEL return the first label in the same basic block. */
+static tree
+main_block_label (tree label)
+{
+ basic_block bb = label_to_block (label);
+
+ /* label_to_block possibly inserted undefined label into the chain. */
+ if (!label_for_bb[bb->index])
+ label_for_bb[bb->index] = label;
+ return label_for_bb[bb->index];
+}
+
+/* Cleanup redundant labels. This is a three-steo process:
+ 1) Find the leading label for each block.
+ 2) Redirect all references to labels to the leading labels.
+ 3) Cleanup all useless labels. */
+
+static void
+cleanup_dead_labels (void)
+{
+ basic_block bb;
+ 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.
+ First do so for each block ending in a control statement. */
+ FOR_EACH_BB (bb)
+ {
+ tree stmt = last_stmt (bb);
+ if (!stmt)
+ continue;
+
+ switch (TREE_CODE (stmt))
+ {
+ case COND_EXPR:
+ {
+ tree true_branch, false_branch;
+
+ true_branch = COND_EXPR_THEN (stmt);
+ false_branch = COND_EXPR_ELSE (stmt);
+
+ GOTO_DESTINATION (true_branch)
+ = main_block_label (GOTO_DESTINATION (true_branch));
+ GOTO_DESTINATION (false_branch)
+ = main_block_label (GOTO_DESTINATION (false_branch));
+
+ 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)
+ CASE_LABEL (TREE_VEC_ELT (vec, i))
+ = main_block_label (CASE_LABEL (TREE_VEC_ELT (vec, i)));
+
+ break;
+ }
+
+ /* We have to handle GOTO_EXPRs until they're removed, and we don't
+ remove them until after we've created the CFG edges. */
+ case GOTO_EXPR:
+ if (! computed_goto_p (stmt))
+ {
+ GOTO_DESTINATION (stmt)
+ = main_block_label (GOTO_DESTINATION (stmt));
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ for_each_eh_region (update_eh_label);
+
+ /* 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);
+}
+
+/* Look for blocks ending in a multiway branch (a SWITCH_EXPR in GIMPLE),
+ and scan the sorted vector of cases. Combine the ones jumping to the
+ same label.
+ Eg. three separate entries 1: 2: 3: become one entry 1..3: */
+
+static void
+group_case_labels (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ tree stmt = last_stmt (bb);
+ if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
+ {
+ tree labels = SWITCH_LABELS (stmt);
+ int old_size = TREE_VEC_LENGTH (labels);
+ int i, j, new_size = old_size;
+ tree default_label = TREE_VEC_ELT (labels, old_size - 1);
+
+ /* Look for possible opportunities to merge cases.
+ Ignore the last element of the label vector because it
+ must be the default case. */
+ i = 0;
+ while (i < old_size - 2)
+ {
+ tree base_case, base_label, base_high, type;
+ base_case = TREE_VEC_ELT (labels, i);
+
+ if (! base_case)
+ abort ();
+
+ base_label = CASE_LABEL (base_case);
+
+ /* Discard cases that have the same destination as the
+ default case. */
+ if (base_label == default_label)
+ {
+ TREE_VEC_ELT (labels, i) = NULL_TREE;
+ i++;
+ continue;
+ }
+
+ type = TREE_TYPE (CASE_LOW (base_case));
+ base_high = CASE_HIGH (base_case) ?
+ CASE_HIGH (base_case) : CASE_LOW (base_case);
+
+ /* Try to merge case labels. Break out when we reach the end
+ of the label vector or when we cannot merge the next case
+ label with the current one. */
+ while (i < old_size - 2)
+ {
+ tree merge_case = TREE_VEC_ELT (labels, ++i);
+ tree merge_label = CASE_LABEL (merge_case);
+ tree t = int_const_binop (PLUS_EXPR, base_high,
+ integer_one_node, 1);
+
+ /* Merge the cases if they jump to the same place,
+ and their ranges are consecutive. */
+ if (merge_label == base_label
+ && tree_int_cst_equal (CASE_LOW (merge_case), t))
+ {
+ base_high = CASE_HIGH (merge_case) ?
+ CASE_HIGH (merge_case) : CASE_LOW (merge_case);
+ CASE_HIGH (base_case) = base_high;
+ TREE_VEC_ELT (labels, i) = NULL_TREE;
+ new_size--;
+ }
+ else
+ break;
+ }
+ }
+
+ /* Compress the case labels in the label vector, and adjust the
+ length of the vector. */
+ for (i = 0, j = 0; i < new_size; i++)
+ {
+ while (! TREE_VEC_ELT (labels, j))
+ j++;
+ TREE_VEC_ELT (labels, i) = TREE_VEC_ELT (labels, j++);
+ }
+ TREE_VEC_LENGTH (labels) = new_size;
+ }
+ }
+}
+
+/* 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_HAS_LOCATION (stmt))
+ {
+ location_t loc = EXPR_LOCATION (stmt);
+ warning ("%Hwill never be executed", &loc);
+ 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 = PHI_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;
+ source_locus loc = 0;
+
+ 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_HAS_LOCATION (stmt) && !loc)
+#ifdef USE_MAPPED_LOCATION
+ loc = EXPR_LOCATION (stmt);
+#else
+ loc = EXPR_LOCUS (stmt);
+#endif
+ }
+
+ /* 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)
+#ifdef USE_MAPPED_LOCATION
+ warning ("%Hwill never be executed", &loc);
+#else
+ warning ("%Hwill never be executed", loc);
+#endif
+
+ 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.
+ We can make optimal use here of the fact that the case labels are
+ sorted: We can do a binary search for a case matching VAL. */
+
+static tree
+find_case_label_for_value (tree switch_expr, tree val)
+{
+ tree vec = SWITCH_LABELS (switch_expr);
+ size_t low, high, n = TREE_VEC_LENGTH (vec);
+ tree default_case = TREE_VEC_ELT (vec, n - 1);
+
+ for (low = -1, high = n - 1; high - low > 1; )
+ {
+ size_t i = (high + low) / 2;
+ tree t = TREE_VEC_ELT (vec, i);
+ int cmp;
+
+ /* Cache the result of comparing CASE_LOW and val. */
+ cmp = tree_int_cst_compare (CASE_LOW (t), val);
+
+ if (cmp > 0)
+ high = i;
+ else
+ low = i;
+
+ if (CASE_HIGH (t) == NULL)
+ {
+ /* A singe-valued case label. */
+ if (cmp == 0)
+ return t;
+ }
+ else
+ {
+ /* A case range. We can only handle integer ranges. */
+ if (cmp <= 0 && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
+ return t;
+ }
+ }
+
+ 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 = PHI_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;
+
+ 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);
+
+ stmt = build1 (GOTO_EXPR, void_type_node, label);
+#ifdef USE_MAPPED_LOCATION
+ SET_EXPR_LOCATION (stmt, e->goto_locus);
+#else
+ SET_EXPR_LOCUS (stmt, e->goto_locus);
+#endif
+ bsi_insert_after (&last, stmt, BSI_NEW_STMT);
+ e->flags &= ~EDGE_FALLTHRU;
+ }
+}
+
+/* Remove block annotations and other datastructures. */
+
+void
+delete_tree_cfg_annotations (void)
+{
+ basic_block bb;
+ if (n_basic_blocks > 0)
+ free_blocks_annotations ();
+
+ label_to_block_map = NULL;
+ free_rbi_pool ();
+ FOR_EACH_BB (bb)
+ bb->rbi = NULL;
+}
+
+
+/* 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;
+
+ /* Insert code just before returning the value. We may need to decompose
+ the return in the case it contains non-trivial operand. */
+ if (TREE_CODE (tmp) == RETURN_EXPR)
+ {
+ tree op = TREE_OPERAND (tmp, 0);
+ if (!is_gimple_val (op))
+ {
+ if (TREE_CODE (op) != MODIFY_EXPR)
+ abort ();
+ bsi_insert_before (bsi, op, BSI_NEW_STMT);
+ TREE_OPERAND (tmp, 0) = TREE_OPERAND (op, 0);
+ }
+ bsi_prev (bsi);
+ 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 = PHI_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, void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp, x;
+
+ if (TYPE_P (t))
+ *walk_subtrees = 0;
+
+ /* Check operand N for being valid GIMPLE and give error MSG if not.
+ We check for constants explicitly since they are not considered
+ gimple invariants if they overflowed. */
+#define CHECK_OP(N, MSG) \
+ do { if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, N))) != 'c' \
+ && !is_gimple_val (TREE_OPERAND (t, N))) \
+ { error (MSG); return TREE_OPERAND (t, N); }} while (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 t;
+ }
+ break;
+
+ case ADDR_EXPR:
+ /* Skip any references (they will be checked when we recurse down the
+ tree) and ensure that any variable used as a prefix is marked
+ addressable. */
+ for (x = TREE_OPERAND (t, 0);
+ (handled_component_p (x)
+ || 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:
+ CHECK_OP (0, "Invalid operand to unary operator");
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case BIT_FIELD_REF:
+ case VIEW_CONVERT_EXPR:
+ /* We have a nest of references. Verify that each of the operands
+ that determine where to reference is either a constant or a variable,
+ verify that the base is valid, and then show we've already checked
+ the subtrees. */
+ while (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR
+ || handled_component_p (t))
+ {
+ if (TREE_CODE (t) == COMPONENT_REF && TREE_OPERAND (t, 2))
+ CHECK_OP (2, "Invalid COMPONENT_REF offset operator");
+ else if (TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == ARRAY_RANGE_REF)
+ {
+ CHECK_OP (1, "Invalid array index.");
+ if (TREE_OPERAND (t, 2))
+ CHECK_OP (2, "Invalid array lower bound.");
+ if (TREE_OPERAND (t, 3))
+ CHECK_OP (3, "Invalid array stride.");
+ }
+ else if (TREE_CODE (t) == BIT_FIELD_REF)
+ {
+ CHECK_OP (1, "Invalid operand to BIT_FIELD_REF");
+ CHECK_OP (2, "Invalid operand to BIT_FIELD_REF");
+ }
+
+ t = TREE_OPERAND (t, 0);
+ }
+
+ if (TREE_CODE_CLASS (TREE_CODE (t)) != 'c'
+ && !is_gimple_lvalue (t))
+ {
+ error ("Invalid reference prefix.");
+ return t;
+ }
+ *walk_subtrees = 0;
+ 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 LTGT_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:
+ CHECK_OP (0, "Invalid operand to binary operator");
+ CHECK_OP (1, "Invalid operand to binary operator");
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+
+#undef CHECK_OP
+}
+
+
+/* Verify STMT, return true if STMT is not in GIMPLE form.
+ TODO: Implement type checking. */
+
+static bool
+verify_stmt (tree stmt, bool last_in_block)
+{
+ tree addr;
+
+ if (!is_gimple_stmt (stmt))
+ {
+ error ("Is not a valid GIMPLE statement.");
+ goto fail;
+ }
+
+ addr = walk_tree (&stmt, verify_expr, NULL, NULL);
+ if (addr)
+ {
+ debug_generic_stmt (addr);
+ return true;
+ }
+
+ /* If the statement is marked as part of an EH region, then it is
+ expected that the statement could throw. Verify that when we
+ have optimizations that simplify statements such that we prove
+ that they cannot throw, that we update other data structures
+ to match. */
+ if (lookup_stmt_eh_region (stmt) >= 0)
+ {
+ if (!tree_could_throw_p (stmt))
+ {
+ error ("Statement marked for throw, but doesn't.");
+ goto fail;
+ }
+ if (!last_in_block && tree_can_throw_internal (stmt))
+ {
+ error ("Statement marked for throw in middle of block.");
+ goto fail;
+ }
+ }
+
+ return false;
+
+ fail:
+ debug_generic_stmt (stmt);
+ return true;
+}
+
+
+/* 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 || TREE_CODE (t) == ARRAY_RANGE_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 = PHI_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); )
+ {
+ tree stmt = bsi_stmt (bsi);
+ bsi_next (&bsi);
+ err |= verify_stmt (stmt, bsi_end_p (bsi));
+ 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:
+ {
+ tree prev;
+ 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;
+ }
+
+ /* Verify that the case labels are sorted. */
+ prev = TREE_VEC_ELT (vec, 0);
+ for (i = 1; i < n - 1; ++i)
+ {
+ tree c = TREE_VEC_ELT (vec, i);
+ if (! CASE_LOW (c))
+ {
+ error ("Found default case not at end of case vector");
+ err = 1;
+ continue;
+ }
+ if (! tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
+ {
+ error ("Case labels not sorted:\n ");
+ print_generic_expr (stderr, prev, 0);
+ fprintf (stderr," is greater than ");
+ print_generic_expr (stderr, c, 0);
+ fprintf (stderr," but comes before it.\n");
+ err = 1;
+ }
+ prev = c;
+ }
+ if (CASE_LOW (TREE_VEC_ELT (vec, n - 1)))
+ {
+ error ("No default case found at end of case vector");
+ err = 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, prev, next;
+
+ 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 = PHI_CHAIN (phi))
+ {
+ var = PHI_RESULT (phi);
+ new_phi = create_phi_node (var, bb);
+ SSA_NAME_DEF_STMT (var) = new_phi;
+ SET_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 chain is in the same order. */
+ prev = NULL;
+ for (phi = phi_nodes (bb); phi; phi = next)
+ {
+ next = PHI_CHAIN (phi);
+ PHI_CHAIN (phi) = prev;
+ prev = phi;
+ }
+ set_phi_nodes (bb, prev);
+
+ /* 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 = PHI_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 shrunk 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 = PHI_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. */
+
+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);
+ tree copy;
+
+ if (TREE_CODE (stmt) == LABEL_EXPR)
+ continue;
+
+ copy = unshare_expr (stmt);
+
+ /* Copy also the virtual operands. */
+ get_stmt_ann (copy);
+ copy_virtual_operands (copy, stmt);
+
+ bsi_insert_after (&bsi_tgt, copy, 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;
+}
+
+bool
+tree_purge_dead_eh_edges (basic_block bb)
+{
+ bool changed = false;
+ edge e, next;
+ tree stmt = last_stmt (bb);
+
+ if (stmt && tree_can_throw_internal (stmt))
+ return false;
+
+ for (e = bb->succ; e ; e = next)
+ {
+ next = e->succ_next;
+ if (e->flags & EDGE_EH)
+ {
+ ssa_remove_edge (e);
+ changed = true;
+ }
+ }
+
+ return changed;
+}
+
+bool
+tree_purge_all_dead_eh_edges (bitmap blocks)
+{
+ bool changed = false;
+ size_t i;
+
+ EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
+ { changed |= tree_purge_dead_eh_edges (BASIC_BLOCK (i)); });
+
+ return changed;
+}
+
+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 =
+{
+ "crited", /* 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 */
+ TODO_dump_func, /* todo_flags_finish */
+};
+
+/* Emit return warnings. */
+
+static void
+execute_warn_function_return (void)
+{
+#ifdef USE_MAPPED_LOCATION
+ source_location location;
+#else
+ location_t *locus;
+#endif
+ 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)
+ {
+#ifdef USE_MAPPED_LOCATION
+ location = UNKNOWN_LOCATION;
+#else
+ locus = NULL;
+#endif
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ {
+ last = last_stmt (e->src);
+ if (TREE_CODE (last) == RETURN_EXPR
+#ifdef USE_MAPPED_LOCATION
+ && (location = EXPR_LOCATION (last)) != UNKNOWN_LOCATION)
+#else
+ && (locus = EXPR_LOCUS (last)) != NULL)
+#endif
+ break;
+ }
+#ifdef USE_MAPPED_LOCATION
+ if (location == UNKNOWN_LOCATION)
+ location = cfun->function_end_locus;
+ warning ("%H`noreturn' function does return", &location);
+#else
+ if (!locus)
+ locus = &cfun->function_end_locus;
+ warning ("%H`noreturn' function does return", locus);
+#endif
+ }
+
+ /* 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)
+ {
+#ifdef USE_MAPPED_LOCATION
+ location = EXPR_LOCATION (last);
+ if (location == UNKNOWN_LOCATION)
+ location = cfun->function_end_locus;
+ warning ("%Hcontrol reaches end of non-void function", &location);
+#else
+ locus = EXPR_LOCUS (last);
+ if (!locus)
+ locus = &cfun->function_end_locus;
+ warning ("%Hcontrol reaches end of non-void function", locus);
+#endif
+ 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_cfg, /* 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-chrec.c b/gcc/tree-chrec.c
new file mode 100644
index 00000000000..9146ec36b36
--- /dev/null
+++ b/gcc/tree-chrec.c
@@ -0,0 +1,1019 @@
+/* Chains of recurrences.
+ Copyright (C) 2003, 2004 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. */
+
+/* This file implements operations on chains of recurrences. Chains
+ of recurrences are used for modeling evolution functions of scalar
+ variables.
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+#include "diagnostic.h"
+#include "varray.h"
+#include "tree-chrec.h"
+#include "tree-pass.h"
+
+
+/* This part will be removed once the merging is finished. */
+
+
+
+/* The following trees are unique elements. Thus the comparison of
+ another element to these elements should be done on the pointer to
+ these trees, and not on their value. */
+
+/* The SSA_NAMEs that are not yet analyzed are qualified with NULL_TREE. */
+tree chrec_not_analyzed_yet;
+
+/* Reserved to the cases where the analyzer has detected an
+ undecidable property at compile time. */
+tree chrec_dont_know;
+
+/* When the analyzer has detected that a property will never
+ happen, then it qualifies it with chrec_known. */
+tree chrec_known;
+
+/* Empty hook. Will be replaced by the main function from
+ tree-scalar-evolution.c. */
+
+tree
+count_ev_in_wider_type (tree foo ATTRIBUTE_UNUSED,
+ tree bar ATTRIBUTE_UNUSED)
+{
+ return NULL_TREE;
+}
+
+/* Empty hook. Will be replaced by the main function from
+ tree-scalar-evolution.c. */
+
+bool
+chrec_contains_symbols_defined_in_loop (tree chrec ATTRIBUTE_UNUSED,
+ unsigned loop_nb ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+
+
+
+/* Extended folder for chrecs. */
+
+/* Determines whether CST is not a constant evolution. */
+
+static inline bool
+is_not_constant_evolution (tree cst)
+{
+ return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
+}
+
+/* Fold CODE for a polynomial function and a constant. */
+
+static inline tree
+chrec_fold_poly_cst (enum tree_code code,
+ tree type,
+ tree poly,
+ tree cst)
+{
+#if defined ENABLE_CHECKING
+ if (poly == NULL_TREE
+ || cst == NULL_TREE
+ || TREE_CODE (poly) != POLYNOMIAL_CHREC
+ || is_not_constant_evolution (cst))
+ abort ();
+#endif
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly),
+ chrec_fold_plus (type, CHREC_LEFT (poly), cst),
+ CHREC_RIGHT (poly));
+
+ case MINUS_EXPR:
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly),
+ chrec_fold_minus (type, CHREC_LEFT (poly), cst),
+ CHREC_RIGHT (poly));
+
+ case MULT_EXPR:
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly),
+ chrec_fold_multiply (type, CHREC_LEFT (poly), cst),
+ chrec_fold_multiply (type, CHREC_RIGHT (poly), cst));
+
+ default:
+ return chrec_dont_know;
+ }
+}
+
+/* Fold the addition of two polynomial functions. */
+
+static inline tree
+chrec_fold_plus_poly_poly (enum tree_code code,
+ tree type,
+ tree poly0,
+ tree poly1)
+{
+ tree left, right;
+
+#if defined ENABLE_CHECKING
+ if (poly0 == NULL_TREE
+ || poly1 == NULL_TREE
+ || TREE_CODE (poly0) != POLYNOMIAL_CHREC
+ || TREE_CODE (poly1) != POLYNOMIAL_CHREC)
+ abort ();
+#endif
+
+ /*
+ {a, +, b}_1 + {c, +, d}_2 -> {{a, +, b}_1 + c, +, d}_2,
+ {a, +, b}_2 + {c, +, d}_1 -> {{c, +, d}_1 + a, +, b}_2,
+ {a, +, b}_x + {c, +, d}_x -> {a+c, +, b+d}_x. */
+ if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
+ {
+ if (code == PLUS_EXPR)
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly1),
+ chrec_fold_plus (type, poly0, CHREC_LEFT (poly1)),
+ CHREC_RIGHT (poly1));
+ else
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly1),
+ chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
+ chrec_fold_multiply (type, CHREC_RIGHT (poly1),
+ convert (type, integer_minus_one_node)));
+ }
+
+ if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
+ {
+ if (code == PLUS_EXPR)
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly0),
+ chrec_fold_plus (type, CHREC_LEFT (poly0), poly1),
+ CHREC_RIGHT (poly0));
+ else
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly0),
+ chrec_fold_minus (type, CHREC_LEFT (poly0), poly1),
+ CHREC_RIGHT (poly0));
+ }
+
+ if (code == PLUS_EXPR)
+ {
+ left = chrec_fold_plus
+ (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
+ right = chrec_fold_plus
+ (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
+ }
+ else
+ {
+ left = chrec_fold_minus
+ (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
+ right = chrec_fold_minus
+ (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
+ }
+
+ if (chrec_zerop (right))
+ return left;
+ else
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly0), left, right);
+}
+
+
+
+/* Fold the multiplication of two polynomial functions. */
+
+static inline tree
+chrec_fold_multiply_poly_poly (tree type,
+ tree poly0,
+ tree poly1)
+{
+#if defined ENABLE_CHECKING
+ if (poly0 == NULL_TREE
+ || poly1 == NULL_TREE
+ || TREE_CODE (poly0) != POLYNOMIAL_CHREC
+ || TREE_CODE (poly1) != POLYNOMIAL_CHREC)
+ abort ();
+#endif
+
+ /* {a, +, b}_1 * {c, +, d}_2 -> {c*{a, +, b}_1, +, d}_2,
+ {a, +, b}_2 * {c, +, d}_1 -> {a*{c, +, d}_1, +, b}_2,
+ {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
+ if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
+ /* poly0 is a constant wrt. poly1. */
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly1),
+ chrec_fold_multiply (type, CHREC_LEFT (poly1), poly0),
+ CHREC_RIGHT (poly1));
+
+ if (CHREC_VARIABLE (poly1) < CHREC_VARIABLE (poly0))
+ /* poly1 is a constant wrt. poly0. */
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (poly0),
+ chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
+ CHREC_RIGHT (poly0));
+
+ /* poly0 and poly1 are two polynomials in the same variable,
+ {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
+ return
+ build_polynomial_chrec
+ (CHREC_VARIABLE (poly0),
+ build_polynomial_chrec
+ (CHREC_VARIABLE (poly0),
+
+ /* "a*c". */
+ chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1)),
+
+ /* "a*d + b*c + b*d". */
+ chrec_fold_plus
+ (type, chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_RIGHT (poly1)),
+
+ chrec_fold_plus
+ (type,
+ chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_LEFT (poly1)),
+ chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1))))),
+
+ /* "2*b*d". */
+ chrec_fold_multiply
+ (type, build_int_2 (2, 0),
+ chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1))));
+}
+
+/* When the operands are automatically_generated_chrec_p, the fold has
+ to respect the semantics of the operands. */
+
+static inline tree
+chrec_fold_automatically_generated_operands (tree op0,
+ tree op1)
+{
+ if (op0 == chrec_dont_know
+ || op1 == chrec_dont_know)
+ return chrec_dont_know;
+
+ if (op0 == chrec_known
+ || op1 == chrec_known)
+ return chrec_known;
+
+ if (op0 == chrec_not_analyzed_yet
+ || op1 == chrec_not_analyzed_yet)
+ return chrec_not_analyzed_yet;
+
+ /* The default case produces a safe result. */
+ return chrec_dont_know;
+}
+
+/* Fold the addition of two chrecs. */
+
+static tree
+chrec_fold_plus_1 (enum tree_code code,
+ tree type,
+ tree op0,
+ tree op1)
+{
+ if (automatically_generated_chrec_p (op0)
+ || automatically_generated_chrec_p (op1))
+ return chrec_fold_automatically_generated_operands (op0, op1);
+
+ switch (TREE_CODE (op0))
+ {
+ case POLYNOMIAL_CHREC:
+ switch (TREE_CODE (op1))
+ {
+ case POLYNOMIAL_CHREC:
+ return chrec_fold_plus_poly_poly (code, type, op0, op1);
+
+ default:
+ if (code == PLUS_EXPR)
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (op0),
+ chrec_fold_plus (type, CHREC_LEFT (op0), op1),
+ CHREC_RIGHT (op0));
+ else
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (op0),
+ chrec_fold_minus (type, CHREC_LEFT (op0), op1),
+ CHREC_RIGHT (op0));
+ }
+
+ default:
+ switch (TREE_CODE (op1))
+ {
+ case POLYNOMIAL_CHREC:
+ if (code == PLUS_EXPR)
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (op1),
+ chrec_fold_plus (type, op0, CHREC_LEFT (op1)),
+ CHREC_RIGHT (op1));
+ else
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (op1),
+ chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
+ chrec_fold_multiply (type, CHREC_RIGHT (op1),
+ convert (type,
+ integer_minus_one_node)));
+
+ default:
+ if (tree_contains_chrecs (op0)
+ || tree_contains_chrecs (op1))
+ return build (code, type, op0, op1);
+ else
+ return fold (build (code, type, op0, op1));
+ }
+ }
+}
+
+/* Fold the addition of two chrecs. */
+
+tree
+chrec_fold_plus (tree type,
+ tree op0,
+ tree op1)
+{
+ if (integer_zerop (op0))
+ return op1;
+ if (integer_zerop (op1))
+ return op0;
+
+ return chrec_fold_plus_1 (PLUS_EXPR, type, op0, op1);
+}
+
+/* Fold the subtraction of two chrecs. */
+
+tree
+chrec_fold_minus (tree type,
+ tree op0,
+ tree op1)
+{
+ if (integer_zerop (op1))
+ return op0;
+
+ return chrec_fold_plus_1 (MINUS_EXPR, type, op0, op1);
+}
+
+/* Fold the multiplication of two chrecs. */
+
+tree
+chrec_fold_multiply (tree type,
+ tree op0,
+ tree op1)
+{
+ if (automatically_generated_chrec_p (op0)
+ || automatically_generated_chrec_p (op1))
+ return chrec_fold_automatically_generated_operands (op0, op1);
+
+ switch (TREE_CODE (op0))
+ {
+ case POLYNOMIAL_CHREC:
+ switch (TREE_CODE (op1))
+ {
+ case POLYNOMIAL_CHREC:
+ return chrec_fold_multiply_poly_poly (type, op0, op1);
+
+ default:
+ if (integer_onep (op1))
+ return op0;
+ if (integer_zerop (op1))
+ return convert (type, integer_zero_node);
+
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (op0),
+ chrec_fold_multiply (type, CHREC_LEFT (op0), op1),
+ chrec_fold_multiply (type, CHREC_RIGHT (op0), op1));
+ }
+
+ default:
+ if (integer_onep (op0))
+ return op1;
+
+ if (integer_zerop (op0))
+ return convert (type, integer_zero_node);
+
+ switch (TREE_CODE (op1))
+ {
+ case POLYNOMIAL_CHREC:
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (op1),
+ chrec_fold_multiply (type, CHREC_LEFT (op1), op0),
+ chrec_fold_multiply (type, CHREC_RIGHT (op1), op0));
+
+ default:
+ if (integer_onep (op1))
+ return op0;
+ if (integer_zerop (op1))
+ return convert (type, integer_zero_node);
+ return fold (build (MULT_EXPR, type, op0, op1));
+ }
+ }
+}
+
+
+
+/* Operations. */
+
+/* The factorial. */
+
+static tree
+tree_fold_factorial (tree f)
+{
+ if (tree_int_cst_sgn (f) <= 0)
+ return integer_one_node;
+ else
+ return fold
+ (build (MULT_EXPR, integer_type_node, f,
+ tree_fold_factorial (fold (build (MINUS_EXPR, integer_type_node,
+ f, integer_one_node)))));
+}
+
+/* The binomial coefficient. */
+
+static tree
+tree_fold_binomial (tree n,
+ tree k)
+{
+ return fold
+ (build (EXACT_DIV_EXPR, integer_type_node, tree_fold_factorial (n),
+ fold (build (MULT_EXPR, integer_type_node,
+ tree_fold_factorial (k),
+ tree_fold_factorial
+ (fold (build (MINUS_EXPR, integer_type_node,
+ n, k)))))));
+}
+
+/* Helper function. Use the Newton's interpolating formula for
+ evaluating the value of the evolution function. */
+
+static tree
+chrec_evaluate (unsigned var,
+ tree chrec,
+ tree n,
+ tree k)
+{
+ tree type = chrec_type (chrec);
+ tree binomial_n_k = tree_fold_binomial (n, k);
+
+ if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
+ {
+ if (CHREC_VARIABLE (chrec) > var)
+ return chrec_evaluate (var, CHREC_LEFT (chrec), n, k);
+
+ if (CHREC_VARIABLE (chrec) == var)
+ return chrec_fold_plus
+ (type,
+ fold (build (MULT_EXPR, type, binomial_n_k, CHREC_LEFT (chrec))),
+ chrec_evaluate (var, CHREC_RIGHT (chrec), n,
+ fold (build (PLUS_EXPR, type, k, integer_one_node))));
+
+ return fold (build (MULT_EXPR, type, binomial_n_k, chrec));
+ }
+ else
+ return fold (build (MULT_EXPR, type, binomial_n_k, chrec));
+}
+
+/* Evaluates "CHREC (X)" when the varying variable is VAR.
+ Example: Given the following parameters,
+
+ var = 1
+ chrec = {3, +, 4}_1
+ x = 10
+
+ The result is given by the Newton's interpolating formula:
+ 3 * \binom{10}{0} + 4 * \binom{10}{1}.
+*/
+
+tree
+chrec_apply (unsigned var,
+ tree chrec,
+ tree x)
+{
+ tree type = chrec_type (chrec);
+ tree res = chrec_dont_know;
+
+ if (automatically_generated_chrec_p (chrec)
+ || automatically_generated_chrec_p (x)
+
+ /* When the symbols are defined in an outer loop, it is possible
+ to symbolically compute the apply, since the symbols are
+ constants with respect to the varying loop. */
+ || chrec_contains_symbols_defined_in_loop (chrec, var)
+ || chrec_contains_symbols (x))
+ return chrec_dont_know;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "(chrec_apply \n");
+
+ if (evolution_function_is_affine_p (chrec))
+ {
+ /* "{a, +, b} (x)" -> "a + b*x". */
+ if (TREE_CODE (CHREC_LEFT (chrec)) == INTEGER_CST
+ && integer_zerop (CHREC_LEFT (chrec)))
+ res = chrec_fold_multiply (type, CHREC_RIGHT (chrec), x);
+
+ else
+ res = chrec_fold_plus (type, CHREC_LEFT (chrec),
+ chrec_fold_multiply (type,
+ CHREC_RIGHT (chrec), x));
+ }
+
+ else if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
+ res = chrec;
+
+ else if (TREE_CODE (x) == INTEGER_CST
+ && tree_int_cst_sgn (x) == 1)
+ /* testsuite/.../ssa-chrec-38.c. */
+ res = chrec_evaluate (var, chrec, x, integer_zero_node);
+
+ else
+ res = chrec_dont_know;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " (varying_loop = %d\n", var);
+ fprintf (dump_file, ")\n (chrec = ");
+ print_generic_expr (dump_file, chrec, 0);
+ fprintf (dump_file, ")\n (x = ");
+ print_generic_expr (dump_file, x, 0);
+ fprintf (dump_file, ")\n (res = ");
+ print_generic_expr (dump_file, res, 0);
+ fprintf (dump_file, "))\n");
+ }
+
+ return res;
+}
+
+/* Replaces the initial condition in CHREC with INIT_COND. */
+
+tree
+chrec_replace_initial_condition (tree chrec,
+ tree init_cond)
+{
+ if (automatically_generated_chrec_p (chrec))
+ return chrec;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ return build_polynomial_chrec
+ (CHREC_VARIABLE (chrec),
+ chrec_replace_initial_condition (CHREC_LEFT (chrec), init_cond),
+ CHREC_RIGHT (chrec));
+
+ default:
+ return init_cond;
+ }
+}
+
+/* Returns the initial condition of a given CHREC. */
+
+tree
+initial_condition (tree chrec)
+{
+ if (automatically_generated_chrec_p (chrec))
+ return chrec;
+
+ if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
+ return initial_condition (CHREC_LEFT (chrec));
+ else
+ return chrec;
+}
+
+/* Returns a univariate function that represents the evolution in
+ LOOP_NUM. Mask the evolution of any other loop. */
+
+tree
+hide_evolution_in_other_loops_than_loop (tree chrec,
+ unsigned loop_num)
+{
+ if (automatically_generated_chrec_p (chrec))
+ return chrec;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ if (CHREC_VARIABLE (chrec) == loop_num)
+ return build_polynomial_chrec
+ (loop_num,
+ hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
+ loop_num),
+ CHREC_RIGHT (chrec));
+
+ else if (CHREC_VARIABLE (chrec) < loop_num)
+ /* There is no evolution in this loop. */
+ return initial_condition (chrec);
+
+ else
+ return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
+ loop_num);
+
+ default:
+ return chrec;
+ }
+}
+
+/* Returns the evolution part in LOOP_NUM. Example: the call
+ get_evolution_in_loop (1, {{0, +, 1}_1, +, 2}_1) returns
+ {1, +, 2}_1 */
+
+tree
+evolution_part_in_loop_num (tree chrec,
+ unsigned loop_num)
+{
+ if (automatically_generated_chrec_p (chrec))
+ return chrec;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ if (CHREC_VARIABLE (chrec) == loop_num)
+ {
+ if (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC
+ || CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec))
+ return CHREC_RIGHT (chrec);
+
+ else
+ return build_polynomial_chrec
+ (loop_num,
+ evolution_part_in_loop_num (CHREC_LEFT (chrec), loop_num),
+ CHREC_RIGHT (chrec));
+ }
+
+ else if (CHREC_VARIABLE (chrec) < loop_num)
+ /* There is no evolution part in this loop. */
+ return NULL_TREE;
+
+ else
+ return evolution_part_in_loop_num (CHREC_LEFT (chrec), loop_num);
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
+ This function is essentially used for setting the evolution to
+ chrec_dont_know, for example after having determined that it is
+ impossible to say how many times a loop will execute. */
+
+tree
+reset_evolution_in_loop (unsigned loop_num,
+ tree chrec,
+ tree new_evol)
+{
+ if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
+ && CHREC_VARIABLE (chrec) > loop_num)
+ return build
+ (TREE_CODE (chrec),
+ build_int_2 (CHREC_VARIABLE (chrec), 0),
+ reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec), new_evol),
+ reset_evolution_in_loop (loop_num, CHREC_RIGHT (chrec), new_evol));
+
+ while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
+ && CHREC_VARIABLE (chrec) == loop_num)
+ chrec = CHREC_LEFT (chrec);
+
+ return build_polynomial_chrec (loop_num, chrec, new_evol);
+}
+
+/* Merges two evolution functions that were found by following two
+ alternate paths of a conditional expression. */
+
+tree
+chrec_merge (tree chrec1,
+ tree chrec2)
+{
+ if (chrec1 == chrec_dont_know
+ || chrec2 == chrec_dont_know)
+ return chrec_dont_know;
+
+ if (chrec1 == chrec_known
+ || chrec2 == chrec_known)
+ return chrec_known;
+
+ if (chrec1 == chrec_not_analyzed_yet)
+ return chrec2;
+ if (chrec2 == chrec_not_analyzed_yet)
+ return chrec1;
+
+ if (operand_equal_p (chrec1, chrec2, 0))
+ return chrec1;
+
+ return chrec_dont_know;
+}
+
+
+
+/* Observers. */
+
+/* Helper function for is_multivariate_chrec. */
+
+static bool
+is_multivariate_chrec_rec (tree chrec, unsigned int rec_var)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
+ {
+ if (CHREC_VARIABLE (chrec) != rec_var)
+ return true;
+ else
+ return (is_multivariate_chrec_rec (CHREC_LEFT (chrec), rec_var)
+ || is_multivariate_chrec_rec (CHREC_RIGHT (chrec), rec_var));
+ }
+ else
+ return false;
+}
+
+/* Determine whether the given chrec is multivariate or not. */
+
+bool
+is_multivariate_chrec (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
+ return (is_multivariate_chrec_rec (CHREC_LEFT (chrec),
+ CHREC_VARIABLE (chrec))
+ || is_multivariate_chrec_rec (CHREC_RIGHT (chrec),
+ CHREC_VARIABLE (chrec)));
+ else
+ return false;
+}
+
+/* Determines whether the chrec contains symbolic names or not. */
+
+bool
+chrec_contains_symbols (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (chrec) == SSA_NAME
+ || TREE_CODE (chrec) == VAR_DECL
+ || TREE_CODE (chrec) == PARM_DECL
+ || TREE_CODE (chrec) == FUNCTION_DECL
+ || TREE_CODE (chrec) == LABEL_DECL
+ || TREE_CODE (chrec) == RESULT_DECL
+ || TREE_CODE (chrec) == FIELD_DECL)
+ return true;
+
+ switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
+ {
+ case 3:
+ if (chrec_contains_symbols (TREE_OPERAND (chrec, 2)))
+ return true;
+
+ case 2:
+ if (chrec_contains_symbols (TREE_OPERAND (chrec, 1)))
+ return true;
+
+ case 1:
+ if (chrec_contains_symbols (TREE_OPERAND (chrec, 0)))
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Determines whether the chrec contains undetermined coefficients. */
+
+bool
+chrec_contains_undetermined (tree chrec)
+{
+ if (chrec == chrec_dont_know
+ || chrec == chrec_not_analyzed_yet
+ || chrec == NULL_TREE)
+ return true;
+
+ switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
+ {
+ case 3:
+ if (chrec_contains_undetermined (TREE_OPERAND (chrec, 2)))
+ return true;
+
+ case 2:
+ if (chrec_contains_undetermined (TREE_OPERAND (chrec, 1)))
+ return true;
+
+ case 1:
+ if (chrec_contains_undetermined (TREE_OPERAND (chrec, 0)))
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Determines whether the tree EXPR contains chrecs. */
+
+bool
+tree_contains_chrecs (tree expr)
+{
+ if (expr == NULL_TREE)
+ return false;
+
+ if (tree_is_chrec (expr))
+ return true;
+
+ switch (TREE_CODE_LENGTH (TREE_CODE (expr)))
+ {
+ case 3:
+ if (tree_contains_chrecs (TREE_OPERAND (expr, 2)))
+ return true;
+
+ case 2:
+ if (tree_contains_chrecs (TREE_OPERAND (expr, 1)))
+ return true;
+
+ case 1:
+ if (tree_contains_chrecs (TREE_OPERAND (expr, 0)))
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Determine whether the given tree is an affine multivariate
+ evolution. */
+
+bool
+evolution_function_is_affine_multivariate_p (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ if (evolution_function_is_constant_p (CHREC_LEFT (chrec)))
+ {
+ if (evolution_function_is_constant_p (CHREC_RIGHT (chrec)))
+ return true;
+ else
+ {
+ if (TREE_CODE (CHREC_RIGHT (chrec)) == POLYNOMIAL_CHREC
+ && CHREC_VARIABLE (CHREC_RIGHT (chrec))
+ != CHREC_VARIABLE (chrec)
+ && evolution_function_is_affine_multivariate_p
+ (CHREC_RIGHT (chrec)))
+ return true;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ if (evolution_function_is_constant_p (CHREC_RIGHT (chrec))
+ && TREE_CODE (CHREC_LEFT (chrec)) == POLYNOMIAL_CHREC
+ && CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec)
+ && evolution_function_is_affine_multivariate_p
+ (CHREC_LEFT (chrec)))
+ return true;
+ else
+ return false;
+ }
+
+ default:
+ return false;
+ }
+}
+
+/* Determine whether the given tree is a function in zero or one
+ variables. */
+
+bool
+evolution_function_is_univariate_p (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return true;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ switch (TREE_CODE (CHREC_LEFT (chrec)))
+ {
+ case POLYNOMIAL_CHREC:
+ if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_LEFT (chrec)))
+ return false;
+ if (!evolution_function_is_univariate_p (CHREC_LEFT (chrec)))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (TREE_CODE (CHREC_RIGHT (chrec)))
+ {
+ case POLYNOMIAL_CHREC:
+ if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_RIGHT (chrec)))
+ return false;
+ if (!evolution_function_is_univariate_p (CHREC_RIGHT (chrec)))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+
+ default:
+ return true;
+ }
+}
+
+
+
+/* Convert the initial condition of chrec to type. */
+
+tree
+chrec_convert (tree type,
+ tree chrec)
+{
+ tree ct;
+
+ if (automatically_generated_chrec_p (chrec))
+ return chrec;
+
+ ct = chrec_type (chrec);
+ if (ct == type)
+ return chrec;
+
+ if (TYPE_PRECISION (ct) < TYPE_PRECISION (type))
+ return count_ev_in_wider_type (type, chrec);
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ return build_polynomial_chrec (CHREC_VARIABLE (chrec),
+ chrec_convert (type,
+ CHREC_LEFT (chrec)),
+ chrec_convert (type,
+ CHREC_RIGHT (chrec)));
+
+ default:
+ {
+ tree res = convert (type, chrec);
+
+ /* Don't propagate overflows. */
+ TREE_OVERFLOW (res) = 0;
+ if (TREE_CODE_CLASS (TREE_CODE (res)) == 'c')
+ TREE_CONSTANT_OVERFLOW (res) = 0;
+ return res;
+ }
+ }
+}
+
+/* Returns the type of the chrec. */
+
+tree
+chrec_type (tree chrec)
+{
+ if (automatically_generated_chrec_p (chrec))
+ return NULL_TREE;
+
+ return TREE_TYPE (chrec);
+}
+
+extern void initialize_scalar_evolutions_analyzer (void);
+
+/* Initializer. */
+
+void
+initialize_scalar_evolutions_analyzer (void)
+{
+ /* The elements below are unique. */
+ if (chrec_dont_know == NULL_TREE)
+ {
+ chrec_not_analyzed_yet = NULL_TREE;
+ chrec_dont_know = make_node (SCEV_NOT_KNOWN);
+ chrec_known = make_node (SCEV_KNOWN);
+ TREE_TYPE (chrec_dont_know) = NULL_TREE;
+ TREE_TYPE (chrec_known) = NULL_TREE;
+ }
+}
diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h
new file mode 100644
index 00000000000..8e355f0ac35
--- /dev/null
+++ b/gcc/tree-chrec.h
@@ -0,0 +1,206 @@
+/* Chains of recurrences.
+ Copyright (C) 2003, 2004 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. */
+
+#ifndef GCC_TREE_CHREC_H
+#define GCC_TREE_CHREC_H
+
+/* Accessors for the chains of recurrences. */
+#define CHREC_VAR(NODE) TREE_OPERAND (NODE, 0)
+#define CHREC_LEFT(NODE) TREE_OPERAND (NODE, 1)
+#define CHREC_RIGHT(NODE) TREE_OPERAND (NODE, 2)
+#define CHREC_VARIABLE(NODE) TREE_INT_CST_LOW (CHREC_VAR (NODE))
+
+
+
+/* The following trees are unique elements. Thus the comparison of another
+ element to these elements should be done on the pointer to these trees,
+ and not on their value. */
+
+extern tree chrec_not_analyzed_yet;
+extern GTY(()) tree chrec_dont_know;
+extern GTY(()) tree chrec_known;
+
+/* After having added an automatically generated element, please
+ include it in the following function. */
+
+static inline bool
+automatically_generated_chrec_p (tree chrec)
+{
+ return (chrec == chrec_not_analyzed_yet
+ || chrec == chrec_dont_know
+ || chrec == chrec_known);
+}
+
+/* The tree nodes aka. CHRECs. */
+
+static inline bool
+tree_is_chrec (tree expr)
+{
+ if (TREE_CODE (expr) == POLYNOMIAL_CHREC
+ || automatically_generated_chrec_p (expr))
+ return true;
+ else
+ return false;
+}
+
+
+
+/* Chrec folding functions. */
+extern tree chrec_fold_plus (tree, tree, tree);
+extern tree chrec_fold_minus (tree, tree, tree);
+extern tree chrec_fold_multiply (tree, tree, tree);
+extern tree chrec_convert (tree, tree);
+extern tree count_ev_in_wider_type (tree, tree);
+extern tree chrec_type (tree);
+
+/* Operations. */
+extern tree chrec_apply (unsigned, tree, tree);
+extern tree chrec_replace_initial_condition (tree, tree);
+extern tree update_initial_condition_to_origin (tree);
+extern tree initial_condition (tree);
+extern tree evolution_part_in_loop_num (tree, unsigned);
+extern tree hide_evolution_in_other_loops_than_loop (tree, unsigned);
+extern tree reset_evolution_in_loop (unsigned, tree, tree);
+extern tree chrec_merge (tree, tree);
+
+/* Observers. */
+extern bool is_multivariate_chrec (tree);
+extern bool chrec_is_positive (tree, bool *);
+extern bool chrec_contains_symbols (tree);
+extern bool chrec_contains_symbols_defined_in_loop (tree, unsigned);
+extern bool chrec_contains_undetermined (tree);
+extern bool tree_contains_chrecs (tree);
+extern bool evolution_function_is_affine_multivariate_p (tree);
+extern bool evolution_function_is_univariate_p (tree);
+
+
+
+/* Build a polynomial chain of recurrence. */
+
+static inline tree
+build_polynomial_chrec (unsigned loop_num,
+ tree left,
+ tree right)
+{
+ if (left == chrec_dont_know
+ || right == chrec_dont_know)
+ return chrec_dont_know;
+
+ return build (POLYNOMIAL_CHREC, TREE_TYPE (left),
+ build_int_2 (loop_num, 0), left, right);
+}
+
+
+
+/* Observers. */
+
+/* Determines whether CHREC is equal to zero. */
+
+static inline bool
+chrec_zerop (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (chrec) == INTEGER_CST)
+ return integer_zerop (chrec);
+
+ return false;
+}
+
+/* Determines whether the expression CHREC is a constant. */
+
+static inline bool
+evolution_function_is_constant_p (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ switch (TREE_CODE (chrec))
+ {
+ case INTEGER_CST:
+ case REAL_CST:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Determine whether the given tree is an affine evolution function or not. */
+
+static inline bool
+evolution_function_is_affine_p (tree chrec)
+{
+ if (chrec == NULL_TREE)
+ return false;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ if (evolution_function_is_constant_p (CHREC_LEFT (chrec))
+ && evolution_function_is_constant_p (CHREC_RIGHT (chrec)))
+ return true;
+ else
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+/* Determine whether the given tree is an affine or constant evolution
+ function. */
+
+static inline bool
+evolution_function_is_affine_or_constant_p (tree chrec)
+{
+ return evolution_function_is_affine_p (chrec)
+ || evolution_function_is_constant_p (chrec);
+}
+
+/* Determines whether EXPR does not contains chrec expressions. */
+
+static inline bool
+tree_does_not_contain_chrecs (tree expr)
+{
+ return !tree_contains_chrecs (expr);
+}
+
+/* Determines whether CHREC is a loop invariant with respect to LOOP_NUM.
+ Set the result in RES and return true when the property can be computed. */
+
+static inline bool
+no_evolution_in_loop_p (tree chrec, unsigned loop_num, bool *res)
+{
+ tree scev;
+
+ if (chrec == chrec_not_analyzed_yet
+ || chrec == chrec_dont_know
+ || chrec_contains_symbols_defined_in_loop (chrec, loop_num))
+ return false;
+
+ scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num);
+ *res = !tree_is_chrec (scev);
+ return true;
+}
+
+#endif /* GCC_TREE_CHREC_H */
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
new file mode 100644
index 00000000000..0e6dab7e471
--- /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) = fold_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..99f998f9c1d
--- /dev/null
+++ b/gcc/tree-dfa.c
@@ -0,0 +1,1200 @@
+/* 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_v_may_defs;
+ long num_vuses;
+ long num_v_must_defs;
+};
+
+
+/* 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;
+
+ /* 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 = PHI_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 = PHI_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;
+ v_may_def_optype v_may_defs;
+ 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);
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree vuse = V_MAY_DEF_OP (v_may_defs, 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);
+ v_may_def_optype v_may_defs = V_MAY_DEF_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_V_MAY_DEFS (v_may_defs); i++)
+ redirect_immediate_use (V_MAY_DEF_OP (v_may_defs, 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_t) 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))
+ || (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_t) ann;
+
+ return ann;
+}
+
+
+/* Create a new annotation for a tree T. */
+
+tree_ann_t
+create_tree_ann (tree t)
+{
+ tree_ann_t ann;
+
+#if defined ENABLE_CHECKING
+ if (t == NULL_TREE
+ || (t->common.ann
+ && t->common.ann->common.type != TREE_ANN_COMMON))
+ abort ();
+#endif
+
+ ann = ggc_alloc (sizeof (*ann));
+ memset ((void *) ann, 0, sizeof (*ann));
+
+ ann->common.type = TREE_ANN_COMMON;
+ t->common.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 = PHI_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_v_may_defs * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_v_must_defs * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs,
+ 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 = PHI_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_v_may_defs +=
+ NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann));
+ dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann));
+ dfa_stats_p->num_v_must_defs +=
+ NUM_V_MUST_DEFS (V_MUST_DEF_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)
+{
+ struct walk_state *walk_state = (struct walk_state *) data;
+
+ /* If T is a regular variable that the optimizers are interested
+ in, add it to the list of variables. */
+ if (SSA_VAR_P (*tp))
+ add_referenced_var (*tp, walk_state);
+
+ /* Type, _DECL and constant nodes have no interesting children.
+ Ignore them. */
+ else if (DECL_P (*tp)
+ || TYPE_P (*tp)
+ || TREE_CODE_CLASS (TREE_CODE (*tp)) == 'c')
+ *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)
+{
+ STRIP_NOPS (var);
+
+ if (TREE_CODE (var) == SSA_NAME)
+ var = SSA_NAME_VAR (var);
+
+ while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR
+ || handled_component_p (var))
+ var = TREE_OPERAND (var, 0);
+
+#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 V_MAY_DEFS_AFTER contains fewer entries than
+ V_MAY_DEFS_BEFORE. Note that this assumes that both varrays
+ are V_MAY_DEF operands for the same statement. */
+
+static inline bool
+v_may_defs_disappeared_p (v_may_def_optype v_may_defs_before,
+ v_may_def_optype v_may_defs_after)
+{
+ /* If there was nothing before, nothing could've disappeared. */
+ if (v_may_defs_before == NULL)
+ return false;
+
+ /* All/some of them gone. */
+ if (v_may_defs_after == NULL
+ || NUM_V_MAY_DEFS (v_may_defs_before) >
+ NUM_V_MAY_DEFS (v_may_defs_after))
+ return true;
+
+ return false;
+}
+
+/* Return true if V_MUST_DEFS_AFTER contains fewer entries than
+ V_MUST_DEFS_BEFORE. Note that this assumes that both varrays
+ are V_MUST_DEF operands for the same statement. */
+
+static inline bool
+v_must_defs_disappeared_p (v_must_def_optype v_must_defs_before,
+ v_must_def_optype v_must_defs_after)
+{
+ /* If there was nothing before, nothing could've disappeared. */
+ if (v_must_defs_before == NULL)
+ return false;
+
+ /* All/some of them gone. */
+ if (v_must_defs_after == NULL
+ || NUM_V_MUST_DEFS (v_must_defs_before) >
+ NUM_V_MUST_DEFS (v_must_defs_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;
+ v_may_def_optype v_may_defs;
+ vuse_optype vuses;
+ v_must_def_optype v_must_defs;
+ size_t i;
+ bitmap vars_in_vops_to_rename;
+ bool found_exposed_symbol = false;
+ v_may_def_optype v_may_defs_before, v_may_defs_after;
+ v_must_def_optype v_must_defs_before, v_must_defs_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);
+ v_may_defs_before = v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree var = V_MAY_DEF_RESULT (v_may_defs, 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);
+ }
+
+ v_must_defs_before = v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, 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);
+ }
+ }
+
+ v_may_defs_after = v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree var = V_MAY_DEF_RESULT (v_may_defs, 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);
+ }
+ }
+
+ v_must_defs_after = v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, 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
+ || v_may_defs_disappeared_p (v_may_defs_before, v_may_defs_after)
+ || v_must_defs_disappeared_p (v_must_defs_before, v_must_defs_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-eh.c b/gcc/tree-eh.c
new file mode 100644
index 00000000000..c0ddf3e7c3c
--- /dev/null
+++ b/gcc/tree-eh.c
@@ -0,0 +1,1844 @@
+/* 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;
+}
+
+bool
+remove_stmt_from_eh_region (tree t)
+{
+ struct throw_stmt_node dummy;
+ void **slot;
+
+ if (!throw_stmt_table)
+ return false;
+
+ dummy.stmt = t;
+ slot = htab_find_slot (throw_stmt_table, &dummy, NO_INSERT);
+ if (slot)
+ {
+ htab_clear_slot (throw_stmt_table, slot);
+ return true;
+ }
+ else
+ return false;
+}
+
+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 the last case is the default label, as one is required.
+ Then sort the labels, which is also required in GIMPLE. */
+ CASE_LOW (last_case) = NULL;
+ sort_case_labels (case_label_vec);
+
+ /* 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 < sw_estimate * 2;
+ else
+ return f_estimate < 40 || f_estimate * 2 < sw_estimate * 3;
+}
+
+/* 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,
+ ggc_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 or floating point arithmetic. C.f. the rtl version, may_trap_p.
+ This routine expects only GIMPLE lhs or rhs input. */
+
+bool
+tree_could_trap_p (tree expr)
+{
+ enum tree_code code = TREE_CODE (expr);
+ bool honor_nans = false;
+ bool honor_snans = false;
+ bool fp_operation = false;
+ tree t;
+
+ if (TREE_CODE_CLASS (code) == '<'
+ || TREE_CODE_CLASS (code) == '1'
+ || TREE_CODE_CLASS (code) == '2')
+ {
+ t = TREE_TYPE (expr);
+ fp_operation = FLOAT_TYPE_P (t);
+ if (fp_operation)
+ {
+ honor_nans = flag_trapping_math && !flag_finite_math_only;
+ honor_snans = flag_signaling_nans != 0;
+ }
+ }
+
+ switch (code)
+ {
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case BIT_FIELD_REF:
+ t = get_base_address (expr);
+ return !t || tree_could_trap_p (t);
+
+ case INDIRECT_REF:
+ return !TREE_THIS_NOTRAP (expr);
+
+ case ASM_EXPR:
+ return TREE_THIS_VOLATILE (expr);
+
+ 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:
+ case RDIV_EXPR:
+ if (honor_snans)
+ return true;
+ if (fp_operation && flag_trapping_math)
+ return true;
+ t = TREE_OPERAND (expr, 1);
+ if (!TREE_CONSTANT (t) || integer_zerop (t))
+ return true;
+ return false;
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case LTGT_EXPR:
+ /* Some floating point comparisons may trap. */
+ return honor_nans;
+
+ 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:
+ return honor_snans;
+
+ case CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+ /* Conversion of floating point might trap. */
+ return honor_nans;
+
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ case CONJ_EXPR:
+ /* These operations don't trap even with floating point. */
+ return false;
+
+ default:
+ /* Any floating arithmetic may trap. */
+ if (fp_operation && flag_trapping_math)
+ return true;
+ return false;
+ }
+}
+
+bool
+tree_could_throw_p (tree t)
+{
+ if (!flag_exceptions)
+ return false;
+ if (TREE_CODE (t) == MODIFY_EXPR)
+ {
+ if (flag_non_call_exceptions
+ && tree_could_trap_p (TREE_OPERAND (t, 0)))
+ return true;
+ t = TREE_OPERAND (t, 1);
+ }
+
+ if (TREE_CODE (t) == CALL_EXPR)
+ return (call_expr_flags (t) & ECF_NOTHROW) == 0;
+ if (flag_non_call_exceptions)
+ return tree_could_trap_p (t);
+ 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);
+}
+
+bool
+maybe_clean_eh_stmt (tree stmt)
+{
+ if (!tree_could_throw_p (stmt))
+ if (remove_stmt_from_eh_region (stmt))
+ return true;
+ return false;
+}
+
+#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..e68e63eb8ed
--- /dev/null
+++ b/gcc/tree-flow-inline.h
@@ -0,0 +1,688 @@
+/* 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. */
+
+/* Return the variable annotation for T, which must be a _DECL node.
+ Return NULL if the variable annotation doesn't already exist. */
+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;
+}
+
+/* Return the variable annotation for T, which must be a _DECL node.
+ Create the variable annotation if it doesn't exist. */
+static inline var_ann_t
+get_var_ann (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return (ann) ? ann : create_var_ann (var);
+}
+
+/* Return the statement annotation for T, which must be a statement
+ node. Return NULL if the statement annotation doesn't exist. */
+static inline stmt_ann_t
+stmt_ann (tree t)
+{
+#if defined ENABLE_CHECKING
+ if (!is_gimple_stmt (t))
+ abort ();
+#endif
+
+ return (stmt_ann_t) t->common.ann;
+}
+
+/* Return the statement annotation for T, which must be a statement
+ node. Create the statement annotation if it doesn't exist. */
+static inline stmt_ann_t
+get_stmt_ann (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ return (ann) ? ann : create_stmt_ann (stmt);
+}
+
+
+/* Return the annotation type for annotation ANN. */
+static inline enum tree_ann_type
+ann_type (tree_ann_t ann)
+{
+ return ann->common.type;
+}
+
+/* Return the basic block for statement T. */
+static inline basic_block
+bb_for_stmt (tree t)
+{
+ stmt_ann_t ann = stmt_ann (t);
+ return ann ? ann->bb : NULL;
+}
+
+/* Return the may_aliases varray for variable VAR, or NULL if it has
+ no may aliases. */
+static inline varray_type
+may_aliases (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return ann ? ann->may_aliases : NULL;
+}
+
+/* Return true if VAR has a hidden use, false if it does not. */
+static inline bool
+has_hidden_use (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return ann ? ann->has_hidden_use : false;
+}
+
+/* Set the hidden use flag on VAR. */
+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;
+}
+
+/* Return the line number for EXPR, or return -1 if we have no line
+ number information for it. */
+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_HAS_LOCATION (expr))
+ return -1;
+
+ return EXPR_LINENO (expr);
+}
+
+/* Return the file name for EXPR, or return "???" if we have no
+ filename information. */
+static inline const char *
+get_filename (tree expr)
+{
+ const char *filename;
+ if (expr == NULL_TREE)
+ return "???";
+
+ if (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ if (EXPR_HAS_LOCATION (expr) && (filename = EXPR_FILENAME (expr)))
+ return filename;
+ else
+ return "???";
+}
+
+/* Mark statement T as modified. */
+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;
+}
+
+/* Mark statement T as unmodified. */
+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;
+}
+
+/* Return true if T is marked as modified, false otherwise. */
+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;
+}
+
+/* Return the definitions present in ANN, a statement annotation.
+ Return NULL if this annotation contains no definitions. */
+static inline def_optype
+get_def_ops (stmt_ann_t ann)
+{
+ return ann ? ann->def_ops : NULL;
+}
+
+/* Return the uses present in ANN, a statement annotation.
+ Return NULL if this annotation contains no uses. */
+static inline use_optype
+get_use_ops (stmt_ann_t ann)
+{
+ return ann ? ann->use_ops : NULL;
+}
+
+/* Return the virtual may-defs present in ANN, a statement
+ annotation.
+ Return NULL if this annotation contains no virtual may-defs. */
+static inline v_may_def_optype
+get_v_may_def_ops (stmt_ann_t ann)
+{
+ return ann ? ann->v_may_def_ops : NULL;
+}
+
+/* Return the virtual uses present in ANN, a statement annotation.
+ Return NULL if this annotation contains no virtual uses. */
+static inline vuse_optype
+get_vuse_ops (stmt_ann_t ann)
+{
+ return ann ? ann->vuse_ops : NULL;
+}
+
+/* Return the virtual must-defs present in ANN, a statement
+ annotation. Return NULL if this annotation contains no must-defs.*/
+static inline v_must_def_optype
+get_v_must_def_ops (stmt_ann_t ann)
+{
+ return ann ? ann->v_must_def_ops : NULL;
+}
+
+/* Return the tree pointer to by USE. */
+static inline tree
+get_use_from_ptr (use_operand_p use)
+{
+ return *(use.use);
+}
+
+/* Return the tree pointer to by DEF. */
+static inline tree
+get_def_from_ptr (def_operand_p def)
+{
+ return *(def.def);
+}
+
+/* Return a pointer to the tree that is at INDEX in the USES array. */
+static inline use_operand_p
+get_use_op_ptr (use_optype uses, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= uses->num_uses)
+ abort();
+#endif
+ return uses->uses[index];
+}
+
+/* Return a def_operand_p pointer for element INDEX of DEFS. */
+static inline def_operand_p
+get_def_op_ptr (def_optype defs, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= defs->num_defs)
+ abort();
+#endif
+ return defs->defs[index];
+}
+
+
+/* Return the def_operand_p that is the V_MAY_DEF_RESULT for the V_MAY_DEF
+ at INDEX in the V_MAY_DEFS array. */
+static inline def_operand_p
+get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
+{
+ def_operand_p op;
+#ifdef ENABLE_CHECKING
+ if (index >= v_may_defs->num_v_may_defs)
+ abort();
+#endif
+ op.def = &(v_may_defs->v_may_defs[index * 2]);
+ return op;
+}
+
+/* Return a use_operand_p that is the V_MAY_DEF_OP for the V_MAY_DEF at
+ INDEX in the V_MAY_DEFS array. */
+static inline use_operand_p
+get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
+{
+ use_operand_p op;
+#ifdef ENABLE_CHECKING
+ if (index >= v_may_defs->num_v_may_defs)
+ abort();
+#endif
+ op.use = &(v_may_defs->v_may_defs[index * 2 + 1]);
+ return op;
+}
+
+/* Return a use_operand_p that is at INDEX in the VUSES array. */
+static inline use_operand_p
+get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
+{
+ use_operand_p op;
+#ifdef ENABLE_CHECKING
+ if (index >= vuses->num_vuses)
+ abort();
+#endif
+ op.use = &(vuses->vuses[index]);
+ return op;
+}
+
+/* Return a def_operand_p that is the V_MUST_DEF_OP for the
+ V_MUST_DEF at INDEX in the V_MUST_DEFS array. */
+static inline def_operand_p
+get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
+{
+ def_operand_p op;
+#ifdef ENABLE_CHECKING
+ if (index >= v_must_defs->num_v_must_defs)
+ abort();
+#endif
+ op.def = &(v_must_defs->v_must_defs[index]);
+ return op;
+}
+
+/* Return a def_operand_p pointer for the result of PHI. */
+static inline def_operand_p
+get_phi_result_ptr (tree phi)
+{
+ def_operand_p op;
+ op.def = &(PHI_RESULT_TREE (phi));
+ return op;
+}
+
+/* Return a use_operand_p pointer for argument I of phinode PHI. */
+static inline use_operand_p
+get_phi_arg_def_ptr (tree phi, int i)
+{
+ use_operand_p op;
+ op.use = &(PHI_ARG_DEF_TREE (phi, i));
+ return op;
+}
+
+/* Mark the beginning of changes to the SSA operands for STMT. */
+static inline void
+start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ verify_start_operands (stmt);
+#endif
+}
+
+/* Return the bitmap of addresses taken by STMT, or NULL if it takes
+ no addresses. */
+static inline bitmap
+addresses_taken (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ return ann ? ann->addresses_taken : NULL;
+}
+
+/* Return the immediate uses of STMT, or NULL if this information is
+ not computed. */
+static dataflow_t
+get_immediate_uses (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ return ann ? ann->df : NULL;
+}
+
+/* Return the number of immediate uses present in the dataflow
+ information at DF. */
+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;
+}
+
+/* Return the tree that is at NUM in the immediate use DF array. */
+static inline tree
+immediate_use (dataflow_t df, int num)
+{
+ if (!df)
+ return NULL_TREE;
+
+#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);
+}
+
+/* Return the basic_block annotation for BB. */
+static inline bb_ann_t
+bb_ann (basic_block bb)
+{
+ return (bb_ann_t)bb->tree_annotations;
+}
+
+/* Return the PHI nodes for basic block BB, or NULL if there are no
+ PHI nodes. */
+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 = PHI_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 true if T is an executable statement. */
+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;
+}
+
+/* Set the default definition for VAR to DEF. */
+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;
+}
+
+/* Return the default definition for variable VAR, or NULL if none
+ exists. */
+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;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* Return a block_stmt_iterator that points to beginning of basic
+ block BB. */
+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;
+}
+
+/* Return a block statement iterator that points to the last label in
+ block BB. */
+
+static inline block_stmt_iterator
+bsi_after_labels (basic_block bb)
+{
+ block_stmt_iterator bsi;
+ tree_stmt_iterator next;
+
+ bsi.bb = bb;
+
+ if (!bb->stmt_list)
+ {
+#ifdef ENABLE_CHECKING
+ if (bb->index >= 0)
+ abort ();
+#endif
+ bsi.tsi.ptr = NULL;
+ bsi.tsi.container = NULL;
+ return bsi;
+ }
+
+ bsi.tsi = tsi_start (bb->stmt_list);
+ if (tsi_end_p (bsi.tsi))
+ return bsi;
+
+ /* Ensure that there are some labels. The rationale is that we want
+ to insert after the bsi that is returned, and these insertions should
+ be placed at the start of the basic block. This would not work if the
+ first statement was not label; rather fail here than enable the user
+ proceed in wrong way. */
+ if (TREE_CODE (tsi_stmt (bsi.tsi)) != LABEL_EXPR)
+ abort ();
+
+ next = bsi.tsi;
+ tsi_next (&next);
+
+ while (!tsi_end_p (next)
+ && TREE_CODE (tsi_stmt (next)) == LABEL_EXPR)
+ {
+ bsi.tsi = next;
+ tsi_next (&next);
+ }
+
+ return bsi;
+}
+
+/* Return a block statement iterator that points to the end of basic
+ block BB. */
+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;
+}
+
+/* Return true if block statement iterator I has reached the end of
+ the basic block. */
+static inline bool
+bsi_end_p (block_stmt_iterator i)
+{
+ return tsi_end_p (i.tsi);
+}
+
+/* Modify block statement iterator I so that it is at the next
+ statement in the basic block. */
+static inline void
+bsi_next (block_stmt_iterator *i)
+{
+ tsi_next (&i->tsi);
+}
+
+/* Modify block statement iterator I so that it is at the previous
+ statement in the basic block. */
+static inline void
+bsi_prev (block_stmt_iterator *i)
+{
+ tsi_prev (&i->tsi);
+}
+
+/* Return the statement that block statement iterator I is currently
+ at. */
+static inline tree
+bsi_stmt (block_stmt_iterator i)
+{
+ return tsi_stmt (i.tsi);
+}
+
+/* Return a pointer to the statement that block statement iterator I
+ is currently at. */
+static inline tree *
+bsi_stmt_ptr (block_stmt_iterator i)
+{
+ return tsi_stmt_ptr (i.tsi);
+}
+
+/* Return true if VAR may be aliased. */
+static inline bool
+may_be_aliased (tree var)
+{
+ return (TREE_ADDRESSABLE (var)
+ || decl_function_context (var) != current_function_decl);
+}
+
+/* Return true if VAR is a clobbered by function calls. */
+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);
+}
+
+/* Mark variable VAR as being clobbered by function calls. */
+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);
+}
+
+/* Mark variable VAR as being non-addressable. */
+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;
+}
+
+/* Return the common annotation for T. Return NULL if the annotation
+ doesn't already exist. */
+static inline tree_ann_t
+tree_ann (tree t)
+{
+ return t->common.ann;
+}
+
+/* Return a common annotation for T. Create the constant annotation if it
+ doesn't exist. */
+static inline tree_ann_t
+get_tree_ann (tree t)
+{
+ tree_ann_t ann = tree_ann (t);
+ return (ann) ? ann : create_tree_ann (t);
+}
+
+#endif /* _TREE_FLOW_INLINE_H */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
new file mode 100644
index 00000000000..dc4ddb2d7a4
--- /dev/null
+++ b/gcc/tree-flow.h
@@ -0,0 +1,634 @@
+/* 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
+
+/*---------------------------------------------------------------------------
+ Attributes for SSA_NAMEs.
+
+ NOTE: These structures are stored in struct tree_ssa_name
+ but are only used by the tree optimizers, so it makes better sense
+ to declare them here to avoid recompiling unrelated files when
+ making changes.
+---------------------------------------------------------------------------*/
+
+/* Aliasing information for SSA_NAMEs representing pointer variables. */
+struct ptr_info_def GTY(())
+{
+ /* 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;
+};
+
+
+/*---------------------------------------------------------------------------
+ Tree annotations stored in tree_common.ann
+---------------------------------------------------------------------------*/
+enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, STMT_ANN };
+
+struct tree_ann_common_d GTY(())
+{
+ /* Annotation type. */
+ enum tree_ann_type type;
+
+ /* The value handle for this expression. Used by GVN-PRE. */
+ tree GTY((skip)) value_handle;
+};
+
+/* 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 (V_MAY_DEF, VUSE, and V_MUST_DEF). */
+ struct v_may_def_optype_d * GTY (()) v_may_def_ops;
+ struct vuse_optype_d * GTY (()) vuse_ops;
+ struct v_must_def_optype_d * GTY (()) v_must_def_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;
+};
+
+union tree_ann_d GTY((desc ("ann_type ((tree_ann_t)&%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;
+};
+
+typedef union tree_ann_d *tree_ann_t;
+typedef struct var_ann_d *var_ann_t;
+typedef struct stmt_ann_d *stmt_ann_t;
+
+static inline tree_ann_t tree_ann (tree);
+static inline tree_ann_t get_tree_ann (tree);
+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 enum tree_ann_type ann_type (tree_ann_t);
+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 v_may_def_optype get_v_may_def_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;
+
+ /* 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)
+
+/* Array of all SSA_NAMEs used in the function. */
+extern GTY(()) varray_type ssa_names;
+
+#define num_ssa_names VARRAY_ACTIVE_SIZE (ssa_names)
+#define ssa_name(i) VARRAY_TREE (ssa_names, 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 block_stmt_iterator bsi_after_labels (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_annotations (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 tree tree_block_label (basic_block bb);
+extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
+extern bool tree_purge_dead_eh_edges (basic_block);
+extern bool tree_purge_all_dead_eh_edges (bitmap);
+
+/* 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 tree_ann_t create_tree_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 *);
+extern void kill_redundant_phi_nodes (void);
+
+/* In tree-into-ssa.c */
+extern void rewrite_into_ssa (bool);
+extern void rewrite_ssa_into_ssa (bitmap);
+
+void compute_global_livein (bitmap, bitmap);
+tree duplicate_ssa_name (tree, tree);
+
+/* 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 (use_operand_p, tree);
+extern void propagate_tree_value (tree *, tree);
+extern void replace_exp (use_operand_p, tree);
+extern bool may_propagate_copy (tree, tree);
+
+/* In tree-flow-inline.h */
+static inline int phi_arg_from_edge (tree, edge);
+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 int lookup_stmt_eh_region (tree);
+extern void add_stmt_to_eh_region (tree, int);
+extern bool remove_stmt_from_eh_region (tree);
+extern bool maybe_clean_eh_stmt (tree);
+
+/* In tree-ssa-pre.c */
+void add_to_value (tree, tree);
+void debug_value_expressions (tree);
+void print_value_expressions (FILE *, tree);
+
+
+/* In tree-vn.c */
+bool expressions_equal_p (tree, tree);
+tree get_value_handle (tree);
+hashval_t vn_compute (tree, hashval_t, vuse_optype);
+tree vn_lookup_or_add (tree, vuse_optype);
+void vn_add (tree, tree, vuse_optype);
+tree vn_lookup (tree, vuse_optype);
+void vn_init (void);
+void vn_delete (void);
+
+
+/* In tree-sra.c */
+void insert_edge_copies (tree stmt, basic_block bb);
+
+#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..97a34a1182a
--- /dev/null
+++ b/gcc/tree-gimple.c
@@ -0,0 +1,524 @@
+/* Functions to analyze and validate GIMPLE trees.
+ Copyright (C) 2002, 2003, 2004 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 -> compound-stmt
+
+ compound-stmt: STATEMENT_LIST
+ members -> stmt
+
+ stmt : block
+ | if-stmt
+ | switch-stmt
+ | goto-stmt
+ | return-stmt
+ | resx-stmt
+ | label-stmt
+ | try-stmt
+ | modify-stmt
+ | call-stmt
+
+ block : BIND_EXPR
+ BIND_EXPR_VARS -> chain of DECLs
+ BIND_EXPR_BLOCK -> BLOCK
+ BIND_EXPR_BODY -> compound-stmt
+
+ if-stmt : COND_EXPR
+ op0 -> condition
+ op1 -> compound-stmt
+ op2 -> compound-stmt
+
+ switch-stmt : SWITCH_EXPR
+ op0 -> val
+ op1 -> NULL
+ op2 -> TREE_VEC of CASE_LABEL_EXPRs
+ The CASE_LABEL_EXPRs are sorted by CASE_LOW,
+ and default is last.
+
+ goto-stmt : GOTO_EXPR
+ op0 -> LABEL_DECL | val
+
+ return-stmt : RETURN_EXPR
+ op0 -> return-value
+
+ return-value : NULL
+ | RESULT_DECL
+ | MODIFY_EXPR
+ op0 -> RESULT_DECL
+ op1 -> lhs
+
+ resx-stmt : RESX_EXPR
+
+ label-stmt : LABEL_EXPR
+ op0 -> LABEL_DECL
+
+ try-stmt : TRY_CATCH_EXPR
+ op0 -> compound-stmt
+ op1 -> handler
+ | TRY_FINALLY_EXPR
+ op0 -> compound-stmt
+ op1 -> compound-stmt
+
+ handler : catch-seq
+ | EH_FILTER_EXPR
+ | compound-stmt
+
+ catch-seq : STATEMENT_LIST
+ members -> CATCH_EXPR
+
+ modify-stmt : MODIFY_EXPR
+ op0 -> lhs
+ op1 -> rhs
+
+ call-stmt : CALL_EXPR
+ op0 -> val | OBJ_TYPE_REF
+ op1 -> call-arg-list
+
+ call-arg-list: TREE_LIST
+ members -> lhs
+
+ addr-expr-arg: ID
+ | compref
+
+ lhs : addr-expr-arg
+ | '*' val
+ | bitfieldref
+
+ min-lval : ID
+ | '*' val
+
+ bitfieldref : BIT_FIELD_REF
+ op0 -> inner-compref
+ op1 -> CONST
+ op2 -> var
+
+ compref : inner-compref
+ | REALPART_EXPR
+ op0 -> inner-compref
+ | IMAGPART_EXPR
+ op0 -> inner-compref
+
+ inner-compref: min-lval
+ | COMPONENT_REF
+ op0 -> inner-compref
+ op1 -> FIELD_DECL
+ op2 -> val
+ | ARRAY_REF
+ op0 -> inner-compref
+ op1 -> val
+ op2 -> val
+ op3 -> val
+ | ARRAY_RANGE_REF
+ op0 -> inner-compref
+ op1 -> val
+ op2 -> val
+ op3 -> val
+ | VIEW_CONVERT_EXPR
+ op0 -> inner-compref
+
+ condition : val
+ | val RELOP val
+
+ val : ID
+ | CONST
+
+ rhs : lhs
+ | CONST
+ | '&' addr-expr-arg
+ | call_expr
+ | UNOP val
+ | val BINOP val
+ | val RELOP val
+*/
+
+static inline bool is_gimple_id (tree);
+
+/* Validation of GIMPLE expressions. */
+
+/* Return true if T is a GIMPLE RHS. */
+
+bool
+is_gimple_rhs (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ switch (TREE_CODE_CLASS (code))
+ {
+ case '1':
+ case '2':
+ case '<':
+ return true;
+
+ 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:
+ case OBJ_TYPE_REF:
+ return true;
+
+ default:
+ break;
+ }
+
+ return is_gimple_lvalue (t) || is_gimple_val (t);
+}
+
+/* Returns true 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 true 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 true if T is a GIMPLE condition. */
+
+bool
+is_gimple_condexpr (tree t)
+{
+ return (is_gimple_val (t)
+ || TREE_CODE_CLASS (TREE_CODE (t)) == '<');
+}
+
+/* Return true if T is a valid operand for ADDR_EXPR. */
+
+bool
+is_gimple_addr_expr_arg (tree t)
+{
+ return (is_gimple_id (t)
+ || TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == ARRAY_RANGE_REF
+ || TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR
+ || TREE_CODE (t) == INDIRECT_REF);
+}
+
+/* Return true 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 true 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 TREE_TYPE (t) == NULL || 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 true;
+
+ case VA_ARG_EXPR:
+ /* FIXME this should be lowered. */
+ return true;
+
+ case CALL_EXPR:
+ case MODIFY_EXPR:
+ /* These are valid regardless of their type. */
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Return true 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 true 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 true 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 true 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 true 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 true 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 false;
+
+ /* 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. */
+
+bool
+is_gimple_min_lval (tree t)
+{
+ return (is_gimple_id (t)
+ || TREE_CODE (t) == INDIRECT_REF);
+}
+
+/* Return true if T is a typecast operation. */
+
+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);
+}
+
+/* Return true if T is a valid op0 of a CALL_EXPR. */
+
+bool
+is_gimple_call_addr (tree t)
+{
+ return (TREE_CODE (t) == OBJ_TYPE_REF
+ || is_gimple_val (t));
+}
+
+/* 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) == MODIFY_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == CALL_EXPR)
+ return t;
+ return NULL_TREE;
+}
+
+/* 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)
+{
+ while (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR
+ || handled_component_p (t))
+ t = TREE_OPERAND (t, 0);
+
+ if (SSA_VAR_P (t)
+ || TREE_CODE (t) == STRING_CST
+ || TREE_CODE (t) == CONSTRUCTOR
+ || TREE_CODE (t) == INDIRECT_REF)
+ return t;
+ else
+ return NULL_TREE;
+}
+
+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 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..5395c67667c
--- /dev/null
+++ b/gcc/tree-gimple.h
@@ -0,0 +1,128 @@
+/* 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_name (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 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. */
+extern bool is_gimple_stmt (tree);
+
+/* Returns true iff TYPE is a valid type for a scalar register variable. */
+extern bool is_gimple_reg_type (tree);
+/* Returns true iff T is a scalar register variable. */
+extern bool is_gimple_reg (tree);
+/* Returns true iff T is any sort of variable. */
+extern bool is_gimple_variable (tree);
+/* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */
+extern bool is_gimple_min_lval (tree);
+/* Returns true iff T is an lvalue other than an INDIRECT_REF. */
+extern bool is_gimple_addr_expr_arg (tree);
+/* Returns true iff T is any valid GIMPLE lvalue. */
+extern bool is_gimple_lvalue (tree);
+
+/* Returns true iff T is a GIMPLE restricted function invariant. */
+extern bool is_gimple_min_invariant (tree);
+/* Returns true iff T is a GIMPLE rvalue. */
+extern bool is_gimple_val (tree);
+/* Returns true iff T is a valid rhs for a MODIFY_EXPR. */
+extern bool is_gimple_rhs (tree);
+
+/* Returns true iff T is a valid if-statement condition. */
+extern bool is_gimple_condexpr (tree);
+
+/* Returns true iff T is a type conversion. */
+extern bool is_gimple_cast (tree);
+/* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
+ another CONSTRUCTOR). */
+extern bool is_gimple_constructor_elt (tree);
+/* Returns true iff T is a variable that does not need to live in memory. */
+extern bool is_gimple_non_addressable (tree t);
+
+/* Returns true iff T is a valid call address expression. */
+extern bool is_gimple_call_addr (tree);
+/* If T makes a function call, returns the CALL_EXPR operand. */
+extern tree get_call_expr_in (tree t);
+
+extern void recalculate_side_effects (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. */
+};
+
+extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
+ bool (*) (tree), fallback_t);
+extern void gimplify_type_sizes (tree, tree *);
+extern void gimplify_one_sizepos (tree *, tree *);
+extern void gimplify_stmt (tree *);
+extern void gimplify_to_stmt_list (tree *);
+extern void gimplify_body (tree *, tree);
+extern void push_gimplify_context (void);
+extern void pop_gimplify_context (tree);
+extern void gimplify_and_add (tree, tree *);
+
+/* Miscellaneous helpers. */
+extern tree get_base_address (tree t);
+extern void gimple_add_tmp_var (tree);
+extern tree gimple_current_bind_expr (void);
+extern void gimple_push_bind_expr (tree);
+extern void gimple_pop_bind_expr (void);
+extern void unshare_all_trees (tree);
+extern tree voidify_wrapper_expr (tree, tree);
+extern tree gimple_build_eh_filter (tree, tree, tree);
+extern tree build_and_jump (tree *);
+extern tree alloc_stmt_list (void);
+extern void free_stmt_list (tree);
+extern tree force_labels_r (tree *, int *, void *);
+extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
+
+/* In tree-nested.c. */
+extern void lower_nested_functions (tree);
+
+#endif /* _TREE_SIMPLE_H */
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
new file mode 100644
index 00000000000..027a90b39f0
--- /dev/null
+++ b/gcc/tree-into-ssa.c
@@ -0,0 +1,1912 @@
+/* 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"
+#include "ggc.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 that contain a phi node for VAR. */
+ bitmap phi_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;
+
+ /* Bitmap of names to rename. */
+ sbitmap names_to_rename;
+};
+
+struct rewrite_block_data
+{
+ varray_type block_defs;
+};
+
+/* Information stored for ssa names. */
+
+struct ssa_name_info
+{
+ /* 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;
+
+ /* The actual definition of the ssa name. */
+ tree current_def;
+};
+
+/* 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 set_def_block (tree, basic_block, bool, bool);
+static void set_livein_block (tree, basic_block);
+static bool prepare_use_operand_for_rename (use_operand_p, size_t *uid_p);
+static bool prepare_def_operand_for_rename (tree def, size_t *uid_p);
+static void insert_phi_nodes (bitmap *, bitmap);
+static void rewrite_stmt (struct dom_walk_data *, basic_block,
+ block_stmt_iterator);
+static inline void rewrite_operand (use_operand_p);
+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);
+
+/* Get the information associated with NAME. */
+
+static inline struct ssa_name_info *
+get_ssa_name_ann (tree name)
+{
+ if (!SSA_NAME_AUX (name))
+ SSA_NAME_AUX (name) = xcalloc (1, sizeof (struct ssa_name_info));
+
+ return SSA_NAME_AUX (name);
+}
+
+/* Gets phi_state field for VAR. */
+
+static inline enum need_phi_state
+get_phi_state (tree var)
+{
+ if (TREE_CODE (var) == SSA_NAME)
+ return get_ssa_name_ann (var)->need_phi_state;
+ else
+ return var_ann (var)->need_phi_state;
+}
+
+/* Sets phi_state field for VAR to STATE. */
+
+static inline void
+set_phi_state (tree var, enum need_phi_state state)
+{
+ if (TREE_CODE (var) == SSA_NAME)
+ get_ssa_name_ann (var)->need_phi_state = state;
+ else
+ var_ann (var)->need_phi_state = state;
+}
+
+/* Return the current definition for VAR. */
+
+static inline tree
+get_current_def (tree var)
+{
+ if (TREE_CODE (var) == SSA_NAME)
+ return get_ssa_name_ann (var)->current_def;
+ else
+ return var_ann (var)->current_def;
+}
+
+/* Sets current definition of VAR to DEF. */
+
+static inline void
+set_current_def (tree var, tree def)
+{
+ if (TREE_CODE (var) == SSA_NAME)
+ get_ssa_name_ann (var)->current_def = def;
+ else
+ var_ann (var)->current_def = def;
+}
+
+/* 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). */
+
+void
+compute_global_livein (bitmap livein, bitmap def_blocks)
+{
+ basic_block bb, *worklist, *tos;
+ int i;
+
+ tos = worklist
+ = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 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);
+}
+
+/* Block initialization routine for mark_def_sites. Clear the
+ KILLS bitmap at the start of each block. */
+
+static void
+ssa_mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
+ basic_block bb)
+{
+ struct mark_def_sites_global_data *gd = walk_data->global_data;
+ sbitmap kills = gd->kills;
+ tree phi, def;
+ unsigned def_uid;
+
+ sbitmap_zero (kills);
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ def = PHI_RESULT (phi);
+ def_uid = SSA_NAME_VERSION (def);
+
+ if (!TEST_BIT (gd->names_to_rename, def_uid))
+ continue;
+
+ set_def_block (def, bb, true, true);
+ SET_BIT (kills, def_uid);
+ }
+}
+
+/* Marks ssa names used as arguments of phis at the end of BB. */
+
+static void
+ssa_mark_phi_uses (struct dom_walk_data *walk_data, basic_block bb)
+{
+ struct mark_def_sites_global_data *gd = walk_data->global_data;
+ sbitmap kills = gd->kills;
+ edge e;
+ tree phi, use;
+ unsigned uid;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ use = PHI_ARG_DEF_FROM_EDGE (phi, e);
+ if (TREE_CODE (use) != SSA_NAME)
+ continue;
+
+ uid = SSA_NAME_VERSION (use);
+
+ if (TEST_BIT (gd->names_to_rename, uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (use, bb);
+ }
+ }
+}
+
+/* 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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++)
+ {
+ use_operand_p use_p = USE_OP_PTR (uses, i);
+
+ if (prepare_use_operand_for_rename (use_p, &uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (USE_FROM_PTR (use_p), bb);
+ }
+
+ /* Similarly for virtual uses. */
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ use_operand_p use_p = VUSE_OP_PTR (vuses, i);
+
+ if (prepare_use_operand_for_rename (use_p, &uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (USE_FROM_PTR (use_p), bb);
+ }
+
+ /* Note that virtual definitions are irrelevant for computing KILLS
+ because a V_MAY_DEF 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. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ use_operand_p use_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
+ if (prepare_use_operand_for_rename (use_p, &uid))
+ {
+ /* If we do not already have an SSA_NAME for our destination,
+ then set the destination to the source. */
+ if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
+ SET_V_MAY_DEF_RESULT (v_may_defs, i, USE_FROM_PTR (use_p));
+
+ set_livein_block (USE_FROM_PTR (use_p), bb);
+ set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb, false, false);
+ }
+ }
+
+ /* Now process the virtual must-defs made by this statement. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree def = V_MUST_DEF_OP (v_must_defs, i);
+
+ if (prepare_def_operand_for_rename (def, &uid))
+ {
+ set_def_block (def, bb, false, false);
+ SET_BIT (kills, uid);
+ }
+ }
+
+ /* 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 = DEF_OP (defs, i);
+
+ if (prepare_def_operand_for_rename (def, &uid))
+ {
+ set_def_block (def, bb, false, false);
+ SET_BIT (kills, uid);
+ }
+ }
+}
+
+/* Ditto, but works over ssa names. */
+
+static void
+ssa_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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ vuse_optype vuses;
+ def_optype defs;
+ use_optype uses;
+ size_t i, uid, def_uid;
+ tree stmt, use, def;
+ stmt_ann_t ann;
+
+ /* Mark all the blocks that have definitions for each variable in the
+ names_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++)
+ {
+ use = USE_OP (uses, i);
+ uid = SSA_NAME_VERSION (use);
+
+ if (TEST_BIT (gd->names_to_rename, uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (use, bb);
+ }
+
+ /* Similarly for virtual uses. */
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ use = VUSE_OP (vuses, i);
+ uid = SSA_NAME_VERSION (use);
+
+ if (TEST_BIT (gd->names_to_rename, uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (use, bb);
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ use = V_MAY_DEF_OP (v_may_defs, i);
+ uid = SSA_NAME_VERSION (use);
+
+ if (TEST_BIT (gd->names_to_rename, uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (use, 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++)
+ {
+ def = DEF_OP (defs, i);
+ def_uid = SSA_NAME_VERSION (def);
+
+ if (TEST_BIT (gd->names_to_rename, def_uid))
+ {
+ set_def_block (def, bb, false, true);
+ SET_BIT (kills, def_uid);
+ }
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ def = V_MAY_DEF_RESULT (v_may_defs, i);
+ def_uid = SSA_NAME_VERSION (def);
+
+ if (TEST_BIT (gd->names_to_rename, def_uid))
+ {
+ set_def_block (def, bb, false, true);
+ SET_BIT (kills, def_uid);
+ }
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ def = V_MUST_DEF_OP (v_must_defs, i);
+ def_uid = SSA_NAME_VERSION (def);
+
+ if (TEST_BIT (gd->names_to_rename, def_uid))
+ {
+ set_def_block (def, bb, false, true);
+ SET_BIT (kills, def_uid);
+ }
+ }
+}
+
+/* Mark block BB as the definition site for variable VAR. PHI_P is true if
+ VAR is defined by a phi node. SSA_P is true if we are called from
+ rewrite_ssa_into_ssa. */
+
+static void
+set_def_block (tree var, basic_block bb, bool phi_p, bool ssa_p)
+{
+ struct def_blocks_d *db_p;
+ enum need_phi_state state;
+
+ if (!ssa_p
+ && TREE_CODE (var) == SSA_NAME)
+ var = SSA_NAME_VAR (var);
+
+ state = get_phi_state (var);
+ 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);
+ if (phi_p)
+ bitmap_set_bit (db_p->phi_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)
+ set_phi_state (var, NEED_PHI_STATE_NO);
+ else
+ set_phi_state (var, 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 = get_phi_state (var);
+
+ 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)))
+ set_phi_state (var, NEED_PHI_STATE_MAYBE);
+ }
+ else
+ set_phi_state (var, NEED_PHI_STATE_MAYBE);
+}
+
+
+/* If the use operand pointed to by OP_P needs to be renamed, then strip away
+ any SSA_NAME wrapping the operand, set *UID_P to the underlying variable's
+ uid, and return true. Otherwise return false. If the operand was an
+ SSA_NAME, change it to the stipped name. */
+
+static bool
+prepare_use_operand_for_rename (use_operand_p op_p, size_t *uid_p)
+{
+ tree use = USE_FROM_PTR (op_p);
+ tree var = (TREE_CODE (use) != SSA_NAME) ? use : SSA_NAME_VAR (use);
+ *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 this is a use which already
+ has an SSA_NAME, then strip it off.
+
+ By not throwing away SSA_NAMEs on assignments, we avoid a lot of
+ useless churn of SSA_NAMEs without having to overly complicate the
+ renamer. */
+ if (TREE_CODE (use) == SSA_NAME)
+ SET_USE (op_p, var);
+
+ return true;
+}
+
+/* If the def variable DEF needs to be renamed, then strip away any SSA_NAME
+ wrapping the operand, set *UID_P to the underlying variable's uid and return
+ true. Otherwise return false. */
+
+static bool
+prepare_def_operand_for_rename (tree def, size_t *uid_p)
+{
+ tree var = (TREE_CODE (def) != SSA_NAME) ? def : SSA_NAME_VAR (def);
+ *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;
+
+ return true;
+}
+
+/* Helper for insert_phi_nodes. If VAR needs PHI nodes, insert them
+ at the dominance frontier (DFS) of blocks defining VAR.
+ WORK_STACK is the varray used to implement the worklist of basic
+ blocks. */
+
+static inline
+void insert_phi_nodes_1 (tree var, bitmap *dfs, varray_type *work_stack)
+{
+ if (get_phi_state (var) != 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). If NAMES_TO_RENAME is not NULL, do the same but
+ for ssa name rewriting. */
+
+static void
+insert_phi_nodes (bitmap *dfs, bitmap names_to_rename)
+{
+ 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_GENERIC_PTR_NOGC_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 (names_to_rename)
+ {
+ EXECUTE_IF_SET_IN_BITMAP (names_to_rename, 0, i,
+ {
+ if (ssa_name (i))
+ insert_phi_nodes_1 (ssa_name (i), dfs, &work_stack);
+ });
+ }
+ else 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);
+
+ VARRAY_FREE (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 virtual 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 = PHI_CHAIN (phi))
+ {
+ tree result = PHI_RESULT (phi);
+
+ register_new_def (result, &bd->block_defs);
+ }
+}
+
+/* Register DEF (an SSA_NAME) to be a new definition for the original
+ ssa name VAR and push VAR's current reaching definition
+ into the stack pointed by BLOCK_DEFS_P. */
+
+static void
+ssa_register_new_def (tree var, tree def, varray_type *block_defs_p)
+{
+ 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
+ nothing to do. TODO we should not be called at all, and just
+ keep the original name. */
+ if (get_phi_state (var) == NEED_PHI_STATE_NO)
+ {
+ set_current_def (var, def);
+ return;
+ }
+
+ currdef = get_current_def (var);
+ 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. */
+ VARRAY_PUSH_TREE (*block_defs_p, var);
+ VARRAY_PUSH_TREE (*block_defs_p, currdef);
+
+ /* Set the current reaching definition for VAR to be DEF. */
+ set_current_def (var, def);
+}
+
+/* Ditto, for rewriting ssa names. */
+
+static void
+ssa_rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
+{
+ tree phi, new_name;
+ struct rewrite_block_data *bd
+ = (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ sbitmap names_to_rename = walk_data->global_data;
+ edge e;
+ bool abnormal_phi;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
+
+ for (e = bb->pred; e; e = e->pred_next)
+ if (e->flags & EDGE_ABNORMAL)
+ break;
+ abnormal_phi = (e != NULL);
+
+ /* 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);
+
+ if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (result)))
+ {
+ new_name = duplicate_ssa_name (result, phi);
+ SET_PHI_RESULT (phi, new_name);
+
+ if (abnormal_phi)
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) = 1;
+ }
+ else
+ new_name = result;
+
+ ssa_register_new_def (result, new_name, &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);
+ }
+ }
+}
+
+/* Ditto, for ssa name rewriting. */
+
+static void
+ssa_rewrite_phi_arguments (struct dom_walk_data *walk_data, basic_block bb)
+{
+ edge e;
+ sbitmap names_to_rename = walk_data->global_data;
+ use_operand_p op;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ tree phi;
+
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ op = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
+ if (TREE_CODE (USE_FROM_PTR (op)) != SSA_NAME)
+ continue;
+
+ if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (op))))
+ continue;
+
+ SET_USE (op, get_reaching_def (USE_FROM_PTR (op)));
+ if (e->flags & EDGE_ABNORMAL)
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (op)) = 1;
+ }
+ }
+}
+
+/* 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;
+ }
+
+ set_current_def (var, saved_def);
+ }
+}
+
+/* Ditto, for rewriting ssa names. */
+
+static void
+ssa_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 var;
+ tree saved_def = VARRAY_TOP_TREE (bd->block_defs);
+ VARRAY_POP (bd->block_defs);
+
+ var = VARRAY_TOP_TREE (bd->block_defs);
+ VARRAY_POP (bd->block_defs);
+
+ set_current_def (var, 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. WORK_STACK is the varray used to
+ implement the worklist of basic blocks. */
+
+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;
+ edge e;
+ tree phi;
+ basic_block bb;
+
+ 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_GENERIC_PTR_NOGC (*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)
+ {
+ int dfs_index;
+
+ bb = VARRAY_TOP_GENERIC_PTR_NOGC (*work_stack);
+ bb_index = bb->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_GENERIC_PTR_NOGC (*work_stack, bb);
+ bitmap_set_bit (phi_insertion_points, dfs_index);
+ });
+ }
+
+ /* Remove the blocks where we already have the phis. */
+ bitmap_operation (phi_insertion_points, phi_insertion_points,
+ def_map->phi_blocks, BITMAP_AND_COMPL);
+
+ /* 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,
+ do
+ {
+ bb = BASIC_BLOCK (bb_index);
+
+ phi = create_phi_node (var, bb);
+
+ /* If we are rewriting ssa names, add also the phi arguments. */
+ if (TREE_CODE (var) == SSA_NAME)
+ {
+ for (e = bb->pred; e; e = e->pred_next)
+ add_phi_arg (&phi, var, e);
+ }
+ }
+ while (0));
+
+ 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_defs = V_MUST_DEF_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++)
+ {
+ def_operand_p def_p = DEF_OP_PTR (defs, i);
+
+ if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
+ SET_DEF (def_p, make_ssa_name (DEF_FROM_PTR (def_p), stmt));
+
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (DEF_FROM_PTR (def_p), &bd->block_defs);
+ }
+
+ /* Register new virtual definitions made by the statement. */
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i));
+
+ if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
+ SET_V_MAY_DEF_RESULT (v_may_defs, i,
+ make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i),
+ stmt));
+
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), &bd->block_defs);
+ }
+
+ /* Register new virtual mustdefs made by the statement. */
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ def_operand_p v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
+
+ if (TREE_CODE (DEF_FROM_PTR (v_must_def_p)) != SSA_NAME)
+ SET_DEF (v_must_def_p,
+ make_ssa_name (DEF_FROM_PTR (v_must_def_p), stmt));
+
+ /* FIXME: We shouldn't be registering new mustdefs if the variable
+ doesn't need to be renamed. */
+ register_new_def (DEF_FROM_PTR (v_must_def_p), &bd->block_defs);
+ }
+
+}
+
+/* Ditto, for rewriting ssa names. */
+
+static void
+ssa_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, var;
+ use_operand_p use_p;
+ def_operand_p def_p;
+ vuse_optype vuses;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ def_optype defs;
+ use_optype uses;
+ struct rewrite_block_data *bd;
+ sbitmap names_to_rename = walk_data->global_data;
+
+ 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);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_defs = V_MUST_DEF_OPS (ann);
+
+ /* Step 1. Rewrite USES and VUSES in the statement. */
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ use_p = USE_OP_PTR (uses, i);
+ if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
+ SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
+ }
+
+ /* Rewrite virtual uses in the statement. */
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ use_p = VUSE_OP_PTR (vuses, i);
+ if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
+ SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
+ }
+
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ use_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
+ if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
+ SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
+ }
+
+ /* Step 2. Register the statement's DEF and VDEF operands. */
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ def_p = DEF_OP_PTR (defs, i);
+ var = DEF_FROM_PTR (def_p);
+
+ if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
+ continue;
+
+ SET_DEF (def_p, duplicate_ssa_name (var, stmt));
+ ssa_register_new_def (var, DEF_FROM_PTR (def_p), &bd->block_defs);
+ }
+
+ /* Register new virtual definitions made by the statement. */
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ def_p = V_MAY_DEF_RESULT_PTR (v_may_defs, i);
+ var = DEF_FROM_PTR (def_p);
+
+ if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
+ continue;
+
+ SET_DEF (def_p, duplicate_ssa_name (var, stmt));
+ ssa_register_new_def (var, DEF_FROM_PTR (def_p), &bd->block_defs);
+ }
+
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
+ var = DEF_FROM_PTR (def_p);
+
+ if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
+ continue;
+
+ SET_DEF (def_p, duplicate_ssa_name (var, stmt));
+ ssa_register_new_def (var, DEF_FROM_PTR (def_p), &bd->block_defs);
+ }
+}
+
+/* Replace the operand pointed by OP_P with its immediate reaching
+ definition. */
+
+static inline void
+rewrite_operand (use_operand_p op_p)
+{
+ if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
+ SET_USE (op_p, get_reaching_def (USE_FROM_PTR (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 (get_phi_state (var) == NEED_PHI_STATE_NO)
+ {
+ set_current_def (var, def);
+ return;
+ }
+
+ currdef = get_current_def (var);
+ 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. */
+ set_current_def (var, 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, avar;
+
+ /* Lookup the current reaching definition for VAR. */
+ default_d = NULL_TREE;
+ currdef_var = get_current_def (var);
+
+ /* If there is no reaching definition for VAR, create and register a
+ default definition for it (if needed). */
+ if (currdef_var == NULL_TREE)
+ {
+ if (TREE_CODE (var) == SSA_NAME)
+ avar = SSA_NAME_VAR (var);
+ else
+ avar = var;
+
+ default_d = default_def (avar);
+ if (default_d == NULL_TREE)
+ {
+ default_d = make_ssa_name (avar, build_empty_stmt ());
+ set_default_def (avar, default_d);
+ }
+ set_current_def (var, 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->phi_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->phi_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).
+
+ ALL is true if all variables should be renamed (otherwise just those
+ mentioned in vars_to_rename are taken into account). */
+
+void
+rewrite_into_ssa (bool all)
+{
+ bitmap *dfs;
+ basic_block bb;
+ struct dom_walk_data walk_data;
+ struct mark_def_sites_global_data mark_def_sites_global_data;
+ bitmap old_vars_to_rename = vars_to_rename;
+ unsigned i;
+
+ timevar_push (TV_TREE_SSA_OTHER);
+
+ if (all)
+ vars_to_rename = NULL;
+ else
+ {
+ /* Initialize the array of variables to rename. */
+
+ if (vars_to_rename == NULL)
+ abort ();
+
+ if (bitmap_first_set_bit (vars_to_rename) < 0)
+ {
+ timevar_pop (TV_TREE_SSA_OTHER);
+ return;
+ }
+
+ 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++)
+ set_current_def (referenced_var (i), NULL_TREE);
+
+ /* 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, NULL);
+
+ /* 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);
+
+ vars_to_rename = old_vars_to_rename;
+ timevar_pop (TV_TREE_SSA_OTHER);
+}
+
+/* The ssa names in NAMES_TO_RENAME may have more than one definition;
+ add phi nodes and rewrite them to fix this. */
+
+void
+rewrite_ssa_into_ssa (bitmap names_to_rename)
+{
+ bitmap *dfs;
+ basic_block bb;
+ struct dom_walk_data walk_data;
+ struct mark_def_sites_global_data mark_def_sites_global_data;
+ unsigned i;
+ sbitmap snames_to_rename;
+ tree name;
+
+ if (bitmap_first_set_bit (names_to_rename) < 0)
+ return;
+
+ timevar_push (TV_TREE_SSA_OTHER);
+
+ /* Allocate memory for the DEF_BLOCKS hash table. */
+ def_blocks = htab_create (num_ssa_names,
+ 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 ();
+ }
+
+ /* 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
+ = ssa_mark_def_sites_initialize_block;
+ walk_data.before_dom_children_walk_stmts = ssa_mark_def_sites;
+ walk_data.before_dom_children_after_stmts = ssa_mark_phi_uses;
+ walk_data.after_dom_children_before_stmts = NULL;
+ walk_data.after_dom_children_walk_stmts = NULL;
+ walk_data.after_dom_children_after_stmts = NULL;
+
+ snames_to_rename = sbitmap_alloc (num_ssa_names);
+ sbitmap_zero (snames_to_rename);
+ EXECUTE_IF_SET_IN_BITMAP (names_to_rename, 0, i,
+ SET_BIT (snames_to_rename, i));
+
+ mark_def_sites_global_data.kills = sbitmap_alloc (num_ssa_names);
+ mark_def_sites_global_data.names_to_rename = snames_to_rename;
+ 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);
+
+ for (i = 0; i < num_ssa_names; i++)
+ if (ssa_name (i))
+ set_current_def (ssa_name (i), NULL_TREE);
+
+ /* Insert PHI nodes at dominance frontiers of definition blocks. */
+ insert_phi_nodes (dfs, names_to_rename);
+
+ /* 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 = ssa_rewrite_initialize_block;
+ walk_data.before_dom_children_walk_stmts = ssa_rewrite_stmt;
+ walk_data.before_dom_children_after_stmts = ssa_rewrite_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 = ssa_rewrite_finalize_block;
+ walk_data.global_data = snames_to_rename;
+ 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);
+
+ sbitmap_free (snames_to_rename);
+
+ 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);
+
+ for (i = 0; i < num_ssa_names; i++)
+ {
+ name = ssa_name (i);
+ if (!name
+ || !SSA_NAME_AUX (name))
+ continue;
+
+ free (SSA_NAME_AUX (name));
+ SSA_NAME_AUX (name) = NULL;
+ }
+ timevar_pop (TV_TREE_SSA_OTHER);
+}
+
+/* Rewrites all variables into ssa. */
+
+static void
+rewrite_all_into_ssa (void)
+{
+ rewrite_into_ssa (true);
+}
+
+struct tree_opt_pass pass_build_ssa =
+{
+ "ssa", /* name */
+ NULL, /* gate */
+ rewrite_all_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..d13ea960888
--- /dev/null
+++ b/gcc/tree-iterator.c
@@ -0,0 +1,367 @@
+/* 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);
+ memset (list, 0, sizeof(struct tree_common));
+ TREE_SET_CODE (list, STATEMENT_LIST);
+ }
+ 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 ();
+
+ 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;
+ }
+
+ TREE_SIDE_EFFECTS (i->container) = 1;
+
+ 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 ();
+
+ 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;
+ }
+
+ TREE_SIDE_EFFECTS (i->container) = 1;
+
+ 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..c2483098871
--- /dev/null
+++ b/gcc/tree-iterator.h
@@ -0,0 +1,123 @@
+/* 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 *);
+
+void append_to_statement_list (tree, tree *);
+void append_to_statement_list_force (tree, tree *);
+
+#endif /* GCC_TREE_ITERATOR_H */
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
new file mode 100644
index 00000000000..2320bc9f2d9
--- /dev/null
+++ b/gcc/tree-mudflap.c
@@ -0,0 +1,1294 @@
+/* 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 "hard-reg-set.h"
+#include "rtl.h"
+#include "tree.h"
+#include "tm_p.h"
+#include "basic-block.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"
+#include "cgraph.h"
+
+/* Internal function decls */
+
+/* Helpers. */
+static tree mf_build_string (const char *string);
+static tree mf_varname_tree (tree);
+static tree mf_file_function_line_tree (location_t);
+
+/* Indirection-related instrumentation. */
+static void mf_decl_cache_locals (void);
+static void mf_decl_clear_locals (void);
+static void mf_xform_derefs (void);
+static void execute_mudflap_function_ops (void);
+
+/* Addressable variables instrumentation. */
+static void mf_xform_decls (tree, tree);
+static tree mx_xfn_xform_decls (tree *, int *, void *);
+static void mx_register_decls (tree, tree *);
+static void execute_mudflap_function_decls (void);
+
+
+/* ------------------------------------------------------------------------ */
+/* Some generally helpful functions for mudflap instrumentation. */
+
+/* Build a reference to a literal string. */
+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);
+}
+
+/* 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]. */
+ {
+ expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl));
+ const char *sourcefile;
+ unsigned sourceline = xloc.line;
+
+ sourcefile = xloc.file;
+ 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);
+
+ 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 location)
+{
+ expanded_location xloc = expand_location (location);
+ const char *file = NULL, *colon, *line, *op, *name, *cp;
+ char linebuf[18];
+ char *string;
+ tree result;
+
+ /* Add FILENAME[:LINENUMBER]. */
+ if (xloc.file == NULL && current_function_decl != NULL_TREE)
+ xloc.file = DECL_SOURCE_FILE (current_function_decl);
+ if (xloc.file == NULL)
+ xloc.file = "<unknown file>";
+
+ if (xloc.line > 0)
+ {
+ sprintf (linebuf, "%d", xloc.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;
+}
+
+
+/* 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 unsigned char __mf_lc_shift; */
+static GTY (()) tree mf_cache_shift_decl;
+
+/* extern 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, int type); */
+static GTY (()) tree mf_unregister_fndecl;
+
+/* Helper for mudflap_init: construct a decl with the given category,
+ name, and type, mark it an external reference, and pushdecl it. */
+static inline tree
+mf_make_builtin (enum tree_code category, const char *name, tree type)
+{
+ tree decl = mf_mark (build_decl (category, get_identifier (name), type));
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ lang_hooks.decls.pushdecl (decl);
+ return decl;
+}
+
+/* Helper for mudflap_init: construct a tree corresponding to the type
+ struct __mf_cache { uintptr_t low; uintptr_t high; };
+ where uintptr_t is the FIELD_TYPE argument. */
+static inline tree
+mf_make_mf_cache_struct_type (tree field_type)
+{
+ /* There is, abominably, no language-independent way to construct a
+ RECORD_TYPE. So we have to call the basic type construction
+ primitives by hand. */
+ tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type);
+ tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type);
+
+ tree struct_type = make_node (RECORD_TYPE);
+ DECL_CONTEXT (fieldlo) = struct_type;
+ DECL_CONTEXT (fieldhi) = struct_type;
+ TREE_CHAIN (fieldlo) = fieldhi;
+ TYPE_FIELDS (struct_type) = fieldlo;
+ TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
+ layout_type (struct_type);
+
+ return struct_type;
+}
+
+#define build_function_type_3(rtype, arg1, arg2, arg3) \
+ build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \
+ tree_cons (0, arg3, void_list_node))))
+#define build_function_type_4(rtype, arg1, arg2, arg3, arg4) \
+ build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \
+ tree_cons (0, arg3, tree_cons (0, arg4, \
+ void_list_node)))))
+
+/* Initialize the global tree nodes that correspond to mf-runtime.h
+ declarations. */
+void
+mudflap_init (void)
+{
+ static bool done = false;
+ tree mf_const_string_type;
+ tree mf_cache_array_type;
+ tree mf_check_register_fntype;
+ tree mf_unregister_fntype;
+
+ if (done)
+ return;
+ done = true;
+
+ mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode,
+ /*unsignedp=*/true);
+ mf_const_string_type
+ = build_pointer_type (build_qualified_type
+ (char_type_node, TYPE_QUAL_CONST));
+
+ mf_cache_struct_type = mf_make_mf_cache_struct_type (mf_uintptr_type);
+ mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
+ mf_cache_array_type = build_array_type (mf_cache_struct_type, 0);
+ mf_check_register_fntype =
+ build_function_type_4 (void_type_node, ptr_type_node, size_type_node,
+ integer_type_node, mf_const_string_type);
+ mf_unregister_fntype =
+ build_function_type_3 (void_type_node, ptr_type_node, size_type_node,
+ integer_type_node);
+
+ mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache",
+ mf_cache_array_type);
+ mf_cache_shift_decl = mf_make_builtin (VAR_DECL, "__mf_lc_shift",
+ unsigned_char_type_node);
+ mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask",
+ mf_uintptr_type);
+ mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check",
+ mf_check_register_fntype);
+ mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register",
+ mf_check_register_fntype);
+ mf_unregister_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_unregister",
+ mf_unregister_fntype);
+}
+#undef build_function_type_4
+#undef build_function_type_3
+
+
+/* ------------------------------------------------------------------------ */
+/* Memory reference transforms. Perform the mudflap indirection-related
+ tree transforms on the current function.
+
+ This is the second part of the mudflap instrumentation. It works on
+ low-level GIMPLE using the CFG, because we want to run this pass after
+ tree optimizations have been performed, but we have to preserve the CFG
+ for expansion from trees to RTL. */
+
+static void
+execute_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 ();
+
+ mf_xform_derefs ();
+
+ if (! flag_mudflap_threads)
+ mf_decl_clear_locals ();
+
+ pop_gimplify_context (NULL);
+}
+
+/* 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 (void)
+{
+ tree t, shift_init_stmts, mask_init_stmts;
+ tree_stmt_iterator tsi;
+
+ /* Build the cache vars. */
+ 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 the cache vars. We just load the
+ globals into the cache variables. */
+ t = build (MODIFY_EXPR, TREE_TYPE (mf_cache_shift_decl_l),
+ mf_cache_shift_decl_l, mf_cache_shift_decl);
+ SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
+ gimplify_to_stmt_list (&t);
+ shift_init_stmts = t;
+
+ t = build (MODIFY_EXPR, TREE_TYPE (mf_cache_mask_decl_l),
+ mf_cache_mask_decl_l, mf_cache_mask_decl);
+ SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
+ gimplify_to_stmt_list (&t);
+ mask_init_stmts = t;
+
+ /* Anticipating multiple entry points, we insert the cache vars
+ initializers in each successor of the ENTRY_BLOCK_PTR. */
+ for (tsi = tsi_start (shift_init_stmts);
+ ! tsi_end_p (tsi);
+ tsi_next (&tsi))
+ insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
+
+ for (tsi = tsi_start (mask_init_stmts);
+ ! tsi_end_p (tsi);
+ tsi_next (&tsi))
+ insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
+ bsi_commit_edge_inserts (NULL);
+}
+
+
+static void
+mf_decl_clear_locals (void)
+{
+ /* Unset local shadows. */
+ mf_cache_shift_decl_l = NULL_TREE;
+ mf_cache_mask_decl_l = NULL_TREE;
+}
+
+static void
+mf_build_check_statement_for (tree addr, tree size,
+ block_stmt_iterator *instr_bsi,
+ location_t *locus, tree dirflag)
+{
+ tree_stmt_iterator head, tsi;
+ tree ptrtype = TREE_TYPE (addr);
+ block_stmt_iterator bsi;
+ basic_block cond_bb, then_bb, join_bb;
+ edge e;
+ tree cond, t, u, v, l1, l2;
+ tree mf_value;
+ tree mf_base;
+ tree mf_elem;
+
+ /* We first need to split the current basic block, and start altering
+ the CFG. This allows us to insert the statements we're about to
+ construct into the right basic blocks. The label l1 is the label
+ of the block for the THEN clause of the conditional jump we're
+ about to construct, and l2 is the ELSE clause, which is just the
+ continuation of the old statement stream. */
+ l1 = create_artificial_label ();
+ l2 = create_artificial_label ();
+ cond_bb = bb_for_stmt (bsi_stmt (*instr_bsi));
+ bsi = *instr_bsi;
+ bsi_prev (&bsi);
+ if (! bsi_end_p (bsi))
+ {
+ e = split_block (cond_bb, bsi_stmt (bsi));
+ cond_bb = e->src;
+ join_bb = e->dest;
+ }
+ else
+ {
+ join_bb = cond_bb;
+ cond_bb = create_empty_bb (join_bb->prev_bb);
+ e = make_edge (cond_bb, join_bb, 0);
+ }
+ e->flags = EDGE_FALSE_VALUE;
+ then_bb = create_empty_bb (cond_bb);
+ make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
+ make_edge (then_bb, join_bb, EDGE_FALLTHRU);
+
+ /* We expect that the conditional jump we will construct will not
+ be taken very often as it basically is an exception condition. */
+ predict_edge_def (then_bb->pred, PRED_MUDFLAP, NOT_TAKEN);
+
+ /* 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, then_bb, cond_bb);
+ set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
+ }
+
+ /* 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>. */
+ t = build (MODIFY_EXPR, void_type_node, mf_value, unshare_expr (addr));
+ SET_EXPR_LOCUS (t, locus);
+ gimplify_to_stmt_list (&t);
+ head = tsi_start (t);
+ tsi = tsi_last (t);
+
+ /* Build: __mf_base = (uintptr_t)__mf_value. */
+ t = build (MODIFY_EXPR, void_type_node, mf_base,
+ build1 (NOP_EXPR, mf_uintptr_type, mf_value));
+ SET_EXPR_LOCUS (t, locus);
+ gimplify_to_stmt_list (&t);
+ tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+
+ /* 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, NULL_TREE, NULL_TREE);
+ t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
+ t = build (MODIFY_EXPR, void_type_node, mf_elem, t);
+ SET_EXPR_LOCUS (t, locus);
+ gimplify_to_stmt_list (&t);
+ tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+
+ /* Quick validity check.
+
+ if (__mf_elem->low > __mf_base
+ || (__mf_elem_high < __mf_base + sizeof(T) - 1))
+ {
+ __mf_check ();
+ ... and only if single-threaded:
+ __mf_lookup_shift_1 = f...;
+ __mf_lookup_mask_l = ...;
+ }
+
+ It is expected that this body of code is rarely executed so we mark
+ the edge to the THEN clause of the conditional jump as unlikely. */
+
+ /* Construct t <-- '__mf_elem->low > __mf_base'. */
+ t = build (COMPONENT_REF, mf_uintptr_type,
+ build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
+ TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
+ t = build (GT_EXPR, boolean_type_node, t, mf_base);
+
+ /* Construct '__mf_elem->high < __mf_base + sizeof(T) - 1'.
+
+ First build:
+ 1) u <-- '__mf_elem->high'
+ 2) v <-- '__mf_base + sizeof (T) - 1'.
+
+ Then build 'u <-- (u < v). */
+
+
+ u = build (COMPONENT_REF, mf_uintptr_type,
+ build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
+ TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
+
+ v = convert (mf_uintptr_type,
+ size_binop (MINUS_EXPR, size, size_one_node));
+ v = fold (build (PLUS_EXPR, mf_uintptr_type, mf_base, v));
+
+ u = build (LT_EXPR, boolean_type_node, u, v);
+
+ /* Build the composed conditional: t <-- 't || u'. Then store the
+ result of the evaluation of 't' in a temporary variable which we
+ can use as the condition for the conditional jump. */
+ t = build (TRUTH_OR_EXPR, boolean_type_node, t, u);
+ cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
+ t = build (MODIFY_EXPR, boolean_type_node, cond, t);
+ gimplify_to_stmt_list (&t);
+ tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+
+ /* Build the conditional jump. 'cond' is just a temporary so we can
+ simply build a void COND_EXPR. We do need labels in both arms though. */
+ t = build (COND_EXPR, void_type_node, cond,
+ build (GOTO_EXPR, void_type_node, tree_block_label (then_bb)),
+ build (GOTO_EXPR, void_type_node, tree_block_label (join_bb)));
+ SET_EXPR_LOCUS (t, locus);
+ tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+
+ /* At this point, after so much hard work, we have only constructed
+ the conditional jump,
+
+ if (__mf_elem->low > __mf_base
+ || (__mf_elem_high < __mf_base + sizeof(T) - 1))
+
+ The lowered GIMPLE tree representing this code is in the statement
+ list starting at 'head'.
+
+ We can insert this now in the current basic block, ie. the one that
+ the statement we're instrumenting was originally in. */
+ bsi = bsi_last (cond_bb);
+ for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
+ bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
+
+ /* Now build up the body of the cache-miss handling:
+
+ __mf_check();
+ refresh *_l vars.
+
+ This is the body of the conditional. */
+
+ u = tree_cons (NULL_TREE,
+ mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION
+ : *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);
+ gimplify_to_stmt_list (&t);
+ head = tsi_start (t);
+ tsi = tsi_last (t);
+
+ if (! flag_mudflap_threads)
+ {
+ t = build (MODIFY_EXPR, void_type_node,
+ mf_cache_shift_decl_l, mf_cache_shift_decl);
+ tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+
+ t = build (MODIFY_EXPR, void_type_node,
+ mf_cache_mask_decl_l, mf_cache_mask_decl);
+ tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ }
+
+ /* Insert the check code in the THEN block. */
+ bsi = bsi_start (then_bb);
+ for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
+ bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
+
+ *instr_bsi = bsi_start (join_bb);
+ bsi_next (instr_bsi);
+}
+
+static void
+mf_xform_derefs_1 (block_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
+ || (! TYPE_MIN_VALUE (dom)
+ || ! really_constant_p (TYPE_MIN_VALUE (dom)))
+ || (! TYPE_MAX_VALUE (dom)
+ || ! really_constant_p (TYPE_MAX_VALUE (dom)))
+ || (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))
+ {
+ if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
+ size = DECL_SIZE_UNIT (field);
+
+ addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+ addr = fold_convert (ptr_type_node, addr);
+ addr = fold (build (PLUS_EXPR, ptr_type_node,
+ addr, fold_convert (ptr_type_node,
+ 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 (void)
+{
+ basic_block bb, next;
+ block_stmt_iterator i;
+ int saved_last_basic_block = last_basic_block;
+
+ bb = ENTRY_BLOCK_PTR ->next_bb;
+ do
+ {
+ next = bb->next_bb;
+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ {
+ tree s = bsi_stmt (i);
+
+ /* Only a few GIMPLE statements can reference memory. */
+ switch (TREE_CODE (s))
+ {
+ case MODIFY_EXPR:
+ 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:
+ ;
+ }
+ }
+ bb = next;
+ }
+ while (bb && bb->index <= saved_last_basic_block);
+}
+
+/* ------------------------------------------------------------------------ */
+/* ADDR_EXPR transforms. Perform the declaration-related mudflap tree
+ transforms on the current function.
+
+ This is the first part of the mudflap instrumentation. It works on
+ high-level GIMPLE because after lowering, all variables are moved out
+ of their BIND_EXPR binding context, and we lose liveness information
+ for the declarations we wish to instrument. */
+
+static void
+execute_mudflap_function_decls (void)
+{
+ if (mf_marked_p (current_function_decl))
+ return;
+
+ push_gimplify_context ();
+
+ mf_xform_decls (DECL_SAVED_TREE (current_function_decl),
+ DECL_ARGUMENTS (current_function_decl));
+
+ pop_gimplify_context (NULL);
+}
+
+/* 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)
+ /* It must be a non-external, automatic variable. */
+ && ! DECL_EXTERNAL (decl)
+ && ! TREE_STATIC (decl)
+ /* The decl must have its address taken. */
+ && TREE_ADDRESSABLE (decl)
+ /* The type of the variable must be complete. */
+ && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
+ /* Don't process the same decl twice. */
+ && ! mf_marked_p (decl))
+ {
+ 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 gimplify_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), __MF_TYPE_STACK) */
+ 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,
+ tree_cons (NULL_TREE,
+ build_int_2 (3, 0), /* __MF_TYPE_STACK */
+ NULL_TREE)));
+ /* __mf_unregister (...) */
+ unregister_fncall = build_function_call_expr (mf_unregister_fndecl,
+ unregister_fncall_params);
+
+ /* (& VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK, "name") */
+ 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_LOCATION. */
+ 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);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* Externally visible mudflap functions. */
+
+
+/* Mark and return the given tree node to prevent further mudflap
+ transforms. */
+static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
+
+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);
+}
+
+/* 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);
+
+ 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);
+ }
+
+ if (enqueued_call_stmt_chain)
+ {
+ cgraph_build_static_cdtor ('I', enqueued_call_stmt_chain);
+ enqueued_call_stmt_chain = 0;
+ }
+}
+
+
+static bool
+gate_mudflap (void)
+{
+ return flag_mudflap != 0;
+}
+
+struct tree_opt_pass pass_mudflap_1 =
+{
+ "mudflap1", /* name */
+ gate_mudflap, /* gate */
+ execute_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 */
+};
+
+struct tree_opt_pass pass_mudflap_2 =
+{
+ "mudflap2", /* name */
+ gate_mudflap, /* gate */
+ execute_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_verify_flow | TODO_verify_stmts
+ | TODO_dump_func /* todo_flags_finish */
+};
+
+#include "gt-tree-mudflap.h"
diff --git a/gcc/tree-mudflap.h b/gcc/tree-mudflap.h
new file mode 100644
index 00000000000..554bf6263f9
--- /dev/null
+++ b/gcc/tree-mudflap.h
@@ -0,0 +1,37 @@
+/* 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_init (void);
+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);
+
+#endif /* TREE_MUDFLAP_H */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
new file mode 100644
index 00000000000..fdcaaf82436
--- /dev/null
+++ b/gcc/tree-nested.c
@@ -0,0 +1,1419 @@
+/* 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 of variable size 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_ADDRESSABLE (type)
+ || (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;
+ DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
+ 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) == REALPART_EXPR || TREE_CODE (base) == IMAGPART_EXPR
+ || handled_component_p (base))
+ 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.
+ Note also that it's represented as a parameter. This is more
+ close to the truth, since the initial value does come from
+ the caller. */
+ decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type);
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ TREE_USED (decl) = 1;
+ DECL_CONTEXT (decl) = info->context;
+ DECL_ARG_TYPE (decl) = type;
+
+ /* 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 controlled 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));
+ break;
+ 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, NULL_TREE);
+ 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, NULL_TREE);
+ 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, NULL_TREE);
+ 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 REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case BIT_FIELD_REF:
+ /* Go down this entire nest and just look at the final prefix and
+ anything that describes the references. Otherwise, we lose track
+ of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */
+ wi->val_only = true;
+ for (; handled_component_p (t)
+ || TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR;
+ tp = &TREE_OPERAND (t, 0), t = *tp)
+ {
+ if (TREE_CODE (t) == COMPONENT_REF)
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
+ NULL);
+ else if (TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == ARRAY_RANGE_REF)
+ {
+ walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
+ NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
+ NULL);
+ walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi,
+ NULL);
+ }
+ else if (TREE_CODE (t) == BIT_FIELD_REF)
+ {
+ walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
+ NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
+ NULL);
+ }
+ }
+ wi->val_only = false;
+ walk_tree (tp, 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 REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case BIT_FIELD_REF:
+ /* Go down this entire nest and just look at the final prefix and
+ anything that describes the references. Otherwise, we lose track
+ of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */
+ wi->val_only = true;
+ for (; handled_component_p (t)
+ || TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR;
+ tp = &TREE_OPERAND (t, 0), t = *tp)
+ {
+ if (TREE_CODE (t) == COMPONENT_REF)
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
+ NULL);
+ else if (TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == ARRAY_RANGE_REF)
+ {
+ walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi,
+ NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
+ NULL);
+ walk_tree (&TREE_OPERAND (t, 3), convert_local_reference, wi,
+ NULL);
+ }
+ else if (TREE_CODE (t) == BIT_FIELD_REF)
+ {
+ walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi,
+ NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
+ NULL);
+ }
+ }
+ wi->val_only = false;
+ walk_tree (tp, 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 behavior 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, NULL_TREE);
+ 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 = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
+ root->frame_decl, root->chain_field, NULL_TREE);
+ 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, NULL_TREE);
+ 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 inserted 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..761bb03c94a
--- /dev/null
+++ b/gcc/tree-nrv.c
@@ -0,0 +1,218 @@
+/* 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 occurrences
+ 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, set the expression being returned to RESULT. */
+ else if (TREE_CODE (*tp) == RETURN_EXPR)
+ TREE_OPERAND (*tp, 0) = dp->result;
+
+ /* Otherwise replace all occurrences 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-outof-ssa.c b/gcc/tree-outof-ssa.c
new file mode 100644
index 00000000000..d1899981c1f
--- /dev/null
+++ b/gcc/tree-outof-ssa.c
@@ -0,0 +1,2223 @@
+/* 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_use_variable (var_map, use_operand_p, tree *);
+static bool replace_def_variable (var_map, def_operand_p, 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 = PHI_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 = PHI_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 = PHI_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 use operand 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_use_variable (var_map map, use_operand_p p, tree *expr)
+{
+ tree new_var;
+ tree var = USE_FROM_PTR (p);
+
+ /* Check if we are replacing this variable with an expression. */
+ if (expr)
+ {
+ int version = SSA_NAME_VERSION (var);
+ if (expr[version])
+ {
+ tree new_expr = TREE_OPERAND (expr[version], 1);
+ SET_USE (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)
+ {
+ SET_USE (p, new_var);
+ set_is_used (new_var);
+ return true;
+ }
+ return false;
+}
+
+
+/* Replace def operand DEF_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 DEF_P with an expression instead of a
+ variable. If the stmt is changed, return true. */
+
+static inline bool
+replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
+{
+ tree new_var;
+ tree var = DEF_FROM_PTR (def_p);
+
+ /* Check if we are replacing this variable with an expression. */
+ if (expr)
+ {
+ int version = SSA_NAME_VERSION (var);
+ if (expr[version])
+ {
+ tree new_expr = TREE_OPERAND (expr[version], 1);
+ SET_DEF (def_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)
+ {
+ SET_DEF (def_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 = PHI_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 = PHI_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 V_MAY_DEF 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. */
+
+
+/* Dependency 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 dependency on V_MAY_DEFs. */
+#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 (num_ssa_names + 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 dependency between the def of ssa VERSION and VAR. If VAR is
+ replaceable by an expression, add a dependence 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 V_MAY_DEFS. */
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0)
+ return false;
+
+ /* There must be no V_MUST_DEFS. */
+ if (NUM_V_MUST_DEFS (V_MUST_DEF_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 dependency 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 dependence
+ 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 dependency 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 dependent 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 dependent 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 dependency lists. */
+ while ((p = tab->pending_dependence))
+ {
+ tab->pending_dependence = p->next;
+ free_value_expr (tab, p);
+ }
+
+ /* A V_MAY_DEF kills any expression using a virtual operand. */
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0)
+ kill_virtual_exprs (tab, true);
+
+ /* A V_MUST_DEF kills any expression using a virtual operand. */
+ if (NUM_V_MUST_DEFS (V_MUST_DEF_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)num_ssa_names + 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 || TREE_CODE (t) == ARRAY_RANGE_REF)
+ {
+ while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
+ && is_gimple_min_invariant (TREE_OPERAND (t, 1))
+ && (!TREE_OPERAND (t, 2)
+ || is_gimple_min_invariant (TREE_OPERAND (t, 2))))
+ || (TREE_CODE (t) == COMPONENT_REF
+ && (!TREE_OPERAND (t,2)
+ || is_gimple_min_invariant (TREE_OPERAND (t, 2))))
+ || TREE_CODE (t) == BIT_FIELD_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR
+ || TREE_CODE (t) == VIEW_CONVERT_EXPR
+ || TREE_CODE (t) == NOP_EXPR
+ || TREE_CODE (t) == CONVERT_EXPR)
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_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 = PHI_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);
+ use_operand_p use_p;
+ 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_use_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++)
+ {
+ def_operand_p def_p = DEF_OP_PTR (defs, i);
+
+ if (replace_def_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
+ && (DEF_FROM_PTR (def_p) == USE_OP (uses, 0)))
+ 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 = PHI_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 = PHI_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. */
+ SET_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 (num_ssa_names + 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..276de395bd1
--- /dev/null
+++ b/gcc/tree-pass.h
@@ -0,0 +1,139 @@
+/* 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)
+#define PROP_rtl (1 << 8)
+
+#define PROP_trees \
+ (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh)
+
+/* 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_loop_init;
+extern struct tree_opt_pass pass_loop_done;
+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;
+extern struct tree_opt_pass pass_expand;
+extern struct tree_opt_pass pass_rest_of_compilation;
+extern struct tree_opt_pass pass_fre;
+
+
+#endif /* GCC_TREE_PASS_H */
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
new file mode 100644
index 00000000000..dc2a2294e7f
--- /dev/null
+++ b/gcc/tree-phinodes.c
@@ -0,0 +1,528 @@
+/* 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] = PHI_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)
+ SET_PHI_RESULT (phi, var);
+ else
+ SET_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;
+ PHI_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] = PHI_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++)
+ {
+ SET_PHI_ARG_DEF (new_phi, i, NULL_TREE);
+ PHI_ARG_EDGE (new_phi, i) = NULL;
+ PHI_ARG_NONZERO (new_phi, i) = false;
+ }
+
+ *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. */
+ PHI_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 && PHI_CHAIN (p) != old_phi;
+ p = PHI_CHAIN (p))
+ ;
+
+ if (!p)
+ abort ();
+
+ PHI_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;
+ }
+
+ SET_PHI_ARG_DEF (*phi, i, def);
+ PHI_ARG_EDGE (*phi, i) = e;
+ PHI_ARG_NONZERO (*phi, i) = false;
+ 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)
+ {
+ SET_PHI_ARG_DEF (phi, i, PHI_ARG_DEF (phi, num_elem - 1));
+ PHI_ARG_EDGE (phi, i) = PHI_ARG_EDGE (phi, num_elem - 1);
+ PHI_ARG_NONZERO (phi, i) = PHI_ARG_NONZERO (phi, num_elem - 1);
+ }
+
+ /* Shrink the vector and return. */
+ SET_PHI_ARG_DEF (phi, num_elem - 1, NULL_TREE);
+ PHI_ARG_EDGE (phi, num_elem - 1) = NULL;
+ PHI_ARG_NONZERO (phi, num_elem - 1) = false;
+ 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. */
+ PHI_CHAIN (prev) = PHI_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 = PHI_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 = PHI_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 = PHI_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
+ {
+ PHI_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)
+ PHI_CHAIN (last_phi) = NULL_TREE;
+ bb_ann (bb)->phi_nodes = new_phi_list;
+
+#if defined ENABLE_CHECKING
+ for (phi = phi_nodes (bb); phi; phi = PHI_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..743524f481e
--- /dev/null
+++ b/gcc/tree-pretty-print.c
@@ -0,0 +1,2279 @@
+/* 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))
+
+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 a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
+ FLAGS are as in dump_generic_node. */
+
+static void
+dump_function_declaration (pretty_printer *buffer, tree node,
+ int spc, int flags)
+{
+ bool wrote_arg = false;
+ tree arg;
+
+ pp_space (buffer);
+ pp_character (buffer, '(');
+
+ /* Print the argument types. The last element in the list is a VOID_TYPE.
+ The following avoids printing the last element. */
+ arg = TYPE_ARG_TYPES (node);
+ while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
+ {
+ wrote_arg = true;
+ dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
+ arg = TREE_CHAIN (arg);
+ if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+ }
+
+ if (!wrote_arg)
+ pp_string (buffer, "void");
+
+ pp_character (buffer, ')');
+}
+
+/* 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))
+ {
+ expanded_location xloc = expand_location (EXPR_LOCATION (node));
+ pp_character (buffer, '[');
+ if (xloc.file)
+ {
+ pp_string (buffer, xloc.file);
+ pp_string (buffer, " : ");
+ }
+ pp_decimal_int (buffer, xloc.line);
+ 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, ')');
+ dump_function_declaration (buffer, fnode, spc, flags);
+ }
+ 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 innermost component type. */
+ for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
+ tmp = TREE_TYPE (tmp))
+ ;
+ dump_generic_node (buffer, tmp, spc, flags, false);
+
+ /* Print the dimensions. */
+ for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
+ tmp = TREE_TYPE (tmp))
+ {
+ tree domain = TYPE_DOMAIN (tmp);
+
+ pp_character (buffer, '[');
+ if (domain)
+ {
+ if (TYPE_MIN_VALUE (domain)
+ && !integer_zerop (TYPE_MIN_VALUE (domain)))
+ {
+ dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
+ spc, flags, false);
+ pp_string (buffer, " .. ");
+ }
+
+ if (TYPE_MAX_VALUE (domain))
+ dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
+ spc, flags, false);
+ }
+ else
+ pp_string (buffer, "<unknown>");
+
+ pp_character (buffer, ']');
+ }
+ break;
+ }
+
+ case SET_TYPE:
+ NIY;
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_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 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 (DECL_IS_BUILTIN (node))
+ {
+ /* Don't print the declaration of built-in types. */
+ break;
+ }
+ if (DECL_NAME (node))
+ dump_decl_name (buffer, node, flags);
+ else
+ {
+ if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
+ && 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,
+ (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
+ ? "union" : "struct "));
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+ }
+ }
+ 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);
+
+ op0 = component_ref_field_offset (node);
+ if (op0 && TREE_CODE (op0) != INTEGER_CST)
+ {
+ pp_string (buffer, "{off: ");
+ dump_generic_node (buffer, op0, spc, flags, false);
+ pp_character (buffer, '}');
+ }
+ 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 ARRAY_REF:
+ case ARRAY_RANGE_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);
+ if (TREE_CODE (node) == ARRAY_RANGE_REF)
+ pp_string (buffer, " ...");
+ pp_character (buffer, ']');
+
+ op0 = array_ref_low_bound (node);
+ op1 = array_ref_element_size (node);
+
+ if (!integer_zerop (op0)
+ || (TYPE_SIZE_UNIT (TREE_TYPE (node))
+ && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
+ {
+ pp_string (buffer, "{lb: ");
+ dump_generic_node (buffer, op0, spc, flags, false);
+ pp_string (buffer, " sz: ");
+ dump_generic_node (buffer, op1, spc, flags, false);
+ pp_character (buffer, '}');
+ }
+ 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:
+ pp_string (buffer, "TARGET_EXPR <");
+ dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case DECL_EXPR:
+ print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
+ is_stmt = false;
+ break;
+
+ case COND_EXPR:
+ if (TREE_TYPE (node) == NULL || 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:
+ pp_string (buffer, "<PLACEHOLDER_EXPR ");
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+ pp_character (buffer, '>');
+ 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:
+ case LTGT_EXPR:
+ case ORDERED_EXPR:
+ case UNORDERED_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 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 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 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 OBJ_TYPE_REF:
+ pp_string (buffer, "OBJ_TYPE_REF(");
+ dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
+ pp_character (buffer, ';');
+ dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
+ pp_character (buffer, '-');
+ pp_character (buffer, '>');
+ dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
+ pp_character (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;
+
+ case VALUE_HANDLE:
+ pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (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)
+{
+ INDENT (spc);
+
+ if (TREE_CODE (t) == TYPE_DECL)
+ pp_string (buffer, "typedef ");
+
+ 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 if (TREE_CODE (t) == FUNCTION_DECL)
+ {
+ dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
+ pp_space (buffer);
+ dump_decl_name (buffer, t, flags);
+ dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
+ }
+ 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
+ || TREE_CODE (node) == QUAL_UNION_TYPE))
+ pp_string (buffer, "union ");
+
+ 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);
+ }
+ 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 UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case LTGT_EXPR:
+ case ORDERED_EXPR:
+ case UNORDERED_EXPR:
+ 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 ARRAY_RANGE_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 ORDERED_EXPR:
+ return "ord";
+ case UNORDERED_EXPR:
+ return "unord";
+
+ case EQ_EXPR:
+ return "==";
+ case UNEQ_EXPR:
+ return "u==";
+
+ case NE_EXPR:
+ return "!=";
+
+ case LT_EXPR:
+ return "<";
+ case UNLT_EXPR:
+ return "u<";
+
+ case LE_EXPR:
+ return "<=";
+ case UNLE_EXPR:
+ return "u<=";
+
+ case GT_EXPR:
+ return ">";
+ case UNGT_EXPR:
+ return "u>";
+
+ case GE_EXPR:
+ return ">=";
+ case UNGE_EXPR:
+ return "u>=";
+
+ case LTGT_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 "++ ";
+
+ 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:
+ case OBJ_TYPE_REF:
+ 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);
+ v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
+ vuse_optype vuses = VUSE_OPS (ann);
+
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ pp_string (buffer, "# ");
+ dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
+ spc + 2, flags, false);
+ pp_string (buffer, " = V_MAY_DEF <");
+ dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
+ spc + 2, flags, false);
+ pp_string (buffer, ">;");
+ newline_and_indent (buffer, spc);
+ }
+
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+ pp_string (buffer, "# V_MUST_DEF <");
+ dump_generic_node (buffer, v_must_def, 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 = PHI_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,
+ int flags)
+{
+ 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);
+
+ if ((flags & TDF_LINENO)
+#ifdef USE_MAPPED_LOCATION
+ && e->goto_locus != UNKNOWN_LOCATION
+#else
+ && e->goto_locus
+#endif
+ )
+ {
+ expanded_location goto_xloc;
+#ifdef USE_MAPPED_LOCATION
+ goto_xloc = expand_location (e->goto_locus);
+#else
+ goto_xloc = *e->goto_locus;
+#endif
+ pp_character (buffer, '[');
+ if (goto_xloc.file)
+ {
+ pp_string (buffer, goto_xloc.file);
+ pp_string (buffer, " : ");
+ }
+ pp_decimal_int (buffer, goto_xloc.line);
+ pp_string (buffer, "] ");
+ }
+
+ 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, flags);
+
+ 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..2e2e85a812a
--- /dev/null
+++ b/gcc/tree-sra.c
@@ -0,0 +1,2023 @@
+/* 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"
+#include "obstack.h"
+#include "target.h"
+/* expr.h is needed for MOVE_RATIO. */
+#include "expr.h"
+
+
+/* This object of this pass is to replace a non-addressable aggregate with a
+ set of independent variables. Most of the time, all of these variables
+ will be scalars. But a secondary objective is to break up larger
+ aggregates into smaller aggregates. In the process we may find that some
+ bits of the larger aggregate can be deleted as unreferenced.
+
+ This substitution is done globally. More localized substitutions would
+ be the purvey of a load-store motion pass.
+
+ The optimization proceeds in phases:
+
+ (1) Identify variables that have types that are candidates for
+ decomposition.
+
+ (2) Scan the function looking for the ways these variables are used.
+ In particular we're interested in the number of times a variable
+ (or member) is needed as a complete unit, and the number of times
+ a variable (or member) is copied.
+
+ (3) Based on the usage profile, instantiate substitution variables.
+
+ (4) Scan the function making replacements.
+*/
+
+
+/* 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;
+
+/* Sets of bit pairs that cache type decomposition and instantiation. */
+static bitmap sra_type_decomp_cache;
+static bitmap sra_type_inst_cache;
+
+/* One of these structures is created for each candidate aggregate
+ and each (accessed) member of such an aggregate. */
+struct sra_elt
+{
+ /* A tree of the elements. Used when we want to traverse everything. */
+ struct sra_elt *parent;
+ struct sra_elt *children;
+ struct sra_elt *sibling;
+
+ /* If this element is a root, then this is the VAR_DECL. If this is
+ a sub-element, this is some token used to identify the reference.
+ In the case of COMPONENT_REF, this is the FIELD_DECL. In the case
+ of an ARRAY_REF, this is the (constant) index. In the case of a
+ complex number, this is a zero or one. */
+ tree element;
+
+ /* The type of the element. */
+ tree type;
+
+ /* A VAR_DECL, for any sub-element we've decided to replace. */
+ tree replacement;
+
+ /* The number of times the element is referenced as a whole. I.e.
+ given "a.b.c", this would be incremented for C, but not for A or B. */
+ unsigned int n_uses;
+
+ /* The number of times the element is copied to or from another
+ scalarizable element. */
+ unsigned int n_copies;
+
+ /* True if TYPE is scalar. */
+ bool is_scalar;
+
+ /* True if we saw something about this element that prevents scalarization,
+ such as non-constant indexing. */
+ bool cannot_scalarize;
+
+ /* True if we've decided that structure-to-structure assignment
+ should happen via memcpy and not per-element. */
+ bool use_block_copy;
+
+ /* A flag for use with/after random access traversals. */
+ bool visited;
+};
+
+/* Random access to the child of a parent is performed by hashing.
+ This prevents quadratic behaviour, and allows SRA to function
+ reasonably on larger records. */
+static htab_t sra_map;
+
+/* All structures are allocated out of the following obstack. */
+static struct obstack sra_obstack;
+
+/* Debugging functions. */
+static void dump_sra_elt_name (FILE *, struct sra_elt *);
+extern void debug_sra_elt_name (struct sra_elt *);
+
+
+/* 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 TYPE is a scalar type. */
+
+static bool
+is_sra_scalar_type (tree type)
+{
+ enum tree_code code = TREE_CODE (type);
+ return (code == INTEGER_TYPE || code == REAL_TYPE || code == VECTOR_TYPE
+ || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
+ || code == CHAR_TYPE || code == POINTER_TYPE || code == OFFSET_TYPE
+ || code == REFERENCE_TYPE);
+}
+
+/* Return true if TYPE can be decomposed into a set of independent variables.
+
+ Note that this doesn't imply that all elements of TYPE can be
+ instantiated, just that if we decide to break up the type into
+ separate pieces that it can be done. */
+
+static bool
+type_can_be_decomposed_p (tree type)
+{
+ unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
+ tree t;
+
+ /* Avoid searching the same type twice. */
+ if (bitmap_bit_p (sra_type_decomp_cache, cache+0))
+ return true;
+ if (bitmap_bit_p (sra_type_decomp_cache, cache+1))
+ return false;
+
+ /* The type must have a definite non-zero size. */
+ if (TYPE_SIZE (type) == NULL || integer_zerop (TYPE_SIZE (type)))
+ goto fail;
+
+ /* The type must be a non-union aggregate. */
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ {
+ bool saw_one_field = false;
+
+ for (t = TYPE_FIELDS (type); t ; t = TREE_CHAIN (t))
+ if (TREE_CODE (t) == FIELD_DECL)
+ {
+ /* Reject incorrectly represented bit fields. */
+ if (DECL_BIT_FIELD (t)
+ && (tree_low_cst (DECL_SIZE (t), 1)
+ != TYPE_PRECISION (TREE_TYPE (t))))
+ goto fail;
+
+ saw_one_field = true;
+ }
+
+ /* Record types must have at least one field. */
+ if (!saw_one_field)
+ goto fail;
+ }
+ break;
+
+ case ARRAY_TYPE:
+ /* Array types must have a fixed lower and upper bound. */
+ t = TYPE_DOMAIN (type);
+ if (t == NULL)
+ goto fail;
+ if (TYPE_MIN_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MIN_VALUE (t)))
+ goto fail;
+ if (TYPE_MAX_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MAX_VALUE (t)))
+ goto fail;
+ break;
+
+ case COMPLEX_TYPE:
+ break;
+
+ default:
+ goto fail;
+ }
+
+ bitmap_set_bit (sra_type_decomp_cache, cache+0);
+ return true;
+
+ fail:
+ bitmap_set_bit (sra_type_decomp_cache, cache+1);
+ return false;
+}
+
+/* Return true if DECL can be decomposed into a set of independent
+ (though not necessarily scalar) variables. */
+
+static bool
+decl_can_be_decomposed_p (tree var)
+{
+ /* Early out for scalars. */
+ if (is_sra_scalar_type (TREE_TYPE (var)))
+ return false;
+
+ /* The variable must not be aliased. */
+ 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;
+ }
+
+ /* The variable must not be volatile. */
+ 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;
+ }
+
+ /* We must be able to decompose the variable's type. */
+ if (!type_can_be_decomposed_p (TREE_TYPE (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 its type cannot be decomposed\n");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+/* Return true if TYPE can be *completely* decomposed into scalars. */
+
+static bool
+type_can_instantiate_all_elements (tree type)
+{
+ if (is_sra_scalar_type (type))
+ return true;
+ if (!type_can_be_decomposed_p (type))
+ return false;
+
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ {
+ unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
+ tree f;
+
+ if (bitmap_bit_p (sra_type_inst_cache, cache+0))
+ return true;
+ if (bitmap_bit_p (sra_type_inst_cache, cache+1))
+ return false;
+
+ for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ if (!type_can_instantiate_all_elements (TREE_TYPE (f)))
+ {
+ bitmap_set_bit (sra_type_inst_cache, cache+1);
+ return false;
+ }
+ }
+
+ bitmap_set_bit (sra_type_inst_cache, cache+0);
+ return true;
+ }
+
+ case ARRAY_TYPE:
+ return type_can_instantiate_all_elements (TREE_TYPE (type));
+
+ case COMPLEX_TYPE:
+ return true;
+
+ default:
+ abort ();
+ }
+}
+
+/* Test whether ELT or some sub-element cannot be scalarized. */
+
+static bool
+can_completely_scalarize_p (struct sra_elt *elt)
+{
+ struct sra_elt *c;
+
+ if (elt->cannot_scalarize)
+ return false;
+
+ for (c = elt->children; c ; c = c->sibling)
+ if (!can_completely_scalarize_p (c))
+ return false;
+
+ return true;
+}
+
+
+/* A simplified tree hashing algorithm that only handles the types of
+ trees we expect to find in sra_elt->element. */
+
+static hashval_t
+sra_hash_tree (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case FIELD_DECL:
+ return DECL_UID (t);
+ case INTEGER_CST:
+ return TREE_INT_CST_LOW (t) ^ TREE_INT_CST_HIGH (t);
+ default:
+ abort ();
+ }
+}
+
+/* Hash function for type SRA_PAIR. */
+
+static hashval_t
+sra_elt_hash (const void *x)
+{
+ const struct sra_elt *e = x;
+ const struct sra_elt *p;
+ hashval_t h;
+
+ h = sra_hash_tree (e->element);
+
+ /* Take into account everything back up the chain. Given that chain
+ lengths are rarely very long, this should be acceptable. If we
+ truely identify this as a performance problem, it should work to
+ hash the pointer value "e->parent". */
+ for (p = e->parent; p ; p = p->parent)
+ h = (h * 65521) ^ sra_hash_tree (p->element);
+
+ return h;
+}
+
+/* Equality function for type SRA_PAIR. */
+
+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->parent != b->parent)
+ return false;
+
+ /* All the field/decl stuff is unique. */
+ if (a->element == b->element)
+ return true;
+
+ /* The only thing left is integer equality. */
+ if (TREE_CODE (a->element) == INTEGER_CST
+ && TREE_CODE (b->element) == INTEGER_CST)
+ return tree_int_cst_equal (a->element, b->element);
+ else
+ return false;
+}
+
+/* Create or return the SRA_ELT structure for CHILD in PARENT. PARENT
+ may be null, in which case CHILD must be a DECL. */
+
+static struct sra_elt *
+lookup_element (struct sra_elt *parent, tree child, tree type,
+ enum insert_option insert)
+{
+ struct sra_elt dummy;
+ struct sra_elt **slot;
+ struct sra_elt *elt;
+
+ dummy.parent = parent;
+ dummy.element = child;
+
+ slot = (struct sra_elt **) htab_find_slot (sra_map, &dummy, insert);
+ if (!slot && insert == NO_INSERT)
+ return NULL;
+
+ elt = *slot;
+ if (!elt && insert == INSERT)
+ {
+ *slot = elt = obstack_alloc (&sra_obstack, sizeof (*elt));
+ memset (elt, 0, sizeof (*elt));
+
+ elt->parent = parent;
+ elt->element = child;
+ elt->type = type;
+ elt->is_scalar = is_sra_scalar_type (type);
+
+ if (parent)
+ {
+ elt->sibling = parent->children;
+ parent->children = elt;
+ }
+
+ /* If this is a parameter, then if we want to scalarize, we have
+ one copy from the true function parameter. Count it now. */
+ if (TREE_CODE (child) == PARM_DECL)
+ {
+ elt->n_copies = 1;
+ bitmap_set_bit (needs_copy_in, var_ann (child)->uid);
+ }
+ }
+
+ return elt;
+}
+
+/* Return true if the ARRAY_REF in EXPR is a constant, in bounds access. */
+
+static bool
+is_valid_const_index (tree expr)
+{
+ tree dom, t, index = TREE_OPERAND (expr, 1);
+
+ if (TREE_CODE (index) != INTEGER_CST)
+ return false;
+
+ /* Watch out for stupid user tricks, indexing outside the array.
+
+ Careful, we're not called only on scalarizable types, so do not
+ assume constant array bounds. We needn't do anything with such
+ cases, since they'll be referring to objects that we should have
+ already rejected for scalarization, so returning false is fine. */
+
+ dom = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ if (dom == NULL)
+ return false;
+
+ t = TYPE_MIN_VALUE (dom);
+ if (!t || TREE_CODE (t) != INTEGER_CST)
+ return false;
+ if (tree_int_cst_lt (index, t))
+ return false;
+
+ t = TYPE_MAX_VALUE (dom);
+ if (!t || TREE_CODE (t) != INTEGER_CST)
+ return false;
+ if (tree_int_cst_lt (t, index))
+ return false;
+
+ return true;
+}
+
+/* Create or return the SRA_ELT structure for EXPR if the expression
+ refers to a scalarizable variable. */
+
+static struct sra_elt *
+maybe_lookup_element_for_expr (tree expr)
+{
+ struct sra_elt *elt;
+ tree child;
+
+ switch (TREE_CODE (expr))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ if (is_sra_candidate_decl (expr))
+ return lookup_element (NULL, expr, TREE_TYPE (expr), INSERT);
+ return NULL;
+
+ case ARRAY_REF:
+ /* We can't scalarize variable array indicies. */
+ if (is_valid_const_index (expr))
+ child = TREE_OPERAND (expr, 1);
+ else
+ return NULL;
+ break;
+
+ case COMPONENT_REF:
+ /* Don't look through unions. */
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) != RECORD_TYPE)
+ return NULL;
+ child = TREE_OPERAND (expr, 1);
+ break;
+
+ case REALPART_EXPR:
+ child = integer_zero_node;
+ break;
+ case IMAGPART_EXPR:
+ child = integer_one_node;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ elt = maybe_lookup_element_for_expr (TREE_OPERAND (expr, 0));
+ if (elt)
+ return lookup_element (elt, child, TREE_TYPE (expr), INSERT);
+ return NULL;
+}
+
+
+/* Functions to walk just enough of the tree to see all scalarizable
+ references, and categorize them. */
+
+/* A set of callbacks for phases 2 and 4. They'll be invoked for the
+ various kinds of references seen. In all cases, *BSI is an iterator
+ pointing to the statement being processed. */
+struct sra_walk_fns
+{
+ /* Invoked when ELT is required as a unit. Note that ELT might refer to
+ a leaf node, in which case this is a simple scalar reference. *EXPR_P
+ points to the location of the expression. IS_OUTPUT is true if this
+ is a left-hand-side reference. */
+ void (*use) (struct sra_elt *elt, tree *expr_p,
+ block_stmt_iterator *bsi, bool is_output);
+
+ /* Invoked when we have a copy between two scalarizable references. */
+ void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
+ block_stmt_iterator *bsi);
+
+ /* Invoked when ELT is initialized from a constant. VALUE may be NULL,
+ in which case it should be treated as an empty CONSTRUCTOR. */
+ void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
+
+ /* Invoked when we have a copy between one scalarizable reference ELT
+ and one non-scalarizable reference OTHER. IS_OUTPUT is true if ELT
+ is on the left-hand side. */
+ void (*ldst) (struct sra_elt *elt, tree other,
+ block_stmt_iterator *bsi, bool is_output);
+
+ /* True during phase 2, false during phase 4. */
+ /* ??? This is a hack. */
+ bool initial_scan;
+};
+
+#ifdef ENABLE_CHECKING
+/* Invoked via walk_tree, if *TP contains an candidate decl, return it. */
+
+static tree
+sra_find_candidate_decl (tree *tp, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+ enum tree_code code = TREE_CODE (t);
+
+ if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
+ {
+ *walk_subtrees = 0;
+ if (is_sra_candidate_decl (t))
+ return t;
+ }
+ else if (TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+#endif
+
+/* Walk most expressions looking for a scalarizable aggregate.
+ If we find one, invoke FNS->USE. */
+
+static void
+sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
+ const struct sra_walk_fns *fns)
+{
+ tree expr = *expr_p;
+ tree inner = expr;
+ bool disable_scalarization = false;
+
+ /* We're looking to collect a reference expression between EXPR and INNER,
+ such that INNER is a scalarizable decl and all other nodes through EXPR
+ are references that we can scalarize. If we come across something that
+ we can't scalarize, we reset EXPR. This has the effect of making it
+ appear that we're referring to the larger expression as a whole. */
+
+ while (1)
+ switch (TREE_CODE (inner))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ /* If there is a scalarizable decl at the bottom, then process it. */
+ if (is_sra_candidate_decl (inner))
+ {
+ struct sra_elt *elt = maybe_lookup_element_for_expr (expr);
+ if (disable_scalarization)
+ elt->cannot_scalarize = true;
+ else
+ fns->use (elt, expr_p, bsi, is_output);
+ }
+ return;
+
+ case ARRAY_REF:
+ /* Non-constant index means any member may be accessed. Prevent the
+ expression from being scalarized. If we were to treat this as a
+ reference to the whole array, we can wind up with a single dynamic
+ index reference inside a loop being overridden by several constant
+ index references during loop setup. It's possible that this could
+ be avoided by using dynamic usage counts based on BB trip counts
+ (based on loop analysis or profiling), but that hardly seems worth
+ the effort. */
+ /* ??? Hack. Figure out how to push this into the scan routines
+ without duplicating too much code. */
+ if (!is_valid_const_index (inner))
+ {
+ disable_scalarization = true;
+ goto use_all;
+ }
+ /* ??? Are we assured that non-constant bounds and stride will have
+ the same value everywhere? I don't think Fortran will... */
+ if (TREE_OPERAND (inner, 2) || TREE_OPERAND (inner, 3))
+ goto use_all;
+ inner = TREE_OPERAND (inner, 0);
+ break;
+
+ case COMPONENT_REF:
+ /* A reference to a union member constitutes a reference to the
+ entire union. */
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (inner, 0))) != RECORD_TYPE)
+ goto use_all;
+ /* ??? See above re non-constant stride. */
+ if (TREE_OPERAND (inner, 2))
+ goto use_all;
+ inner = TREE_OPERAND (inner, 0);
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ inner = TREE_OPERAND (inner, 0);
+ break;
+
+ case BIT_FIELD_REF:
+ /* A bit field reference (access to *multiple* fields simultaneously)
+ is not currently scalarized. Consider this an access to the
+ complete outer element, to which walk_tree will bring us next. */
+ goto use_all;
+
+ case ARRAY_RANGE_REF:
+ /* Similarly, an subrange reference is used to modify indexing. Which
+ means that the canonical element names that we have won't work. */
+ goto use_all;
+
+ case VIEW_CONVERT_EXPR:
+ case NOP_EXPR:
+ /* Similarly, a view/nop explicitly wants to look at an object in a
+ type other than the one we've scalarized. */
+ goto use_all;
+
+ use_all:
+ expr_p = &TREE_OPERAND (inner, 0);
+ inner = expr = *expr_p;
+ break;
+
+ default:
+#ifdef ENABLE_CHECKING
+ /* Validate that we're not missing any references. */
+ if (walk_tree (&inner, sra_find_candidate_decl, NULL, NULL))
+ abort ();
+#endif
+ return;
+ }
+}
+
+/* Walk a TREE_LIST of values looking for scalarizable aggregates.
+ If we find one, invoke FNS->USE. */
+
+static void
+sra_walk_tree_list (tree list, block_stmt_iterator *bsi, bool is_output,
+ const struct sra_walk_fns *fns)
+{
+ tree op;
+ for (op = list; op ; op = TREE_CHAIN (op))
+ sra_walk_expr (&TREE_VALUE (op), bsi, is_output, fns);
+}
+
+/* Walk the arguments of a CALL_EXPR looking for scalarizable aggregates.
+ If we find one, invoke FNS->USE. */
+
+static void
+sra_walk_call_expr (tree expr, block_stmt_iterator *bsi,
+ const struct sra_walk_fns *fns)
+{
+ sra_walk_tree_list (TREE_OPERAND (expr, 1), bsi, false, fns);
+}
+
+/* Walk the inputs and outputs of an ASM_EXPR looking for scalarizable
+ aggregates. If we find one, invoke FNS->USE. */
+
+static void
+sra_walk_asm_expr (tree expr, block_stmt_iterator *bsi,
+ const struct sra_walk_fns *fns)
+{
+ sra_walk_tree_list (ASM_INPUTS (expr), bsi, false, fns);
+ sra_walk_tree_list (ASM_OUTPUTS (expr), bsi, true, fns);
+}
+
+/* Walk a MODIFY_EXPR and categorize the assignment appropriately. */
+
+static void
+sra_walk_modify_expr (tree expr, block_stmt_iterator *bsi,
+ const struct sra_walk_fns *fns)
+{
+ struct sra_elt *lhs_elt, *rhs_elt;
+ tree lhs, rhs;
+
+ lhs = TREE_OPERAND (expr, 0);
+ rhs = TREE_OPERAND (expr, 1);
+ lhs_elt = maybe_lookup_element_for_expr (lhs);
+ rhs_elt = maybe_lookup_element_for_expr (rhs);
+
+ /* If both sides are scalarizable, this is a COPY operation. */
+ if (lhs_elt && rhs_elt)
+ {
+ fns->copy (lhs_elt, rhs_elt, bsi);
+ return;
+ }
+
+ if (lhs_elt)
+ {
+ /* If this is an assignment from a constant, or constructor, then
+ we have access to all of the elements individually. Invoke INIT. */
+ if (TREE_CODE (rhs) == COMPLEX_EXPR
+ || TREE_CODE (rhs) == COMPLEX_CST
+ || TREE_CODE (rhs) == CONSTRUCTOR)
+ fns->init (lhs_elt, rhs, bsi);
+
+ /* If this is an assignment from read-only memory, treat this as if
+ we'd been passed the constructor directly. Invoke INIT. */
+ else if (TREE_CODE (rhs) == VAR_DECL
+ && TREE_STATIC (rhs)
+ && TREE_READONLY (rhs)
+ && targetm.binds_local_p (rhs))
+ fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);
+
+ /* If this is a copy from a non-scalarizable lvalue, invoke LDST.
+ The lvalue requirement prevents us from trying to directly scalarize
+ the result of a function call. Which would result in trying to call
+ the function multiple times, and other evil things. */
+ else if (!lhs_elt->is_scalar && is_gimple_addr_expr_arg (rhs))
+ fns->ldst (lhs_elt, rhs, bsi, true);
+
+ /* Otherwise we're being used in some context that requires the
+ aggregate to be seen as a whole. Invoke USE. */
+ else
+ fns->use (lhs_elt, &TREE_OPERAND (expr, 0), bsi, true);
+ }
+ else
+ {
+ /* LHS_ELT being null only means that the LHS as a whole is not a
+ scalarizable reference. There may be occurrences of scalarizable
+ variables within, which implies a USE. */
+ sra_walk_expr (&TREE_OPERAND (expr, 0), bsi, true, fns);
+ }
+
+ /* Likewise for the right-hand side. The only difference here is that
+ we don't have to handle constants, and the RHS may be a call. */
+ if (rhs_elt)
+ {
+ if (!rhs_elt->is_scalar)
+ fns->ldst (rhs_elt, lhs, bsi, false);
+ else
+ fns->use (rhs_elt, &TREE_OPERAND (expr, 1), bsi, false);
+ }
+ else if (TREE_CODE (rhs) == CALL_EXPR)
+ sra_walk_call_expr (rhs, bsi, fns);
+ else
+ sra_walk_expr (&TREE_OPERAND (expr, 1), bsi, false, fns);
+}
+
+/* Entry point to the walk functions. Search the entire function,
+ invoking the callbacks in FNS on each of the references to
+ scalarizable variables. */
+
+static void
+sra_walk_function (const struct sra_walk_fns *fns)
+{
+ basic_block bb;
+ block_stmt_iterator si, ni;
+
+ /* ??? Phase 4 could derive some benefit to walking the function in
+ dominator tree order. */
+
+ FOR_EACH_BB (bb)
+ for (si = bsi_start (bb); !bsi_end_p (si); si = ni)
+ {
+ tree stmt, t;
+ stmt_ann_t ann;
+
+ stmt = bsi_stmt (si);
+ ann = stmt_ann (stmt);
+
+ ni = si;
+ bsi_next (&ni);
+
+ /* If the statement has no virtual operands, then it doesn't
+ make any structure references that we care about. */
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
+ && NUM_VUSES (VUSE_OPS (ann)) == 0
+ && NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
+ continue;
+
+ switch (TREE_CODE (stmt))
+ {
+ case RETURN_EXPR:
+ /* If we have "return <retval>" then the return value is
+ already exposed for our pleasure. Walk it as a USE to
+ force all the components back in place for the return.
+
+ If we have an embedded assignment, then <retval> is of
+ a type that gets returned in registers in this ABI, and
+ we do not wish to extend their lifetimes. Treat this
+ as a USE of the variable on the RHS of this assignment. */
+
+ t = TREE_OPERAND (stmt, 0);
+ if (TREE_CODE (t) == MODIFY_EXPR)
+ sra_walk_expr (&TREE_OPERAND (t, 1), &si, false, fns);
+ else
+ sra_walk_expr (&TREE_OPERAND (stmt, 0), &si, false, fns);
+ break;
+
+ case MODIFY_EXPR:
+ sra_walk_modify_expr (stmt, &si, fns);
+ break;
+ case CALL_EXPR:
+ sra_walk_call_expr (stmt, &si, fns);
+ break;
+ case ASM_EXPR:
+ sra_walk_asm_expr (stmt, &si, fns);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/* Phase One: Scan all referenced variables in the program looking for
+ structures that could be decomposed. */
+
+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 (decl_can_be_decomposed_p (var))
+ {
+ bitmap_set_bit (sra_candidates, var_ann (var)->uid);
+ any_set = true;
+ }
+ }
+
+ return any_set;
+}
+
+
+/* Phase Two: Scan all references to scalarizable variables. Count the
+ number of times they are used or copied respectively. */
+
+/* Callbacks to fill in SRA_WALK_FNS. Everything but USE is
+ considered a copy, because we can decompose the reference such that
+ the sub-elements needn't be contiguous. */
+
+static void
+scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
+ block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
+ bool is_output ATTRIBUTE_UNUSED)
+{
+ elt->n_uses += 1;
+}
+
+static void
+scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
+ block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
+{
+ lhs_elt->n_copies += 1;
+ rhs_elt->n_copies += 1;
+}
+
+static void
+scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
+ block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
+{
+ lhs_elt->n_copies += 1;
+}
+
+static void
+scan_ldst (struct sra_elt *elt, tree other ATTRIBUTE_UNUSED,
+ block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
+ bool is_output ATTRIBUTE_UNUSED)
+{
+ elt->n_copies += 1;
+}
+
+/* Dump the values we collected during the scanning phase. */
+
+static void
+scan_dump (struct sra_elt *elt)
+{
+ struct sra_elt *c;
+
+ dump_sra_elt_name (dump_file, elt);
+ fprintf (dump_file, ": n_uses=%u n_copies=%u\n", elt->n_uses, elt->n_copies);
+
+ for (c = elt->children; c ; c = c->sibling)
+ scan_dump (c);
+}
+
+/* Entry point to phase 2. Scan the entire function, building up
+ scalarization data structures, recording copies and uses. */
+
+static void
+scan_function (void)
+{
+ static const struct sra_walk_fns fns = {
+ scan_use, scan_copy, scan_init, scan_ldst, true
+ };
+
+ sra_walk_function (&fns);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ size_t i;
+
+ fputs ("\nScan results:\n", dump_file);
+ EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i,
+ {
+ tree var = referenced_var (i);
+ struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
+ if (elt)
+ scan_dump (elt);
+ });
+ fputc ('\n', dump_file);
+ }
+}
+
+/* Phase Three: Make decisions about which variables to scalarize, if any.
+ All elements to be scalarized have replacement variables made for them. */
+
+/* A subroutine of build_element_name. Recursively build the element
+ name on the obstack. */
+
+static void
+build_element_name_1 (struct sra_elt *elt)
+{
+ tree t;
+ char buffer[32];
+
+ if (elt->parent)
+ {
+ build_element_name_1 (elt->parent);
+ obstack_1grow (&sra_obstack, '$');
+
+ if (TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
+ {
+ if (elt->element == integer_zero_node)
+ obstack_grow (&sra_obstack, "real", 4);
+ else
+ obstack_grow (&sra_obstack, "imag", 4);
+ return;
+ }
+ }
+
+ t = elt->element;
+ if (TREE_CODE (t) == INTEGER_CST)
+ {
+ /* ??? Eh. Don't bother doing double-wide printing. */
+ sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (t));
+ obstack_grow (&sra_obstack, buffer, strlen (buffer));
+ }
+ else
+ {
+ tree name = DECL_NAME (t);
+ if (name)
+ obstack_grow (&sra_obstack, IDENTIFIER_POINTER (name),
+ IDENTIFIER_LENGTH (name));
+ else
+ {
+ sprintf (buffer, "D%u", DECL_UID (t));
+ obstack_grow (&sra_obstack, buffer, strlen (buffer));
+ }
+ }
+}
+
+/* Construct a pretty variable name for an element's replacement variable.
+ The name is built on the obstack. */
+
+static char *
+build_element_name (struct sra_elt *elt)
+{
+ build_element_name_1 (elt);
+ obstack_1grow (&sra_obstack, '\0');
+ return obstack_finish (&sra_obstack);
+}
+
+/* Instantiate an element as an independent variable. */
+
+static void
+instantiate_element (struct sra_elt *elt)
+{
+ struct sra_elt *base_elt;
+ tree var, base;
+
+ for (base_elt = elt; base_elt->parent; base_elt = base_elt->parent)
+ continue;
+ base = base_elt->element;
+
+ elt->replacement = var = make_rename_temp (elt->type, "SR");
+ DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
+ TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
+ DECL_ARTIFICIAL (var) = DECL_ARTIFICIAL (base);
+
+ if (DECL_NAME (base) && !DECL_IGNORED_P (base))
+ {
+ char *pretty_name = build_element_name (elt);
+ DECL_NAME (var) = get_identifier (pretty_name);
+ obstack_free (&sra_obstack, pretty_name);
+ }
+
+ if (dump_file)
+ {
+ fputs (" ", dump_file);
+ dump_sra_elt_name (dump_file, elt);
+ fputs (" -> ", dump_file);
+ print_generic_expr (dump_file, var, dump_flags);
+ fputc ('\n', dump_file);
+ }
+}
+
+/* Make one pass across an element tree deciding whether or not it's
+ profitable to instantiate individual leaf scalars.
+
+ PARENT_USES and PARENT_COPIES are the sum of the N_USES and N_COPIES
+ fields all the way up the tree. */
+
+static void
+decide_instantiation_1 (struct sra_elt *elt, unsigned int parent_uses,
+ unsigned int parent_copies)
+{
+ if (dump_file && !elt->parent)
+ {
+ fputs ("Initial instantiation for ", dump_file);
+ dump_sra_elt_name (dump_file, elt);
+ fputc ('\n', dump_file);
+ }
+
+ if (elt->cannot_scalarize)
+ return;
+
+ if (elt->is_scalar)
+ {
+ /* The decision is simple: instantiate if we're used more frequently
+ than the parent needs to be seen as a complete unit. */
+ if (elt->n_uses + elt->n_copies + parent_copies > parent_uses)
+ instantiate_element (elt);
+ }
+ else
+ {
+ struct sra_elt *c;
+ unsigned int this_uses = elt->n_uses + parent_uses;
+ unsigned int this_copies = elt->n_copies + parent_copies;
+
+ for (c = elt->children; c ; c = c->sibling)
+ decide_instantiation_1 (c, this_uses, this_copies);
+ }
+}
+
+/* Compute the size and number of all instantiated elements below ELT.
+ We will only care about this if the size of the complete structure
+ fits in a HOST_WIDE_INT, so we don't have to worry about overflow. */
+
+static unsigned int
+sum_instantiated_sizes (struct sra_elt *elt, unsigned HOST_WIDE_INT *sizep)
+{
+ if (elt->replacement)
+ {
+ *sizep += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (elt->type));
+ return 1;
+ }
+ else
+ {
+ struct sra_elt *c;
+ unsigned int count = 0;
+
+ for (c = elt->children; c ; c = c->sibling)
+ count += sum_instantiated_sizes (c, sizep);
+
+ return count;
+ }
+}
+
+/* Instantiate fields in ELT->TYPE that are not currently present as
+ children of ELT. */
+
+static void instantiate_missing_elements (struct sra_elt *elt);
+
+static void
+instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
+{
+ struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
+ if (sub->is_scalar)
+ {
+ if (sub->replacement == NULL)
+ instantiate_element (sub);
+ }
+ else
+ instantiate_missing_elements (sub);
+}
+
+static void
+instantiate_missing_elements (struct sra_elt *elt)
+{
+ tree type = elt->type;
+
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ {
+ tree f;
+ for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ instantiate_missing_elements_1 (elt, f, TREE_TYPE (f));
+ break;
+ }
+
+ case ARRAY_TYPE:
+ {
+ tree i, max, subtype;
+
+ i = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
+ max = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ subtype = TREE_TYPE (type);
+
+ while (1)
+ {
+ instantiate_missing_elements_1 (elt, i, subtype);
+ if (tree_int_cst_equal (i, max))
+ break;
+ i = int_const_binop (PLUS_EXPR, i, integer_one_node, true);
+ }
+
+ break;
+ }
+
+ case COMPLEX_TYPE:
+ type = TREE_TYPE (type);
+ instantiate_missing_elements_1 (elt, integer_zero_node, type);
+ instantiate_missing_elements_1 (elt, integer_one_node, type);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Make one pass across an element tree deciding whether to perform block
+ or element copies. If we decide on element copies, instantiate all
+ elements. Return true if there are any instantiated sub-elements. */
+
+static bool
+decide_block_copy (struct sra_elt *elt)
+{
+ struct sra_elt *c;
+ bool any_inst;
+
+ /* If scalarization is disabled, respect it. */
+ if (elt->cannot_scalarize)
+ {
+ elt->use_block_copy = 1;
+
+ if (dump_file)
+ {
+ fputs ("Scalarization disabled for ", dump_file);
+ dump_sra_elt_name (dump_file, elt);
+ fputc ('\n', dump_file);
+ }
+
+ return false;
+ }
+
+ /* Don't decide if we've no uses. */
+ if (elt->n_uses == 0 && elt->n_copies == 0)
+ ;
+
+ else if (!elt->is_scalar)
+ {
+ tree size_tree = TYPE_SIZE_UNIT (elt->type);
+ bool use_block_copy = true;
+
+ /* Don't bother trying to figure out the rest if the structure is
+ so large we can't do easy arithmetic. This also forces block
+ copies for variable sized structures. */
+ if (host_integerp (size_tree, 1))
+ {
+ unsigned HOST_WIDE_INT full_size, inst_size = 0;
+ unsigned int inst_count;
+
+ full_size = tree_low_cst (size_tree, 1);
+
+ /* ??? What to do here. If there are two fields, and we've only
+ instantiated one, then instantiating the other is clearly a win.
+ If there are a large number of fields then the size of the copy
+ is much more of a factor. */
+
+ /* If the structure is small, and we've made copies, go ahead
+ and instantiate, hoping that the copies will go away. */
+ if (full_size <= (unsigned) MOVE_RATIO * UNITS_PER_WORD
+ && elt->n_copies > elt->n_uses)
+ use_block_copy = false;
+ else
+ {
+ inst_count = sum_instantiated_sizes (elt, &inst_size);
+
+ if (inst_size * 4 >= full_size * 3)
+ use_block_copy = false;
+ }
+
+ /* In order to avoid block copy, we have to be able to instantiate
+ all elements of the type. See if this is possible. */
+ if (!use_block_copy
+ && (!can_completely_scalarize_p (elt)
+ || !type_can_instantiate_all_elements (elt->type)))
+ use_block_copy = true;
+ }
+ elt->use_block_copy = use_block_copy;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Using %s for ",
+ use_block_copy ? "block-copy" : "element-copy");
+ dump_sra_elt_name (dump_file, elt);
+ fputc ('\n', dump_file);
+ }
+
+ if (!use_block_copy)
+ {
+ instantiate_missing_elements (elt);
+ return true;
+ }
+ }
+
+ any_inst = elt->replacement != NULL;
+
+ for (c = elt->children; c ; c = c->sibling)
+ any_inst |= decide_block_copy (c);
+
+ return any_inst;
+}
+
+/* Entry point to phase 3. Instantiate scalar replacement variables. */
+
+static void
+decide_instantiations (void)
+{
+ unsigned int i;
+ bool cleared_any;
+ struct bitmap_head_def done_head;
+
+ /* We cannot clear bits from a bitmap we're iterating over,
+ so save up all the bits to clear until the end. */
+ bitmap_initialize (&done_head, 1);
+ cleared_any = false;
+
+ EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i,
+ {
+ tree var = referenced_var (i);
+ struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
+ if (elt)
+ {
+ decide_instantiation_1 (elt, 0, 0);
+ if (!decide_block_copy (elt))
+ elt = NULL;
+ }
+ if (!elt)
+ {
+ bitmap_set_bit (&done_head, i);
+ cleared_any = true;
+ }
+ });
+
+ if (cleared_any)
+ {
+ bitmap_operation (sra_candidates, sra_candidates, &done_head,
+ BITMAP_AND_COMPL);
+ bitmap_operation (needs_copy_in, needs_copy_in, &done_head,
+ BITMAP_AND_COMPL);
+ }
+ bitmap_clear (&done_head);
+
+ if (dump_file)
+ fputc ('\n', dump_file);
+}
+
+
+/* Phase Four: Update the function to match the replacements created. */
+
+/* Mark all the variables in V_MAY_DEF or V_MUST_DEF operands for STMT for
+ renaming. This becomes necessary when we modify all of a non-scalar. */
+
+static void
+mark_all_v_defs (tree stmt)
+{
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ size_t i, n;
+
+ get_stmt_operands (stmt);
+
+ v_may_defs = V_MAY_DEF_OPS (stmt_ann (stmt));
+ n = NUM_V_MAY_DEFS (v_may_defs);
+ for (i = 0; i < n; i++)
+ {
+ tree sym = V_MAY_DEF_RESULT (v_may_defs, i);
+ if (TREE_CODE (sym) == SSA_NAME)
+ sym = SSA_NAME_VAR (sym);
+ bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (stmt_ann (stmt));
+ n = NUM_V_MUST_DEFS (v_must_defs);
+ for (i = 0; i < n; i++)
+ {
+ tree sym = V_MUST_DEF_OP (v_must_defs, i);
+ if (TREE_CODE (sym) == SSA_NAME)
+ sym = SSA_NAME_VAR (sym);
+ bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+ }
+}
+
+/* Build a single level component reference to ELT rooted at BASE. */
+
+static tree
+generate_one_element_ref (struct sra_elt *elt, tree base)
+{
+ switch (TREE_CODE (TREE_TYPE (base)))
+ {
+ case RECORD_TYPE:
+ return build (COMPONENT_REF, elt->type, base, elt->element, NULL);
+
+ case ARRAY_TYPE:
+ return build (ARRAY_REF, elt->type, base, elt->element, NULL, NULL);
+
+ case COMPLEX_TYPE:
+ if (elt->element == integer_zero_node)
+ return build (REALPART_EXPR, elt->type, base);
+ else
+ return build (IMAGPART_EXPR, elt->type, base);
+
+ default:
+ abort ();
+ }
+}
+
+/* Build a full component reference to ELT rooted at its native variable. */
+
+static tree
+generate_element_ref (struct sra_elt *elt)
+{
+ if (elt->parent)
+ return generate_one_element_ref (elt, generate_element_ref (elt->parent));
+ else
+ return elt->element;
+}
+
+/* Generate a set of assignment statements in *LIST_P to copy all
+ instantiated elements under ELT to or from the equivalent structure
+ rooted at EXPR. COPY_OUT controls the direction of the copy, with
+ true meaning to copy out of EXPR into ELT. */
+
+static void
+generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
+ tree *list_p)
+{
+ struct sra_elt *c;
+ tree t;
+
+ if (elt->replacement)
+ {
+ if (copy_out)
+ t = build (MODIFY_EXPR, void_type_node, elt->replacement, expr);
+ else
+ t = build (MODIFY_EXPR, void_type_node, expr, elt->replacement);
+ append_to_statement_list (t, list_p);
+ }
+ else
+ {
+ for (c = elt->children; c ; c = c->sibling)
+ {
+ t = generate_one_element_ref (c, unshare_expr (expr));
+ generate_copy_inout (c, copy_out, t, list_p);
+ }
+ }
+}
+
+/* Generate a set of assignment statements in *LIST_P to copy all instantiated
+ elements under SRC to their counterparts under DST. There must be a 1-1
+ correspondence of instantiated elements. */
+
+static void
+generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
+{
+ struct sra_elt *dc, *sc;
+
+ for (dc = dst->children; dc ; dc = dc->sibling)
+ {
+ sc = lookup_element (src, dc->element, NULL, NO_INSERT);
+ if (sc == NULL)
+ abort ();
+ generate_element_copy (dc, sc, list_p);
+ }
+
+ if (dst->replacement)
+ {
+ tree t;
+
+ if (src->replacement == NULL)
+ abort ();
+
+ t = build (MODIFY_EXPR, void_type_node, dst->replacement,
+ src->replacement);
+ append_to_statement_list (t, list_p);
+ }
+}
+
+/* Generate a set of assignment statements in *LIST_P to zero all instantiated
+ elements under ELT. In addition, do not assign to elements that have been
+ marked VISITED but do reset the visited flag; this allows easy coordination
+ with generate_element_init. */
+
+static void
+generate_element_zero (struct sra_elt *elt, tree *list_p)
+{
+ struct sra_elt *c;
+
+ if (elt->visited)
+ {
+ elt->visited = false;
+ return;
+ }
+
+ for (c = elt->children; c ; c = c->sibling)
+ generate_element_zero (c, list_p);
+
+ if (elt->replacement)
+ {
+ tree t;
+
+ if (elt->is_scalar)
+ t = fold_convert (elt->type, integer_zero_node);
+ else
+ /* We generated a replacement for a non-scalar? */
+ abort ();
+
+ t = build (MODIFY_EXPR, void_type_node, elt->replacement, t);
+ append_to_statement_list (t, list_p);
+ }
+}
+
+/* Generate a set of assignment statements in *LIST_P to set all instantiated
+ elements under ELT with the contents of the initializer INIT. In addition,
+ mark all assigned elements VISITED; this allows easy coordination with
+ generate_element_zero. Return false if we found a case we couldn't
+ handle. */
+
+static bool
+generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
+{
+ bool result = true;
+ enum tree_code init_code;
+ struct sra_elt *sub;
+ tree t;
+
+ /* We can be passed DECL_INITIAL of a static variable. It might have a
+ conversion, which we strip off here. */
+ STRIP_USELESS_TYPE_CONVERSION (init);
+ init_code = TREE_CODE (init);
+
+ if (elt->is_scalar)
+ {
+ if (elt->replacement)
+ {
+ t = build (MODIFY_EXPR, void_type_node, elt->replacement, init);
+ append_to_statement_list (t, list_p);
+ elt->visited = true;
+ }
+ return result;
+ }
+
+ switch (init_code)
+ {
+ case COMPLEX_CST:
+ case COMPLEX_EXPR:
+ for (sub = elt->children; sub ; sub = sub->sibling)
+ {
+ if (sub->element == integer_zero_node)
+ t = (init_code == COMPLEX_EXPR
+ ? TREE_OPERAND (init, 0) : TREE_REALPART (init));
+ else
+ t = (init_code == COMPLEX_EXPR
+ ? TREE_OPERAND (init, 1) : TREE_IMAGPART (init));
+ result &= generate_element_init (sub, t, list_p);
+ }
+ break;
+
+ case CONSTRUCTOR:
+ for (t = CONSTRUCTOR_ELTS (init); t ; t = TREE_CHAIN (t))
+ {
+ sub = lookup_element (elt, TREE_PURPOSE (t), NULL, NO_INSERT);
+ if (sub == NULL)
+ continue;
+ result &= generate_element_init (sub, TREE_VALUE (t), list_p);
+ }
+ break;
+
+ default:
+ elt->visited = true;
+ result = false;
+ }
+
+ return result;
+}
+
+/* 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. */
+
+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));
+ }
+ }
+}
+
+/* Helper function to insert LIST before BSI, and set up line number info. */
+
+static void
+sra_insert_before (block_stmt_iterator *bsi, tree list)
+{
+ 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);
+}
+
+/* Similarly, but insert after BSI. Handles insertion onto edges as well. */
+
+static void
+sra_insert_after (block_stmt_iterator *bsi, tree list)
+{
+ tree stmt = bsi_stmt (*bsi);
+
+ if (EXPR_HAS_LOCATION (stmt))
+ annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
+
+ if (stmt_ends_bb_p (stmt))
+ insert_edge_copies (list, bsi->bb);
+ else
+ bsi_insert_after (bsi, list, BSI_SAME_STMT);
+}
+
+/* Similarly, but replace the statement at BSI. */
+
+static void
+sra_replace (block_stmt_iterator *bsi, tree list)
+{
+ sra_insert_before (bsi, list);
+ bsi_remove (bsi);
+ if (bsi_end_p (*bsi))
+ *bsi = bsi_last (bsi->bb);
+ else
+ bsi_prev (bsi);
+}
+
+/* Scalarize a USE. To recap, this is either a simple reference to ELT,
+ if elt is scalar, or some occurrence of ELT that requires a complete
+ aggregate. IS_OUTPUT is true if ELT is being modified. */
+
+static void
+scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
+ bool is_output)
+{
+ tree list = NULL, stmt = bsi_stmt (*bsi);
+
+ if (elt->replacement)
+ {
+ /* If we have a replacement, then updating the reference is as
+ simple as modifying the existing statement in place. */
+ if (is_output)
+ mark_all_v_defs (stmt);
+ *expr_p = elt->replacement;
+ modify_stmt (stmt);
+ }
+ else
+ {
+ /* Otherwise we need some copies. If ELT is being read, then we want
+ to store all (modified) sub-elements back into the structure before
+ the reference takes place. If ELT is being written, then we want to
+ load the changed values back into our shadow variables. */
+ /* ??? We don't check modified for reads, we just always write all of
+ the values. We should be able to record the SSA number of the VOP
+ for which the values were last read. If that number matches the
+ SSA number of the VOP in the current statement, then we needn't
+ emit an assignment. This would also eliminate double writes when
+ a structure is passed as more than one argument to a function call.
+ This optimization would be most effective if sra_walk_function
+ processed the blocks in dominator order. */
+
+ generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
+ if (list == NULL)
+ return;
+ if (is_output)
+ {
+ mark_all_v_defs (expr_first (list));
+ sra_insert_after (bsi, list);
+ }
+ else
+ sra_insert_before (bsi, list);
+ }
+}
+
+/* Scalarize a COPY. To recap, this is an assignment statement between
+ two scalarizable references, LHS_ELT and RHS_ELT. */
+
+static void
+scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
+ block_stmt_iterator *bsi)
+{
+ tree list, stmt;
+
+ if (lhs_elt->replacement && rhs_elt->replacement)
+ {
+ /* If we have two scalar operands, modify the existing statement. */
+ stmt = bsi_stmt (*bsi);
+
+#ifdef ENABLE_CHECKING
+ /* See the commentary in sra_walk_function concerning
+ RETURN_EXPR, and why we should never see one here. */
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ abort ();
+#endif
+
+ TREE_OPERAND (stmt, 0) = lhs_elt->replacement;
+ TREE_OPERAND (stmt, 1) = rhs_elt->replacement;
+ modify_stmt (stmt);
+ }
+ else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
+ {
+ /* If either side requires a block copy, then sync the RHS back
+ to the original structure, leave the original assignment
+ statement (which will perform the block copy), then load the
+ LHS values out of its now-updated original structure. */
+ /* ??? Could perform a modified pair-wise element copy. That
+ would at least allow those elements that are instantiated in
+ both structures to be optimized well. */
+
+ list = NULL;
+ generate_copy_inout (rhs_elt, false,
+ generate_element_ref (rhs_elt), &list);
+ if (list)
+ {
+ mark_all_v_defs (expr_first (list));
+ sra_insert_before (bsi, list);
+ }
+
+ list = NULL;
+ generate_copy_inout (lhs_elt, true,
+ generate_element_ref (lhs_elt), &list);
+ if (list)
+ sra_insert_after (bsi, list);
+ }
+ else
+ {
+ /* Otherwise both sides must be fully instantiated. In which
+ case perform pair-wise element assignments and replace the
+ original block copy statement. */
+
+ stmt = bsi_stmt (*bsi);
+ mark_all_v_defs (stmt);
+
+ list = NULL;
+ generate_element_copy (lhs_elt, rhs_elt, &list);
+ if (list == NULL)
+ abort ();
+ sra_replace (bsi, list);
+ }
+}
+
+/* Scalarize an INIT. To recap, this is an assignment to a scalarizable
+ reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or
+ COMPLEX_EXPR. If RHS is NULL, it should be treated as an empty
+ CONSTRUCTOR. */
+
+static void
+scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
+{
+ bool result = true;
+ tree list = NULL;
+
+ /* Generate initialization statements for all members extant in the RHS. */
+ if (rhs)
+ result = generate_element_init (lhs_elt, rhs, &list);
+
+ /* CONSTRUCTOR is defined such that any member not mentioned is assigned
+ a zero value. Initialize the rest of the instantiated elements. */
+ generate_element_zero (lhs_elt, &list);
+
+ if (!result)
+ {
+ /* If we failed to convert the entire initializer, then we must
+ leave the structure assignment in place and must load values
+ from the structure into the slots for which we did not find
+ constants. The easiest way to do this is to generate a complete
+ copy-out, and then follow that with the constant assignments
+ that we were able to build. DCE will clean things up. */
+ tree list0 = NULL;
+ generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt),
+ &list0);
+ append_to_statement_list (list, &list0);
+ list = list0;
+ }
+
+ if (lhs_elt->use_block_copy || !result)
+ {
+ /* Since LHS is not fully instantiated, we must leave the structure
+ assignment in place. Treating this case differently from a USE
+ exposes constants to later optimizations. */
+ if (list)
+ {
+ mark_all_v_defs (expr_first (list));
+ sra_insert_after (bsi, list);
+ }
+ }
+ else
+ {
+ /* The LHS is fully instantiated. The list of initializations
+ replaces the original structure assignment. */
+ if (!list)
+ abort ();
+ mark_all_v_defs (bsi_stmt (*bsi));
+ sra_replace (bsi, list);
+ }
+}
+
+/* A subroutine of scalarize_ldst called via walk_tree. Set TREE_NO_TRAP
+ on all INDIRECT_REFs. */
+
+static tree
+mark_notrap (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ if (TREE_CODE (t) == INDIRECT_REF)
+ {
+ TREE_THIS_NOTRAP (t) = 1;
+ *walk_subtrees = 0;
+ }
+ else if (DECL_P (t) || TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+
+/* Scalarize a LDST. To recap, this is an assignment between one scalarizable
+ reference ELT and one non-scalarizable reference OTHER. IS_OUTPUT is true
+ if ELT is on the left-hand side. */
+
+static void
+scalarize_ldst (struct sra_elt *elt, tree other,
+ block_stmt_iterator *bsi, bool is_output)
+{
+ /* Shouldn't have gotten called for a scalar. */
+ if (elt->replacement)
+ abort ();
+
+ if (elt->use_block_copy)
+ {
+ /* Since ELT is not fully instantiated, we have to leave the
+ block copy in place. Treat this as a USE. */
+ scalarize_use (elt, NULL, bsi, is_output);
+ }
+ else
+ {
+ /* The interesting case is when ELT is fully instantiated. In this
+ case we can have each element stored/loaded directly to/from the
+ corresponding slot in OTHER. This avoids a block copy. */
+
+ tree list = NULL, stmt = bsi_stmt (*bsi);
+
+ mark_all_v_defs (stmt);
+ generate_copy_inout (elt, is_output, other, &list);
+ if (list == NULL)
+ abort ();
+
+ /* Preserve EH semantics. */
+ if (stmt_ends_bb_p (stmt))
+ {
+ tree_stmt_iterator tsi;
+ tree first;
+
+ /* Extract the first statement from LIST. */
+ tsi = tsi_start (list);
+ first = tsi_stmt (tsi);
+ tsi_delink (&tsi);
+
+ /* Replace the old statement with this new representative. */
+ bsi_replace (bsi, first, true);
+
+ if (!tsi_end_p (tsi))
+ {
+ /* If any reference would trap, then they all would. And more
+ to the point, the first would. Therefore none of the rest
+ will trap since the first didn't. Indicate this by
+ iterating over the remaining statements and set
+ TREE_THIS_NOTRAP in all INDIRECT_REFs. */
+ do
+ {
+ walk_tree (tsi_stmt_ptr (tsi), mark_notrap, NULL, NULL);
+ tsi_next (&tsi);
+ }
+ while (!tsi_end_p (tsi));
+
+ insert_edge_copies (list, bsi->bb);
+ }
+ }
+ else
+ sra_replace (bsi, list);
+ }
+}
+
+/* Generate initializations for all scalarizable parameters. */
+
+static void
+scalarize_parms (void)
+{
+ tree list = NULL;
+ size_t i;
+
+ EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i,
+ {
+ tree var = referenced_var (i);
+ struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
+ generate_copy_inout (elt, true, var, &list);
+ });
+
+ if (list)
+ insert_edge_copies (list, ENTRY_BLOCK_PTR);
+}
+
+/* Entry point to phase 4. Update the function to match replacements. */
+
+static void
+scalarize_function (void)
+{
+ static const struct sra_walk_fns fns = {
+ scalarize_use, scalarize_copy, scalarize_init, scalarize_ldst, false
+ };
+
+ sra_walk_function (&fns);
+ scalarize_parms ();
+ bsi_commit_edge_inserts (NULL);
+}
+
+
+/* Debug helper function. Print ELT in a nice human-readable format. */
+
+static void
+dump_sra_elt_name (FILE *f, struct sra_elt *elt)
+{
+ if (elt->parent && TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
+ {
+ fputs (elt->element == integer_zero_node ? "__real__ " : "__imag__ ", f);
+ dump_sra_elt_name (f, elt->parent);
+ }
+ else
+ {
+ if (elt->parent)
+ dump_sra_elt_name (f, elt->parent);
+ if (DECL_P (elt->element))
+ {
+ if (TREE_CODE (elt->element) == FIELD_DECL)
+ fputc ('.', f);
+ print_generic_expr (f, elt->element, dump_flags);
+ }
+ else
+ fprintf (f, "[" HOST_WIDE_INT_PRINT_DEC "]",
+ TREE_INT_CST_LOW (elt->element));
+ }
+}
+
+/* Likewise, but callable from the debugger. */
+
+void
+debug_sra_elt_name (struct sra_elt *elt)
+{
+ dump_sra_elt_name (stderr, elt);
+ fputc ('\n', stderr);
+}
+
+/* Main entry point. */
+
+static void
+tree_sra (void)
+{
+ /* Initialize local variables. */
+ gcc_obstack_init (&sra_obstack);
+ sra_candidates = BITMAP_XMALLOC ();
+ needs_copy_in = BITMAP_XMALLOC ();
+ sra_type_decomp_cache = BITMAP_XMALLOC ();
+ sra_type_inst_cache = BITMAP_XMALLOC ();
+ sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, NULL);
+
+ /* Scan. If we find anything, instantiate and scalarize. */
+ if (find_candidates_for_sra ())
+ {
+ scan_function ();
+ decide_instantiations ();
+ scalarize_function ();
+ }
+
+ /* Free allocated memory. */
+ htab_delete (sra_map);
+ sra_map = NULL;
+ BITMAP_XFREE (sra_candidates);
+ BITMAP_XFREE (needs_copy_in);
+ BITMAP_XFREE (sra_type_decomp_cache);
+ BITMAP_XFREE (sra_type_inst_cache);
+ obstack_free (&sra_obstack, NULL);
+}
+
+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..75c98e12d3d
--- /dev/null
+++ b/gcc/tree-ssa-alias.c
@@ -0,0 +1,2158 @@
+/* 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 *);
+static struct ptr_info_def *get_ptr_info (tree t);
+
+/* 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 V_MAY_DEF 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 = V_MAY_DEF <a_3>;
+ # b_8 = V_MAY_DEF <b_5>;
+ *p_1 = 3;
+
+ # a_9 = V_MAY_DEF <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)))
+ {
+ struct ptr_info_def *pi;
+
+ 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. */
+ pi = SSA_NAME_PTR_INFO (ptr);
+ if (pi->pt_anything)
+ {
+ pi->pt_malloc = 0;
+ pi->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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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
+ (gcc.c-torture/unsorted/pass.c). 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));
+ struct ptr_info_def *pi;
+ 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);
+
+ pi = SSA_NAME_PTR_INFO (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 (pi->pt_malloc || pi->pt_vars)
+ pi->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. */
+ pi->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 V_MAY_DEF operands as being written to. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree op = V_MAY_DEF_OP (v_may_defs, i);
+ tree var = SSA_NAME_VAR (op);
+ var_ann_t ann = var_ann (var);
+ bitmap_set_bit (ai->written_vars, ann->uid);
+ }
+
+ /* Mark variables in V_MUST_DEF operands as being written to. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, 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);
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
+ var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr));
+
+ if (pi->value_escapes_p || pi->pt_anything)
+ {
+ /* If PTR escapes or may point to anything, then its associated
+ memory tags are call-clobbered. */
+ if (pi->name_mem_tag)
+ mark_call_clobbered (pi->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 (pi->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 (pi->value_escapes_p
+ && pi->name_mem_tag == NULL_TREE
+ && pi->pt_vars)
+ EXECUTE_IF_SET_IN_BITMAP (pi->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 (pi->name_mem_tag && pi->pt_vars)
+ EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j,
+ add_may_alias (pi->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 (pi->name_mem_tag
+ && v_ann->type_mem_tag
+ && is_call_clobbered (pi->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 = V_MAY_DEF <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_PTR_INFO (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 V_MAY_DEF 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 V_MAY_DEF for every
+ call-clobbered variable at call sites. This is the preferred way in terms
+ of optimization opportunities but it may create too many V_MAY_DEF 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)
+{
+ struct ptr_info_def *dest_pi, *orig_pi;
+
+ /* Make sure we have points-to information for ORIG. */
+ collect_points_to_info_for (ai, orig);
+
+ dest_pi = get_ptr_info (dest);
+ orig_pi = SSA_NAME_PTR_INFO (orig);
+
+ if (orig_pi)
+ {
+ dest_pi->pt_anything |= orig_pi->pt_anything;
+ dest_pi->pt_malloc |= orig_pi->pt_malloc;
+
+ if (orig_pi->pt_vars)
+ {
+ if (dest_pi->pt_vars == NULL)
+ {
+ dest_pi->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_copy (dest_pi->pt_vars, orig_pi->pt_vars);
+ }
+ else
+ bitmap_a_or_b (dest_pi->pt_vars,
+ dest_pi->pt_vars,
+ orig_pi->pt_vars);
+ }
+ }
+}
+
+
+/* Add VALUE to the list of expressions pointed-to by PTR. */
+
+static void
+add_pointed_to_expr (tree ptr, tree value)
+{
+ struct ptr_info_def *pi;
+
+#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
+
+ pi = get_ptr_info (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)))
+ pi->pt_malloc = 1;
+ else
+ pi->pt_anything = 1;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Pointer ");
+ print_generic_expr (dump_file, ptr, dump_flags);
+ fprintf (dump_file, " points to ");
+ if (pi->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;
+ struct ptr_info_def *pi;
+ 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))
+ {
+ pi = get_ptr_info (ptr);
+ uid = var_ann (pt_var)->uid;
+ if (pi->pt_vars == NULL)
+ pi->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_set_bit (pi->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. */
+ get_ptr_info (var)->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)
+{
+ struct ptr_info_def *pi = get_ptr_info (ptr);
+ tree tag = pi->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 (pi->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);
+}
+
+
+/* Return the alias information associated with pointer T. It creates a
+ new instance if none existed. */
+
+static struct ptr_info_def *
+get_ptr_info (tree t)
+{
+ struct ptr_info_def *pi;
+
+#if defined ENABLE_CHECKING
+ if (!POINTER_TYPE_P (TREE_TYPE (t)))
+ abort ();
+#endif
+
+ pi = SSA_NAME_PTR_INFO (t);
+ if (pi == NULL)
+ {
+ pi = ggc_alloc (sizeof (*pi));
+ memset ((void *)pi, 0, sizeof (*pi));
+ SSA_NAME_PTR_INFO (t) = pi;
+ }
+
+ return pi;
+}
+
+
+/* Dump points-to information for SSA_NAME PTR into FILE. */
+
+static void
+dump_points_to_info_for (FILE *file, tree ptr)
+{
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
+
+ fprintf (file, "Pointer ");
+ print_generic_expr (file, ptr, dump_flags);
+
+ if (pi == NULL)
+ return;
+
+ if (pi->name_mem_tag)
+ {
+ fprintf (file, ", name memory tag: ");
+ print_generic_expr (file, pi->name_mem_tag, dump_flags);
+ }
+
+ if (pi->value_escapes_p)
+ fprintf (file, ", its value escapes");
+
+ if (pi->pt_anything)
+ fprintf (file, ", points-to anything");
+
+ if (pi->pt_malloc)
+ fprintf (file, ", points-to malloc");
+
+ if (pi->pt_vars)
+ {
+ unsigned ix;
+
+ fprintf (file, ", points-to vars: { ");
+ EXECUTE_IF_SET_IN_BITMAP (pi->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 = PHI_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..70b91f26520
--- /dev/null
+++ b/gcc/tree-ssa-ccp.c
@@ -0,0 +1,2556 @@
+/* Conditional constant propagation pass for the GNU compiler.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 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;
+
+/* Identical to SSA_EDGES. For performance reasons, the list of SSA
+ edges is split into two. One contains all SSA edges who need to be
+ reexamined because their lattice value changed to varying (this
+ worklist), and the other contains all other SSA edges to be
+ reexamined (ssa_edges).
+
+ Since most values in the program are varying, the ideal situation
+ is to move them to that lattice value as quickly as possible.
+ Thus, it doesn't make sense to process any other type of lattice
+ value until all varying values are propagated fully, which is one
+ thing using the varying worklist achieves. In addition, if you
+ don't use a separate worklist for varying edges, you end up with
+ situations where lattice values move from
+ undefined->constant->varying instead of undefined->varying.
+*/
+static GTY(()) varray_type varying_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, value);
+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 bool 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);
+
+/* Process an SSA edge worklist. WORKLIST is the SSA edge worklist to
+ drain. This pops statements off the given WORKLIST and processes
+ them until there are no more statements on WORKLIST. */
+
+static void
+process_ssa_edge_worklist (varray_type *worklist)
+{
+ /* Drain the entire worklist. */
+ while (VARRAY_ACTIVE_SIZE (*worklist) > 0)
+ {
+ /* Pull the statement to simulate off the worklist. */
+ tree stmt = VARRAY_TOP_TREE (*worklist);
+ stmt_ann_t ann = stmt_ann (stmt);
+ VARRAY_POP (*worklist);
+
+ /* 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);
+ }
+ }
+}
+
+/* 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
+ || VARRAY_ACTIVE_SIZE (varying_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);
+ }
+
+ /* In order to move things to varying as quickly as
+ possible,process the VARYING_SSA_EDGES worklist first. */
+ process_ssa_edge_worklist (&varying_ssa_edges);
+
+ /* Now process the SSA_EDGES worklist. */
+ process_ssa_edge_worklist (&ssa_edges);
+ }
+
+ /* 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_verify_stmts /* 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 = PHI_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 = PHI_CHAIN (phi))
+ {
+ int i;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ value *new_val;
+ use_operand_p orig_p = PHI_ARG_DEF_PTR (phi, i);
+ tree orig = USE_FROM_PTR (orig_p);
+
+ if (! SSA_VAR_P (orig))
+ break;
+
+ new_val = get_value (orig);
+ if (new_val->lattice_val == CONSTANT
+ && may_propagate_copy (orig, new_val->const_val))
+ SET_USE (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 (maybe_clean_eh_stmt (stmt))
+ tree_purge_dead_eh_edges (bb);
+ }
+ }
+
+ 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+
+ /* 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 V_MAY_DEF operands VARYING. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ def_to_varying (V_MAY_DEF_RESULT (v_may_defs, i));
+
+ /* Mark all V_MUST_DEF operands VARYING. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ def_to_varying (V_MUST_DEF_OP (v_must_defs, 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++)
+ SET_USE_OP (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 = fold_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 HOST_WIDE_INT var_size, field_size;
+ tree wide_val;
+ unsigned HOST_WIDE_INT mask;
+ unsigned int i;
+
+ /* We can only do this if the size of the type and field and VAL are
+ all constants representable in HOST_WIDE_INT. */
+ if (!host_integerp (TYPE_SIZE (TREE_TYPE (var)), 1)
+ || !host_integerp (DECL_SIZE (field), 1)
+ || !host_integerp (val, 0))
+ return NULL_TREE;
+
+ var_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1);
+ field_size = tree_low_cst (DECL_SIZE (field), 1);
+
+ /* 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_TREE;
+
+#if defined ENABLE_CHECKING
+ if (var_size < field_size)
+ abort ();
+#endif
+
+ /* If the sign bit of the value is not set or the field's type is unsigned,
+ just mask off the high order bits of the value. */
+ if (DECL_UNSIGNED (field)
+ || !(tree_low_cst (val, 0) & (((HOST_WIDE_INT)1) << (field_size - 1))))
+ {
+ /* 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 |= ((HOST_WIDE_INT) 1) << i;
+
+ wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val,
+ fold_convert (TREE_TYPE (var), 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 |= ((HOST_WIDE_INT) 1) << (var_size - i - 1);
+
+ wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
+ fold_convert (TREE_TYPE (var), 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;
+
+ /* Worklists of SSA edges. */
+ VARRAY_TREE_INIT (ssa_edges, 20, "ssa_edges");
+ VARRAY_TREE_INIT (varying_ssa_edges, 20, "varying_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 (num_ssa_names * sizeof (value));
+ memset (value_vector, 0, num_ssa_names * sizeof (value));
+
+ /* 1 if ssa variable is used in a virtual variable context. */
+ virtual_var = sbitmap_alloc (num_ssa_names);
+ 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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 V_MAY_DEF operands VARYING. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
+ {
+ tree res = V_MAY_DEF_RESULT (v_may_defs, x);
+ get_value (res)->lattice_val = VARYING;
+ SET_BIT (virtual_var, SSA_NAME_VERSION (res));
+ }
+
+ /* Mark all V_MUST_DEF operands VARYING. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+ {
+ tree v_must_def = V_MUST_DEF_OP (v_must_defs, x);
+ get_value (v_must_def)->lattice_val = VARYING;
+ SET_BIT (virtual_var, SSA_NAME_VERSION (v_must_def));
+ }
+ }
+
+ 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 = PHI_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;
+ varying_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 or varying_ssa_edges worklist. */
+static void
+add_var_to_ssa_edges_worklist (tree var, value val)
+{
+ 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;
+ if (val.lattice_val == VARYING)
+ VARRAY_PUSH_TREE (varying_ssa_edges, use);
+ else
+ 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, val);
+ *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++)
+ {
+ use_operand_p use = USE_OP_PTR (uses, i);
+ value *val = get_value (USE_FROM_PTR (use));
+
+ if (val->lattice_val == CONSTANT)
+ {
+ SET_USE (use, val->const_val);
+ replaced = true;
+ if (POINTER_TYPE_P (TREE_TYPE (USE_FROM_PTR (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)
+{
+ tree min_idx, idx, elt_offset = integer_zero_node;
+ tree array_type, elt_type, elt_size;
+
+ /* If BASE is an ARRAY_REF, we can pick up another offset (this time
+ measured in units of the size of elements type) from that ARRAY_REF).
+ We can't do anything if either is variable.
+
+ The case we handle here is *(&A[N]+O). */
+ if (TREE_CODE (base) == ARRAY_REF)
+ {
+ tree low_bound = array_ref_low_bound (base);
+
+ elt_offset = TREE_OPERAND (base, 1);
+ if (TREE_CODE (low_bound) != INTEGER_CST
+ || TREE_CODE (elt_offset) != INTEGER_CST)
+ return NULL_TREE;
+
+ elt_offset = int_const_binop (MINUS_EXPR, elt_offset, low_bound, 0);
+ base = TREE_OPERAND (base, 0);
+ }
+
+ /* 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;
+
+ /* If OFFSET and ELT_OFFSET are zero, we don't care about the size of the
+ element type (so we can use the alignment if it's not constant).
+ Otherwise, compute the offset as an index by using a division. If the
+ division isn't exact, then don't do anything. */
+ elt_size = TYPE_SIZE_UNIT (elt_type);
+ if (integer_zerop (offset))
+ {
+ if (TREE_CODE (elt_size) != INTEGER_CST)
+ elt_size = size_int (TYPE_ALIGN (elt_type));
+
+ idx = integer_zero_node;
+ }
+ else
+ {
+ unsigned HOST_WIDE_INT lquo, lrem;
+ HOST_WIDE_INT hquo, hrem;
+
+ if (TREE_CODE (elt_size) != INTEGER_CST
+ || 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);
+ }
+
+ /* Assume the low bound is zero. If there is a domain type, get the
+ low bound, if any, convert the index into that type, and add the
+ low bound. */
+ min_idx = integer_zero_node;
+ if (TYPE_DOMAIN (array_type))
+ {
+ if (TYPE_MIN_VALUE (TYPE_DOMAIN (array_type)))
+ min_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (array_type));
+ else
+ min_idx = fold_convert (TYPE_DOMAIN (array_type), min_idx);
+
+ if (TREE_CODE (min_idx) != INTEGER_CST)
+ return NULL_TREE;
+
+ idx = fold_convert (TYPE_DOMAIN (array_type), idx);
+ elt_offset = fold_convert (TYPE_DOMAIN (array_type), elt_offset);
+ }
+
+ if (!integer_zerop (min_idx))
+ idx = int_const_binop (PLUS_EXPR, idx, min_idx, 0);
+ if (!integer_zerop (elt_offset))
+ idx = int_const_binop (PLUS_EXPR, idx, elt_offset, 0);
+
+ return build (ARRAY_REF, orig_type, base, idx, min_idx,
+ size_int (tree_low_cst (elt_size, 1)
+ / (TYPE_ALIGN (elt_type) / BITS_PER_UNIT)));
+}
+
+/* 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, NULL_TREE);
+ 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
+ nonzero 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, NULL_TREE);
+
+ 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. We can only do this if EXPR is the same type
+ as BASE. We can't do this if EXPR is the element type of an array
+ and BASE is the array. */
+ if (integer_zerop (offset)
+ && lang_hooks.types_compatible_p (TREE_TYPE (base),
+ TREE_TYPE (expr)))
+ 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)
+ {
+ if (TREE_CODE (min_idx) != INTEGER_CST)
+ break;
+
+ 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;
+
+ if (TREE_CODE (rhs) == CALL_EXPR)
+ {
+ tree callee;
+
+ /* Check for builtins that CCP can handle using information not
+ available in the generic fold routines. */
+ callee = get_callee_fndecl (rhs);
+ if (callee && DECL_BUILT_IN (callee))
+ result = ccp_fold_builtin (stmt, rhs);
+ else
+ {
+ /* Check for resolvable OBJ_TYPE_REF. The only sorts we can resolve
+ here are when we've propagated the address of a decl into the
+ object slot. */
+ /* ??? Should perhaps do this in fold proper. However, doing it
+ there requires that we create a new CALL_EXPR, and that requires
+ copying EH region info to the new node. Easier to just do it
+ here where we can just smash the call operand. */
+ callee = TREE_OPERAND (rhs, 0);
+ if (TREE_CODE (callee) == OBJ_TYPE_REF
+ && lang_hooks.fold_obj_type_ref
+ && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (OBJ_TYPE_REF_OBJECT (callee), 0)))
+ {
+ tree t;
+
+ t = TREE_TYPE (TREE_OPERAND (OBJ_TYPE_REF_OBJECT (callee), 0));
+ t = lang_hooks.fold_obj_type_ref (callee, t);
+ if (t)
+ {
+ TREE_OPERAND (rhs, 0) = t;
+ changed = true;
+ }
+ }
+ }
+ }
+
+ /* 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_USELESS_TYPE_CONVERSION (result);
+
+ if (result != rhs)
+ changed |= 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 bool
+set_rhs (tree *stmt_p, tree expr)
+{
+ tree stmt = *stmt_p;
+ enum tree_code code = TREE_CODE (expr);
+
+ /* Verify the constant folded result is valid gimple. */
+ if (TREE_CODE_CLASS (code) == '2')
+ {
+ if (!is_gimple_val (TREE_OPERAND (expr, 0))
+ || !is_gimple_val (TREE_OPERAND (expr, 1)))
+ return false;
+ }
+ else if (TREE_CODE_CLASS (code) == '1')
+ {
+ if (!is_gimple_val (TREE_OPERAND (expr, 0)))
+ return false;
+ }
+
+ 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_t) ann;
+
+ if (TREE_SIDE_EFFECTS (expr))
+ {
+ def_optype defs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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;
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree var = V_MAY_DEF_RESULT (v_may_defs, i);
+ if (TREE_CODE (var) == SSA_NAME)
+ SSA_NAME_DEF_STMT (var) = *stmt_p;
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, i);
+ if (TREE_CODE (var) == SSA_NAME)
+ SSA_NAME_DEF_STMT (var) = *stmt_p;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+/* 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);
+ }
+
+ if (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..5d96fae8e5b
--- /dev/null
+++ b/gcc/tree-ssa-copy.c
@@ -0,0 +1,257 @@
+/* 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. */
+
+
+/* Return true if we may propagate ORIG into DEST, false otherwise. */
+
+bool
+may_propagate_copy (tree dest, tree orig)
+{
+ tree type_d = TREE_TYPE (dest);
+ tree type_o = TREE_TYPE (orig);
+
+ /* Do not copy between types for which we *do* need a conversion. */
+ if (!tree_ssa_useless_type_conversion_1 (type_d, type_o))
+ return false;
+
+ /* 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 (type_d) && POINTER_TYPE_P (type_o))
+ {
+ 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;
+ }
+
+ /* If ORIG flows in from an abnormal edge, it cannot be propagated. */
+ if (TREE_CODE (orig) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
+ return false;
+
+ /* If DEST is an SSA_NAME that flows from an abnormal edge or if it
+ represents a hard register, then it cannot be replaced. */
+ if (TREE_CODE (dest) == SSA_NAME
+ && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
+ || DECL_HARD_REGISTER (SSA_NAME_VAR (dest))))
+ return false;
+
+ /* Anything else is OK. */
+ return true;
+}
+
+/* Given two SSA_NAMEs, replace the annotations for the one referred to by OP
+ with VAR's annotations.
+
+ If OP is a pointer, copy the memory tag used originally by OP 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 is valid. */
+
+static void
+replace_ssa_names_ann (tree op,
+ tree var,
+ bool for_propagation ATTRIBUTE_UNUSED)
+{
+#if defined ENABLE_CHECKING
+ if (for_propagation && !may_propagate_copy (op, 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)))
+ {
+ var_ann_t new_ann = var_ann (SSA_NAME_VAR (var));
+ var_ann_t orig_ann = var_ann (SSA_NAME_VAR (op));
+
+ 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 ();
+ }
+
+}
+
+
+/* Common code for propagate_value and replace_exp.
+
+ Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the
+ replacement is done to propagate a value or not. */
+
+static void
+replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation)
+{
+ if (TREE_CODE (val) == SSA_NAME)
+ {
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
+ replace_ssa_names_ann (USE_FROM_PTR (op_p), val, for_propagation);
+ SET_USE (op_p, val);
+ }
+ else
+ SET_USE (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 (use_operand_p op_p, tree val)
+{
+ replace_exp_1 (op_p, val, true);
+}
+
+
+/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
+ into the tree pointed by OP_P.
+
+ Use this version for const/copy propagation when SSA operands are not
+ available. It will perform the additional checks to ensure validity of
+ the const/copy propagation, but will not update any operand information.
+ Be sure to mark the stmt as modified. */
+
+void
+propagate_tree_value (tree *op_p, tree val)
+{
+ if (TREE_CODE (val) == SSA_NAME)
+ {
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ replace_ssa_names_ann (*op_p, val, true);
+ *op_p = val;
+ }
+ else
+ *op_p = lhd_unsave_expr_now (val);
+}
+
+
+/* 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 (use_operand_p op_p, tree val)
+{
+ replace_exp_1 (op_p, val, false);
+}
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
new file mode 100644
index 00000000000..a355b2d5b7d
--- /dev/null
+++ b/gcc/tree-ssa-copyrename.c
@@ -0,0 +1,395 @@
+/* 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;
+ }
+
+ if ((TREE_CODE (root1) == RESULT_DECL) != (TREE_CODE (root2) == RESULT_DECL))
+ {
+ if (debug)
+ fprintf (debug, " : One root a RESULT_DECL. 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 (num_ssa_names + 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 = PHI_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 <= num_ssa_names; 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..e9ead5c0dfb
--- /dev/null
+++ b/gcc/tree-ssa-dce.c
@@ -0,0 +1,934 @@
+/* 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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;
+ }
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
+ if (need_to_preserve_store (v_may_def))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+ if (need_to_preserve_store (v_must_def))
+ {
+ 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 = PHI_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;
+
+#ifdef ENABLE_CHECKING
+ if (bb == EXIT_BLOCK_PTR)
+ abort ();
+#endif
+
+ if (bb == ENTRY_BLOCK_PTR)
+ return;
+
+ 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 (t && 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
+ V_MAY_DEF operands in this statement. Mark all the statements
+ which feed this statement's uses as necessary. */
+ vuse_optype vuses;
+ v_may_def_optype v_may_defs;
+ 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 V_MAY_DEF expressions are also needed as they
+ represent potential definitions that may reach this
+ statement (V_MAY_DEF operands allow us to follow def-def
+ links). */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (k = 0; k < NUM_V_MAY_DEFS (v_may_defs); k++)
+ mark_operand_necessary (V_MAY_DEF_OP (v_may_defs, 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 = PHI_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 = PHI_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 (num_ssa_names + 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..740fe9bc9b2
--- /dev/null
+++ b/gcc/tree-ssa-dom.c
@@ -0,0 +1,3696 @@
+/* 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 "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;
+
+/* Bitmap of blocks that have had EH statements cleaned. We should
+ remove their dead edges eventually. */
+static bitmap need_eh_cleanup;
+
+/* 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 hashval_t real_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_dominating_conditions (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_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, bb;
+ tree phi;
+ unsigned int i;
+ size_t old_num_referenced_vars = num_referenced_vars;
+ bitmap virtuals_to_rename = BITMAP_XMALLOC ();
+
+ /* First note any variables which we are going to have to take
+ out of SSA form as well as any virtuals which need updating. */
+ 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 = PHI_CHAIN (phi))
+ {
+ tree result = SSA_NAME_VAR (PHI_RESULT (phi));
+
+ if (is_gimple_reg (PHI_RESULT (phi)))
+ bitmap_set_bit (vars_to_rename, var_ann (result)->uid);
+ else
+ bitmap_set_bit (virtuals_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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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);
+ }
+
+ v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+ {
+ tree op = V_MAY_DEF_RESULT (v_may_defs, j);
+ bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
+ }
+
+ v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+ for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, 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 = PHI_CHAIN (phi))
+ {
+ tree result = SSA_NAME_VAR (PHI_RESULT (phi));
+
+ if (is_gimple_reg (PHI_RESULT (phi)))
+ bitmap_set_bit (vars_to_rename, var_ann (result)->uid);
+ else
+ bitmap_set_bit (virtuals_to_rename, var_ann (result)->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;
+ }
+
+ bitmap_a_or_b (vars_to_rename, vars_to_rename, virtuals_to_rename);
+
+ /* We must remove any PHIs for virtual variables that we are going to
+ re-rename. Hopefully we'll be able to simply update these incrementally
+ soon. */
+ FOR_EACH_BB (bb)
+ {
+ tree next;
+
+ for (phi = phi_nodes (bb); phi; phi = next)
+ {
+ tree result = PHI_RESULT (phi);
+
+ next = PHI_CHAIN (phi);
+
+ if (bitmap_bit_p (virtuals_to_rename,
+ var_ann (SSA_NAME_VAR (result))->uid))
+ remove_phi_node (phi, NULL, bb);
+ }
+ }
+ BITMAP_XFREE (virtuals_to_rename);
+}
+
+/* Jump threading, redundancy elimination and const/copy propagation.
+
+ 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. */
+
+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, real_avail_expr_hash, avail_expr_eq, free);
+ VARRAY_TREE_INIT (const_and_copies, num_ssa_names, "const_and_copies");
+ nonzero_vars = BITMAP_XMALLOC ();
+ VARRAY_EDGE_INIT (redirection_edges, 20, "redirection_edges");
+ VARRAY_GENERIC_PTR_INIT (vrp_data, num_ssa_names, "vrp_data");
+ need_eh_cleanup = BITMAP_XMALLOC ();
+
+ /* 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);
+
+ if (bitmap_first_set_bit (need_eh_cleanup) >= 0)
+ {
+ cfg_altered = tree_purge_all_dead_eh_edges (need_eh_cleanup);
+ bitmap_zero (need_eh_cleanup);
+ }
+
+ /* 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. Likewise with EH cleanup.
+ Free the dominance info first so that cleanup_tree_cfg doesn't try
+ to verify it. */
+ if (cfg_altered)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ 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 (false);
+ 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, num_ssa_names);
+ VARRAY_GROW (vrp_data, num_ssa_names);
+ }
+
+ /* 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 emptied the hash table earlier, now delete it completely. */
+ htab_delete (avail_exprs);
+
+ /* It is not necessary 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);
+ BITMAP_XFREE (need_eh_cleanup);
+}
+
+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 = PHI_CHAIN (phi))
+ {
+ tree src = PHI_ARG_DEF_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)
+ SET_USE_OP (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)
+ SET_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++)
+ SET_USE_OP (uses, i, uses_copy[i]);
+
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ SET_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->dest)
+ 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 entries 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 entries 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_dominating_conditions (cond, &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);
+ record_dominating_conditions (inverted, &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.
+
+ Additionally, if all the PHI alternatives are known to have a nonzero
+ value, then the result of this PHI is known to have a nonzero value,
+ even if we do not know its exact value. */
+
+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 = PHI_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
+ inferred 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);
+
+ /* Now see if we know anything about the nonzero property for the
+ result of this PHI. */
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ if (!PHI_ARG_NONZERO (phi, i))
+ break;
+ }
+
+ if (i == PHI_NUM_ARGS (phi))
+ bitmap_set_bit (nonzero_vars, SSA_NAME_VERSION (PHI_RESULT (phi)));
+
+ 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.
+ We can only know the value of the switch's condition if the dominator
+ parent is also the only predecessor of this block. */
+ else if (parent_block_last_stmt
+ && bb->pred->pred_next == NULL
+ && bb->pred->src == parent
+ && 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 || CASE_HIGH (elt))
+ 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
+ && match_case
+ && 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);
+}
+
+/* COND is a condition which is known to be true. Record variants of
+ COND which must also be true.
+
+ For example, if a < b is true, then a <= b must also be true. */
+
+static void
+record_dominating_conditions (tree cond, varray_type *block_avail_exprs_p)
+{
+ switch (TREE_CODE (cond))
+ {
+ case LT_EXPR:
+ record_cond (build2 (LE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (LTGT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case GT_EXPR:
+ record_cond (build2 (GE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (LTGT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case GE_EXPR:
+ case LE_EXPR:
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case EQ_EXPR:
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (LE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (GE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNORDERED_EXPR:
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNLE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNGE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNEQ_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNLT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNGT_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNLT_EXPR:
+ record_cond (build2 (UNLE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNGT_EXPR:
+ record_cond (build2 (UNGE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case UNEQ_EXPR:
+ record_cond (build2 (UNLE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (UNGE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ break;
+
+ case LTGT_EXPR:
+ record_cond (build2 (NE_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+ record_cond (build2 (ORDERED_EXPR, boolean_type_node,
+ TREE_OPERAND (cond, 0),
+ TREE_OPERAND (cond, 1)),
+ boolean_true_node,
+ block_avail_exprs_p);
+
+ default:
+ break;
+ }
+}
+
+/* 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
+ nonzero. */
+ 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;
+
+ /* If we care about correct floating point results, then
+ don't fold x + c1 - c2. Note that we need to take both
+ the codes and the signs to figure this out. */
+ if (FLOAT_TYPE_P (type)
+ && !flag_unsafe_math_optimizations
+ && (rhs_def_code == PLUS_EXPR
+ || rhs_def_code == MINUS_EXPR))
+ {
+ bool neg = false;
+
+ neg ^= (rhs_code == MINUS_EXPR);
+ neg ^= (rhs_def_code == MINUS_EXPR);
+ neg ^= real_isneg (TREE_REAL_CST_PTR (outer_const));
+ neg ^= real_isneg (TREE_REAL_CST_PTR (def_stmt_op1));
+
+ if (neg)
+ goto dont_fold_assoc;
+ }
+
+ /* 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);
+ }
+ }
+ }
+ dont_fold_assoc:;
+ }
+
+ /* 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)
+ = fold_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)
+ = fold_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)
+ {
+ int need_precision;
+ bool fail;
+
+ def = TREE_OPERAND (def, 0);
+
+#ifdef ENABLE_CHECKING
+ /* ??? Why was Jeff testing this? We are gimple... */
+ if (!is_gimple_val (def))
+ abort ();
+#endif
+
+ to = TREE_TYPE (cond);
+ ti = TREE_TYPE (def);
+
+ /* If we have an extension that preserves value, then we
+ can copy the source value into the switch. */
+
+ need_precision = TYPE_PRECISION (ti);
+ fail = false;
+ if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
+ fail = true;
+ else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
+ need_precision += 1;
+ if (TYPE_PRECISION (to) < need_precision)
+ fail = true;
+
+ if (!fail)
+ {
+ SWITCH_COND (stmt) = def;
+ ann->modified = 1;
+
+ return lookup_avail_expr (stmt, block_avail_exprs_p, insert);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* 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).
+
+ NONZERO_VARS is the set SSA_NAMES known to have a nonzero value,
+ even if we don't know their precise value.
+
+ Propagate values from CONST_AND_COPIES and NONZERO_VARS into the PHI
+ nodes of the successors of BB. */
+
+static void
+cprop_into_successor_phis (basic_block bb,
+ varray_type const_and_copies,
+ bitmap nonzero_vars)
+{
+ 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 = PHI_CHAIN (phi))
+ {
+ int i;
+ tree new;
+ use_operand_p orig_p;
+ tree orig;
+
+ /* 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_PTR (phi, hint);
+ orig = USE_FROM_PTR (orig_p);
+ if (TREE_CODE (orig) != SSA_NAME)
+ continue;
+
+ /* If the alternative is known to have a nonzero value, record
+ that fact in the PHI node itself for future use. */
+ if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig)))
+ PHI_ARG_NONZERO (phi, hint) = true;
+
+ /* 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));
+ if (new
+ && (TREE_CODE (new) == SSA_NAME
+ || is_gimple_min_invariant (new))
+ && may_propagate_copy (orig, new))
+ {
+ propagate_value (orig_p, new);
+ }
+ }
+ }
+}
+
+
+/* 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, nonzero_vars);
+}
+
+/* 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)
+{
+ v_may_def_optype v_may_defs = V_MAY_DEF_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_V_MAY_DEFS (v_may_defs) != 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 (*expr_p, cached_lhs)))
+ {
+ 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_tree_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 inferred 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. */
+ if (flag_delete_null_pointer_checks)
+ 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. */
+ while (TREE_CODE (op) == SSA_NAME)
+ {
+ tree def = SSA_NAME_DEF_STMT (op);
+
+ record_var_is_nonzero (op, block_nonzero_vars_p);
+
+ /* And walk up the USE-DEF chains noting other SSA_NAMEs
+ which are known to have a nonzero value. */
+ if (def
+ && TREE_CODE (def) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (def, 1)) == NOP_EXPR)
+ op = TREE_OPERAND (TREE_OPERAND (def, 1), 0);
+ else
+ break;
+ }
+ }
+ }
+
+ /* 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)
+ {
+ v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_def_optype v_must_defs = V_MUST_DEF_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_v_may_defs (new);
+ remove_v_must_defs (new);
+
+ start_ssa_stmt_operands (new);
+ /* For each VDEF on the original statement, we want to create a
+ VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new
+ statement. */
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+ {
+ tree op = V_MAY_DEF_RESULT (v_may_defs, j);
+ add_vuse (op, new);
+ }
+
+ for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, 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);
+ }
+ }
+}
+
+/* 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, use_operand_p op_p, varray_type const_and_copies)
+{
+ bool may_have_exposed_new_symbols = false;
+ tree val;
+ tree op = USE_FROM_PTR (op_p);
+
+ /* 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));
+ 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)
+ && (get_virtual_var (val) != get_virtual_var (op)
+ || TREE_CODE (val) != SSA_NAME))
+ return false;
+
+ /* Get the toplevel type of each operand. */
+ op_type = TREE_TYPE (op);
+ 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 (TREE_CODE (val) != SSA_NAME)
+ {
+ if (!lang_hooks.types_compatible_p (op_type, val_type))
+ {
+ val = fold_convert (TREE_TYPE (op), val);
+ if (!is_gimple_min_invariant (val))
+ return false;
+ }
+ }
+
+ /* Certain operands are not allowed to be copy propagated due
+ to their interaction with exception handling and some GCC
+ extensions. */
+ else if (!may_propagate_copy (op, val))
+ return false;
+
+ /* Dump details. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Replaced '");
+ print_generic_expr (dump_file, op, 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))
+ && 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
+ v_may_def_ops of STMT. */
+
+static 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_v_may_defs;
+ vuse_optype vuses;
+ v_may_def_optype v_may_defs;
+ use_optype uses;
+
+ uses = USE_OPS (ann);
+ num_uses = NUM_USES (uses);
+ for (i = 0; i < num_uses; i++)
+ {
+ use_operand_p op_p = USE_OP_PTR (uses, i);
+ if (TREE_CODE (USE_FROM_PTR (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++)
+ {
+ use_operand_p op_p = VUSE_OP_PTR (vuses, i);
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
+ may_have_exposed_new_symbols
+ |= cprop_operand (ann, op_p, const_and_copies);
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs);
+ for (i = 0; i < num_v_may_defs; i++)
+ {
+ use_operand_p op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
+ may_have_exposed_new_symbols
+ |= cprop_operand (ann, op_p, const_and_copies);
+ }
+ return may_have_exposed_new_symbols;
+}
+
+
+/* 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,
+ block_stmt_iterator si)
+{
+ stmt_ann_t ann;
+ tree stmt;
+ 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);
+ 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 V_MAY_DEFs. */
+ 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, val))
+ cfg_altered = true;
+
+ /* If we simplified a statement in such a way as to be shown that it
+ cannot trap, update the eh information and the cfg to match. */
+ if (maybe_clean_eh_stmt (stmt))
+ {
+ bitmap_set_bit (need_eh_cleanup, bb->index);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Flagged to clear EH edges.\n");
+ }
+ }
+
+ 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_dominating_conditions (cond, 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_dominating_conditions (inverted, 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 hashval_t
+real_avail_expr_hash (const void *p)
+{
+ return ((const struct expr_hash_elt *)p)->hash;
+}
+
+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 definitions 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), block_defs_p);
+ }
+
+ /* Register new virtual mustdefs made by the statement. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (V_MUST_DEF_OP (v_must_defs, i), block_defs_p);
+ }
+}
+
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
new file mode 100644
index 00000000000..ce286948056
--- /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 definition 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_v_may_defs (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 V_MAY_DEF_RESULTs in STMT with the
+ corresponding V_MAY_DEF_OP in STMT. */
+
+static void
+fix_phi_uses (tree phi, tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ v_may_def_optype v_may_defs;
+ unsigned int i;
+ int j;
+
+ get_stmt_operands (stmt);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+
+ /* Walk each V_MAY_DEF in STMT. */
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
+
+ /* Find any uses in the PHI which match V_MAY_DEF and replace
+ them with the appropriate V_MAY_DEF_OP. */
+ for (j = 0; j < PHI_NUM_ARGS (phi); j++)
+ if (v_may_def == PHI_ARG_DEF (phi, j))
+ SET_PHI_ARG_DEF (phi, j, V_MAY_DEF_OP (v_may_defs, i));
+ }
+}
+
+/* Replace the V_MAY_DEF_OPs in STMT1 which match V_MAY_DEF_RESULTs
+ in STMT2 with the appropriate V_MAY_DEF_OPs from STMT2. */
+
+static void
+fix_stmt_v_may_defs (tree stmt1, tree stmt2)
+{
+ stmt_ann_t ann1 = stmt_ann (stmt1);
+ stmt_ann_t ann2 = stmt_ann (stmt2);
+ v_may_def_optype v_may_defs1;
+ v_may_def_optype v_may_defs2;
+ unsigned int i, j;
+
+ get_stmt_operands (stmt1);
+ get_stmt_operands (stmt2);
+ v_may_defs1 = V_MAY_DEF_OPS (ann1);
+ v_may_defs2 = V_MAY_DEF_OPS (ann2);
+
+ /* Walk each V_MAY_DEF_OP in stmt1. */
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs1); i++)
+ {
+ tree v_may_def1 = V_MAY_DEF_OP (v_may_defs1, i);
+
+ /* Find the appropriate V_MAY_DEF_RESULT in STMT2. */
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs2); j++)
+ {
+ if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j))
+ {
+ /* Update. */
+ SET_V_MAY_DEF_OP (v_may_defs1, i, V_MAY_DEF_OP (v_may_defs2, j));
+ break;
+ }
+ }
+
+#ifdef ENABLE_CHECKING
+ /* If we did not find a corresponding V_MAY_DEF_RESULT, then something
+ has gone terribly wrong. */
+ if (j == NUM_V_MAY_DEFS (v_may_defs2))
+ 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);
+ v_may_def_optype v_may_defs;
+
+ get_stmt_operands (stmt);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+
+ /* If this statement has no virtual uses, then there is nothing
+ to do. */
+ if (NUM_V_MAY_DEFS (v_may_defs) == 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 V_MAY_DEFs 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_v_may_defs (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 = PHI_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 = PHI_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..6daf6557f0d
--- /dev/null
+++ b/gcc/tree-ssa-live.c
@@ -0,0 +1,1900 @@
+/* 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ 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 (num_ssa_names + 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 (((num_ssa_names + 1) * sizeof (int)));
+ memset (map->ref_count, 0, (num_ssa_names + 1) * sizeof (int));
+ }
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi, arg;
+ for (phi = phi_nodes (bb); phi; phi = PHI_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 (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 (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
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
+ {
+ tree var = V_MAY_DEF_OP (v_may_defs, x);
+ set_is_used (var);
+
+#if defined ENABLE_CHECKING
+ SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+#endif
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, 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 = PHI_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 = PHI_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 = PHI_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 = PHI_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 entries 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;
+
+ defs = DEF_OPS (ann);
+ num = NUM_DEFS (defs);
+ for (x = 0; x < num; x++)
+ {
+ var = DEF_OP (defs, x);
+ add_conflicts_if_valid (tpa, graph, map, live, var);
+ }
+
+ uses = USE_OPS (ann);
+ num = NUM_USES (uses);
+ for (x = 0; x < num; x++)
+ {
+ var = USE_OP (uses, x);
+ set_if_valid (map, live, var);
+ }
+ }
+ }
+
+ /* 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 = PHI_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 nonzero
+ 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 < num_ssa_names; 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 = PHI_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..59967eef3df
--- /dev/null
+++ b/gcc/tree-ssa-live.h
@@ -0,0 +1,750 @@
+/* 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
+
+#include "partition.h"
+
+/* 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-ch.c b/gcc/tree-ssa-loop-ch.c
new file mode 100644
index 00000000000..5794a86cd6c
--- /dev/null
+++ b/gcc/tree-ssa-loop-ch.c
@@ -0,0 +1,349 @@
+/* Loop header copying on 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 "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "cfgloop.h"
+#include "tree-inline.h"
+#include "flags.h"
+#include "tree-inline.h"
+
+/* Duplicates headers of loops if they are small enough, so that the statements
+ in the loop body are always executed when the loop is entered. This
+ increases effectivity of code motion optimizations, and reduces the need
+ for loop preconditioning. */
+
+/* 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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ unsigned i;
+
+ for (stmt = phi_nodes (bb); stmt; stmt = TREE_CHAIN (stmt))
+ {
+ var = PHI_RESULT (stmt);
+ bitmap_set_bit (vars_to_rename, SSA_NAME_VERSION (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);
+
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ var = DEF_OP (defs, i);
+ bitmap_set_bit (vars_to_rename, SSA_NAME_VERSION (var));
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ var = V_MAY_DEF_RESULT (v_may_defs, i);
+ bitmap_set_bit (vars_to_rename, SSA_NAME_VERSION (var));
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ var = V_MUST_DEF_OP (v_must_defs, i);
+ bitmap_set_bit (vars_to_rename, SSA_NAME_VERSION (var));
+ }
+ }
+}
+
+/* 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, new_phi, var;
+
+ /* TODO: It should be quite easy to keep the dominance information
+ up-to-date. */
+ free_dominance_info (CDI_DOMINATORS);
+
+ 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);
+ }
+
+ 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;
+
+ if (!header->aux)
+ abort ();
+ header->aux = NULL;
+
+ new_header = duplicate_block (header, preheader_edge);
+
+ /* Create the phi nodes on on entry to new_header. */
+ for (phi = phi_nodes (header), var = PENDING_STMT (preheader_edge);
+ phi;
+ phi = TREE_CHAIN (phi), var = TREE_CHAIN (var))
+ {
+ new_phi = create_phi_node (PHI_RESULT (phi), new_header);
+ add_phi_arg (&new_phi, TREE_VALUE (var), preheader_edge);
+ }
+ PENDING_STMT (preheader_edge) = NULL;
+
+ /* 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_ARG_DEF_FROM_EDGE (phi, e);
+ add_phi_arg (&phi, def, e1);
+ }
+ }
+ }
+
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ rewrite_ssa_into_ssa (vars_to_rename);
+ bitmap_clear (vars_to_rename);
+}
+
+/* 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 efficiency 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 do not try to keep the information about irreducible 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_dump_func
+ | TODO_verify_ssa) /* todo_flags_finish */
+};
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
new file mode 100644
index 00000000000..885954e5e85
--- /dev/null
+++ b/gcc/tree-ssa-loop.c
@@ -0,0 +1,143 @@
+/* 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"
+
+/* The loop tree currently optimized. */
+
+struct loops *current_loops;
+
+/* Initializes the loop structures. DUMP is the file to that the details
+ about the analysis should be dumped. */
+
+static struct loops *
+tree_loop_optimizer_init (FILE *dump)
+{
+ struct loops *loops = loop_optimizer_init (dump);
+
+ if (!loops)
+ return NULL;
+
+ /* Creation of preheaders may create redundant phi nodes if the loop is
+ entered by more than one edge, but the initial value of the induction
+ variable is the same on all of them. */
+ kill_redundant_phi_nodes ();
+ rewrite_into_ssa (false);
+ bitmap_clear (vars_to_rename);
+
+ return loops;
+}
+
+/* The loop superpass. */
+
+static bool
+gate_loop (void)
+{
+ return flag_tree_loop_optimize != 0;
+}
+
+struct tree_opt_pass pass_loop =
+{
+ "loop", /* name */
+ gate_loop, /* gate */
+ NULL, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_LOOP, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ TODO_ggc_collect, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect /* todo_flags_finish */
+};
+
+/* Loop optimizer initialization. */
+
+static void
+tree_ssa_loop_init (void)
+{
+ current_loops = tree_loop_optimizer_init (dump_file);
+}
+
+struct tree_opt_pass pass_loop_init =
+{
+ "loopinit", /* name */
+ NULL, /* gate */
+ tree_ssa_loop_init, /* 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 */
+ 0 /* todo_flags_finish */
+};
+
+/* Loop optimizer finalization. */
+
+static void
+tree_ssa_loop_done (void)
+{
+ if (!current_loops)
+ return;
+
+ loop_optimizer_finalize (current_loops,
+ (dump_flags & TDF_DETAILS ? dump_file : NULL));
+ current_loops = NULL;
+ cleanup_tree_cfg ();
+}
+
+struct tree_opt_pass pass_loop_done =
+{
+ "loopdone", /* name */
+ NULL, /* gate */
+ tree_ssa_loop_done, /* 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 */
+ 0 /* todo_flags_finish */
+};
+
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
new file mode 100644
index 00000000000..c44189f0a9f
--- /dev/null
+++ b/gcc/tree-ssa-operands.c
@@ -0,0 +1,1488 @@
+/* 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 or a
+ call-clobbered variable */
+#define opf_is_def (1 << 0)
+
+/* Operand is the target of an assignment expression. */
+#define opf_kill_def (1 << 2)
+
+/* 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 v_may_def operands. */
+static GTY (()) varray_type build_v_may_defs;
+
+/* Array for building all the vuse operands. */
+static GTY (()) varray_type build_vuses;
+
+/* Array for building all the v_must_def operands. */
+static GTY (()) varray_type build_v_must_defs;
+
+#ifdef ENABLE_CHECKING
+tree check_build_stmt;
+#endif
+
+typedef struct voperands_d
+{
+ v_may_def_optype v_may_def_ops;
+ vuse_optype vuse_ops;
+ v_must_def_optype v_must_def_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_v_may_def (tree, tree, voperands_t);
+static void append_v_must_def (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);
+
+/* Return a vector of contiguous memory of a specified size. */
+
+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 = 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 = ggc_alloc (size);
+ use_ops->num_uses = num;
+ return use_ops;
+}
+
+static inline v_may_def_optype
+allocate_v_may_def_optype (unsigned num)
+{
+ v_may_def_optype v_may_def_ops;
+ unsigned size;
+ size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1);
+ v_may_def_ops = ggc_alloc (size);
+ v_may_def_ops->num_v_may_defs = num;
+ return v_may_def_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 = ggc_alloc (size);
+ vuse_ops->num_vuses = num;
+ return vuse_ops;
+}
+
+static inline v_must_def_optype
+allocate_v_must_def_optype (unsigned num)
+{
+ v_must_def_optype v_must_def_ops;
+ unsigned size;
+ size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1);
+ v_must_def_ops = ggc_alloc (size);
+ v_must_def_ops->num_v_must_defs = num;
+ return v_must_def_ops;
+}
+
+static inline void
+free_uses (use_optype *uses, bool dealloc)
+{
+ if (*uses)
+ {
+ if (dealloc)
+ ggc_free (*uses);
+ *uses = NULL;
+ }
+}
+
+static inline void
+free_defs (def_optype *defs, bool dealloc)
+{
+ if (*defs)
+ {
+ if (dealloc)
+ ggc_free (*defs);
+ *defs = NULL;
+ }
+}
+
+static inline void
+free_vuses (vuse_optype *vuses, bool dealloc)
+{
+ if (*vuses)
+ {
+ if (dealloc)
+ ggc_free (*vuses);
+ *vuses = NULL;
+ }
+}
+
+static inline void
+free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc)
+{
+ if (*v_may_defs)
+ {
+ if (dealloc)
+ ggc_free (*v_may_defs);
+ *v_may_defs = NULL;
+ }
+}
+
+static inline void
+free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc)
+{
+ if (*v_must_defs)
+ {
+ if (dealloc)
+ ggc_free (*v_must_defs);
+ *v_must_defs = NULL;
+ }
+}
+
+void
+remove_vuses (tree stmt)
+{
+ stmt_ann_t ann;
+
+ ann = stmt_ann (stmt);
+ if (ann)
+ free_vuses (&(ann->vuse_ops), true);
+}
+
+void
+remove_v_may_defs (tree stmt)
+{
+ stmt_ann_t ann;
+
+ ann = stmt_ann (stmt);
+ if (ann)
+ free_v_may_defs (&(ann->v_may_def_ops), true);
+}
+
+void
+remove_v_must_defs (tree stmt)
+{
+ stmt_ann_t ann;
+
+ ann = stmt_ann (stmt);
+ if (ann)
+ free_v_must_defs (&(ann->v_must_def_ops), true);
+}
+
+void
+init_ssa_operands (void)
+{
+ VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
+ VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses");
+ VARRAY_TREE_INIT (build_v_may_defs, 10, "build v_may_defs");
+ VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
+ VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs");
+}
+
+void
+fini_ssa_operands (void)
+{
+}
+
+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].def = 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].use = VARRAY_TREE_PTR (build_uses, x);
+ VARRAY_POP_ALL (build_uses);
+
+ ann = stmt_ann (stmt);
+ ann->use_ops = use_ops;
+}
+
+static void
+finalize_ssa_v_may_defs (tree stmt)
+{
+ unsigned num, x;
+ v_may_def_optype v_may_def_ops;
+ stmt_ann_t ann;
+
+ num = VARRAY_ACTIVE_SIZE (build_v_may_defs);
+ if (num == 0)
+ return;
+
+#ifdef ENABLE_CHECKING
+ /* V_MAY_DEFs must be entered in pairs of result/uses. */
+ if (num % 2 != 0)
+ abort();
+#endif
+
+ v_may_def_ops = allocate_v_may_def_optype (num / 2);
+ for (x = 0; x < num; x++)
+ v_may_def_ops->v_may_defs[x] = VARRAY_TREE (build_v_may_defs, x);
+ VARRAY_CLEAR (build_v_may_defs);
+
+ ann = stmt_ann (stmt);
+ ann->v_may_def_ops = v_may_def_ops;
+}
+
+static inline void
+finalize_ssa_vuses (tree stmt)
+{
+ unsigned num, x;
+ stmt_ann_t ann;
+ vuse_optype vuse_ops;
+ v_may_def_optype v_may_defs;
+
+#ifdef ENABLE_CHECKING
+ if (VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0)
+ {
+ fprintf (stderr, "Please finalize V_MAY_DEFs 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
+ V_MAY_DEF operation for a variable 'a', then a VUSE for 'a' is not
+ needed because V_MAY_DEFs imply a VUSE of the variable. For instance,
+ suppose that variable 'a' is aliased:
+
+ # VUSE <a_2>
+ # a_3 = V_MAY_DEF <a_2>
+ a = a + 1;
+
+ The VUSE <a_2> is superfluous because it is implied by the V_MAY_DEF
+ operation. */
+
+ ann = stmt_ann (stmt);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ if (NUM_V_MAY_DEFS (v_may_defs) > 0)
+ {
+ size_t i, j;
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
+ {
+ bool found = false;
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+ {
+ tree vuse_var, v_may_def_var;
+ tree vuse = VARRAY_TREE (build_vuses, i);
+ tree v_may_def = V_MAY_DEF_OP (v_may_defs, j);
+
+ if (TREE_CODE (vuse) == SSA_NAME)
+ vuse_var = SSA_NAME_VAR (vuse);
+ else
+ vuse_var = vuse;
+
+ if (TREE_CODE (v_may_def) == SSA_NAME)
+ v_may_def_var = SSA_NAME_VAR (v_may_def);
+ else
+ v_may_def_var = v_may_def;
+
+ if (vuse_var == v_may_def_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;
+}
+
+static void
+finalize_ssa_v_must_defs (tree stmt)
+{
+ unsigned num, x;
+ stmt_ann_t ann;
+ v_must_def_optype v_must_def_ops;
+
+ num = VARRAY_ACTIVE_SIZE (build_v_must_defs);
+ if (num == 0)
+ return;
+
+#ifdef ENABLE_CHECKING
+ /* There should only be a single V_MUST_DEF per assignment. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1)
+ abort ();
+#endif
+
+ v_must_def_ops = allocate_v_must_def_optype (num);
+ for (x = 0; x < num ; x++)
+ v_must_def_ops->v_must_defs[x] = VARRAY_TREE (build_v_must_defs, x);
+ VARRAY_POP_ALL (build_v_must_defs);
+
+ ann = stmt_ann (stmt);
+ ann->v_must_def_ops = v_must_def_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_v_must_defs (stmt);
+ finalize_ssa_v_may_defs (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_v_may_defs) > 0
+ || VARRAY_ACTIVE_SIZE (build_v_must_defs) > 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_v_may_def (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_v_may_defs); i += 2)
+ {
+ tree result = VARRAY_TREE (build_v_may_defs, 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 V_MAY_DEFs matches VAR. If so, re-use it, otherwise add a new
+ V_MAY_DEF for VAR. */
+ result = NULL_TREE;
+ source = NULL_TREE;
+ if (prev_vops)
+ for (i = 0; i < NUM_V_MAY_DEFS (prev_vops->v_may_def_ops); i++)
+ {
+ result = V_MAY_DEF_RESULT (prev_vops->v_may_def_ops, i);
+ if (result == var
+ || (TREE_CODE (result) == SSA_NAME
+ && SSA_NAME_VAR (result) == var))
+ {
+ source = V_MAY_DEF_OP (prev_vops->v_may_def_ops, i);
+ break;
+ }
+ }
+
+ /* If no previous V_MAY_DEF operand was found for VAR, create one now. */
+ if (source == NULL_TREE)
+ {
+ result = var;
+ source = var;
+ }
+
+ VARRAY_PUSH_TREE (build_v_may_defs, result);
+ VARRAY_PUSH_TREE (build_v_may_defs, 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);
+}
+
+/* Add VAR to the list of virtual must definitions 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_v_must_def (tree var, tree stmt, voperands_t prev_vops)
+{
+ stmt_ann_t ann;
+ size_t i;
+ bool found;
+ tree v_must_def;
+
+#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_v_must_defs); i++)
+ {
+ tree v_must_def_var = VARRAY_TREE (build_v_must_defs, i);
+ if (var == v_must_def_var
+ || (TREE_CODE (v_must_def_var) == SSA_NAME
+ && var == SSA_NAME_VAR (v_must_def_var)))
+ return;
+ }
+
+ /* If the statement already had virtual must defs, see if any of the
+ existing V_MUST_DEFs matches VAR. If so, re-use it, otherwise add a new
+ V_MUST_DEF for VAR. */
+ found = false;
+ v_must_def = NULL_TREE;
+ if (prev_vops)
+ for (i = 0; i < NUM_V_MUST_DEFS (prev_vops->v_must_def_ops); i++)
+ {
+ v_must_def = V_MUST_DEF_OP (prev_vops->v_must_def_ops, i);
+ if (v_must_def == var
+ || (TREE_CODE (v_must_def) == SSA_NAME
+ && SSA_NAME_VAR (v_must_def) == var))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ /* If VAR existed already in PREV_VOPS, re-use it. */
+ if (found)
+ var = v_must_def;
+
+ VARRAY_PUSH_TREE (build_v_must_defs, 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, nor
+ makes aliased loads or stores. */
+ ann->has_volatile_ops = false;
+ ann->makes_aliased_stores = false;
+ ann->makes_aliased_loads = 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.v_may_def_ops = V_MAY_DEF_OPS (ann);
+ prev_vops.vuse_ops = VUSE_OPS (ann);
+ prev_vops.v_must_def_ops = V_MUST_DEF_OPS (ann);
+
+ /* Don't free the previous values to memory since we're still using them. */
+ free_v_may_defs (&(ann->v_may_def_ops), false);
+ free_vuses (&(ann->vuse_ops), false);
+ free_v_must_defs (&(ann->v_must_def_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);
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR
+ /* Use a V_MAY_DEF if the RHS might throw, as the LHS won't be
+ modified in that case. FIXME we should represent somehow
+ that it is killed on the fallthrough path. */
+ || tree_could_throw_p (TREE_OPERAND (stmt, 1)))
+ get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def,
+ &prev_vops);
+ else
+ get_expr_operands (stmt, &TREE_OPERAND (stmt, 0),
+ opf_is_def | opf_kill_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_v_may_defs (&(prev_vops.v_may_def_ops), true);
+ free_vuses (&(prev_vops.vuse_ops), true);
+ free_v_must_defs (&(prev_vops.v_must_def_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_v_may_def 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);
+
+ /* We could have the address of a component, array member, etc which
+ has interesting variable references. */
+ if (code == ADDR_EXPR)
+ {
+ /* 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 constant (invariant is not sufficient), there will
+ be no interesting variable references inside. */
+ if (TREE_CONSTANT (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. */
+ expr_p = &TREE_OPERAND (expr, 0);
+ expr = *expr_p;
+ 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;
+
+ /* 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
+ {
+ struct ptr_info_def *pi = NULL;
+
+ /* If we have computed aliasing already, check if PTR has
+ flow-sensitive points-to information. */
+ if (TREE_CODE (ptr) == SSA_NAME
+ && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
+ && pi->name_mem_tag)
+ {
+ /* PTR has its own memory tag. Use it. */
+ add_stmt_operand (&pi->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
+ && pi == 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 || code == ARRAY_RANGE_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);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 3), 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);
+
+ if (code == COMPONENT_REF)
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, 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)
+ {
+ /* A 'pure' or a 'const' functions never call clobber anything.
+ A 'noreturn' function might, but since we don't return anyway
+ there is no point in recording that. */
+ if (!(call_flags
+ & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
+ 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);
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == ARRAY_REF
+ || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF
+ || TREE_CODE (TREE_OPERAND (expr, 0)) == REALPART_EXPR
+ || TREE_CODE (TREE_OPERAND (expr, 0)) == IMAGPART_EXPR)
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def,
+ prev_vops);
+ else
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
+ opf_is_def | opf_kill_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
+ || code == OBJ_TYPE_REF)
+ {
+ tree op0 = TREE_OPERAND (expr, 0);
+ tree op1 = TREE_OPERAND (expr, 1);
+
+ /* If it would be profitable to swap the operands, then do so to
+ canonicalize the statement, enabling better optimization.
+
+ By placing canonicalization of such expressions here we
+ transparently keep statements in canonical form, even
+ when the statement is modified. */
+ if (tree_swap_operands_p (op0, op1, false))
+ {
+ /* For relationals we need to swap the operands and change
+ the code. */
+ if (code == LT_EXPR
+ || code == GT_EXPR
+ || code == LE_EXPR
+ || code == GE_EXPR)
+ {
+ TREE_SET_CODE (expr, swap_tree_comparison (code));
+ TREE_OPERAND (expr, 0) = op1;
+ TREE_OPERAND (expr, 1) = op0;
+ }
+
+ /* For a commutative operator we can just swap the operands. */
+ if (commutative_tree_code (code))
+ {
+ TREE_OPERAND (expr, 0) = op1;
+ TREE_OPERAND (expr, 1) = op0;
+ }
+ }
+
+ 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_v_may_def 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)
+ {
+ if (v_ann->is_alias_tag)
+ {
+ /* Alias tagged vars get regular V_MAY_DEF */
+ s_ann->makes_aliased_stores = 1;
+ append_v_may_def (var, stmt, prev_vops);
+ }
+ else if ((flags & opf_kill_def)
+ && v_ann->mem_tag_kind == NOT_A_TAG)
+ /* V_MUST_DEF for non-aliased non-GIMPLE register
+ variable definitions. Avoid memory tags. */
+ append_v_must_def (var, stmt, prev_vops);
+ else
+ /* Call-clobbered variables & memory tags get
+ V_MAY_DEF */
+ append_v_may_def (var, stmt, prev_vops);
+ }
+ 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_v_may_def (var, stmt, prev_vops);
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+ append_v_may_def (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 V_MAY_DEF 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 V_MAY_DEF, 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);
+ });
+ }
+}
+
+/* Copies virtual operands from SRC to DST. */
+
+void
+copy_virtual_operands (tree dst, tree src)
+{
+ vuse_optype vuses = STMT_VUSE_OPS (src);
+ v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (src);
+ v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (src);
+ vuse_optype *vuses_new = &stmt_ann (dst)->vuse_ops;
+ v_may_def_optype *v_may_defs_new = &stmt_ann (dst)->v_may_def_ops;
+ v_must_def_optype *v_must_defs_new = &stmt_ann (dst)->v_must_def_ops;
+ unsigned i;
+
+ if (vuses)
+ {
+ *vuses_new = allocate_vuse_optype (NUM_VUSES (vuses));
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ SET_VUSE_OP (*vuses_new, i, VUSE_OP (vuses, i));
+ }
+
+ if (v_may_defs)
+ {
+ *v_may_defs_new = allocate_v_may_def_optype (NUM_V_MAY_DEFS (v_may_defs));
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ SET_V_MAY_DEF_OP (*v_may_defs_new, i, V_MAY_DEF_OP (v_may_defs, i));
+ SET_V_MAY_DEF_RESULT (*v_may_defs_new, i,
+ V_MAY_DEF_RESULT (v_may_defs, i));
+ }
+ }
+
+ if (v_must_defs)
+ {
+ *v_must_defs_new = allocate_v_must_def_optype (NUM_V_MUST_DEFS (v_must_defs));
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ SET_V_MUST_DEF_OP (*v_must_defs_new, i, V_MUST_DEF_OP (v_must_defs, i));
+ }
+}
+
+#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..625334109dc
--- /dev/null
+++ b/gcc/tree-ssa-operands.h
@@ -0,0 +1,169 @@
+/* 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. */
+
+
+/* This represents a pointer to a DEF operand. */
+typedef struct def_operand_ptr GTY(())
+{
+ tree * GTY((skip(""))) def;
+} def_operand_p;
+
+/* This represents a pointer to a USE operand. */
+typedef struct use_operand_ptr GTY(())
+{
+ tree * GTY((skip(""))) use;
+} use_operand_p;
+
+
+/* This represents the DEF operands of a stmt. */
+typedef struct def_optype_d GTY(())
+{
+ unsigned num_defs;
+ struct def_operand_ptr GTY((length("%h.num_defs"))) defs[1];
+} def_optype_t;
+
+typedef def_optype_t *def_optype;
+
+/* This represents the USE operands of a stmt. */
+typedef struct use_optype_d GTY(())
+{
+ unsigned num_uses;
+ struct use_operand_ptr GTY((length("%h.num_uses"))) uses[1];
+} use_optype_t;
+
+typedef use_optype_t *use_optype;
+
+/* This represents the MAY_DEFS for a stmt. */
+typedef struct v_may_def_optype_d GTY(())
+{
+ unsigned num_v_may_defs;
+ tree GTY((length ("%h.num_v_may_defs * 2"))) v_may_defs[1];
+} v_may_def_optype_t;
+
+typedef v_may_def_optype_t *v_may_def_optype;
+
+/* This represents the VUSEs for a stmt. */
+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;
+
+/* This represents the V_MUST_DEFS for a stmt. */
+typedef struct v_must_def_optype_d GTY(())
+{
+ unsigned num_v_must_defs;
+ tree GTY((length("%h.num_v_must_defs"))) v_must_defs[1];
+} v_must_def_optype_t;
+
+typedef v_must_def_optype_t *v_must_def_optype;
+
+#define USE_FROM_PTR(OP) get_use_from_ptr (OP)
+#define DEF_FROM_PTR(OP) get_def_from_ptr (OP)
+#define SET_USE(OP, V) ((*((OP).use)) = (V))
+#define SET_DEF(OP, V) ((*((OP).def)) = (V))
+
+
+#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_FROM_PTR (USE_OP_PTR ((OPS), (I))))
+#define SET_USE_OP(OPS, I, V) (SET_USE (USE_OP_PTR ((OPS), (I)), (V)))
+
+
+
+#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_FROM_PTR (DEF_OP_PTR ((OPS), (I))))
+#define SET_DEF_OP(OPS, I, V) (SET_DEF (DEF_OP_PTR ((OPS), (I)), (V)))
+
+
+
+#define V_MAY_DEF_OPS(ANN) get_v_may_def_ops (ANN)
+#define STMT_V_MAY_DEF_OPS(STMT) get_v_may_def_ops (stmt_ann(STMT))
+#define NUM_V_MAY_DEFS(OPS) ((OPS) ? (OPS)->num_v_may_defs : 0)
+#define V_MAY_DEF_RESULT_PTR(OPS, I) get_v_may_def_result_ptr ((OPS), (I))
+#define V_MAY_DEF_RESULT(OPS, I) \
+ (DEF_FROM_PTR (V_MAY_DEF_RESULT_PTR ((OPS), (I))))
+#define SET_V_MAY_DEF_RESULT(OPS, I, V) \
+ (SET_DEF (V_MAY_DEF_RESULT_PTR ((OPS), (I)), (V)))
+#define V_MAY_DEF_OP_PTR(OPS, I) get_v_may_def_op_ptr ((OPS), (I))
+#define V_MAY_DEF_OP(OPS, I) \
+ (USE_FROM_PTR (V_MAY_DEF_OP_PTR ((OPS), (I))))
+#define SET_V_MAY_DEF_OP(OPS, I, V) \
+ (SET_USE (V_MAY_DEF_OP_PTR ((OPS), (I)), (V)))
+
+
+#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) (USE_FROM_PTR (VUSE_OP_PTR ((OPS), (I))))
+#define SET_VUSE_OP(OPS, I, V) (SET_USE (VUSE_OP_PTR ((OPS), (I)), (V)))
+
+
+#define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN)
+#define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT))
+#define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0)
+#define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I))
+#define V_MUST_DEF_OP(OPS, I) \
+ (DEF_FROM_PTR (V_MUST_DEF_OP_PTR ((OPS), (I))))
+#define SET_V_MUST_DEF_OP(OPS, I, V) \
+ (SET_DEF (V_MUST_DEF_OP_PTR ((OPS), (I)), (V)))
+
+
+#define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI)
+#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
+#define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V))
+
+#define PHI_ARG_DEF_PTR(PHI, I) get_phi_arg_def_ptr ((PHI), (I))
+#define PHI_ARG_DEF(PHI, I) USE_FROM_PTR (PHI_ARG_DEF_PTR ((PHI), (I)))
+#define SET_PHI_ARG_DEF(PHI, I, V) \
+ SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V))
+#define PHI_ARG_DEF_FROM_EDGE(PHI, E) \
+ PHI_ARG_DEF ((PHI), \
+ phi_arg_from_edge ((PHI),(E)))
+#define PHI_ARG_DEF_PTR_FROM_EDGE(PHI, E) \
+ PHI_ARG_DEF_PTR ((PHI), \
+ phi_arg_from_edge ((PHI),(E)))
+
+
+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_v_may_defs (tree);
+extern void remove_v_must_defs (tree);
+extern void copy_virtual_operands (tree, 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..bc14dc48d80
--- /dev/null
+++ b/gcc/tree-ssa-phiopt.c
@@ -0,0 +1,677 @@
+/* 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 "flags.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, tree, tree, tree);
+static bool value_replacement (basic_block, tree, tree, tree);
+static bool abs_replacement (basic_block, tree, tree, tree);
+static void replace_phi_with_stmt (block_stmt_iterator, basic_block,
+ basic_block, tree, tree);
+static bool candidate_bb_for_phi_optimization (basic_block,
+ basic_block *,
+ basic_block *);
+static bool empty_block_p (basic_block);
+
+/* 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.
+
+ Also done is the following optimization:
+
+ bb0:
+ if (a != b) goto bb2; else goto bb1;
+ bb1:
+ bb2:
+ x = PHI (a (bb1), b (bb0))
+
+ We can rewrite that as:
+
+ bb0:
+ bb1:
+ bb2:
+ x = b;
+
+ This can sometimes occur as a result of other optimizations. A
+ similar transformation is done by the ifcvt RTL optimizer.
+
+ This pass also eliminates PHI nodes which are really absolute
+ values. i.e. if we have something like:
+
+ bb0:
+ if (a >= 0) goto bb2; else goto bb1;
+ bb1:
+ x = -a;
+ bb2:
+ x = PHI (x (bb1), a (bb0));
+
+ We can rewrite that as:
+
+ bb0:
+ bb1:
+ bb2:
+ x = ABS_EXPR< a >;
+
+ bb1 will become unreachable and bb0 and bb2 will almost always be merged
+ into a single block. Similar transformations are done by the ifcvt
+ RTL optimizer. */
+
+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 && PHI_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)
+ || value_replacement (bb, phi, arg0, arg1)
+ || abs_replacement (bb, phi, arg0, arg1))
+ {
+ /* We have done the replacement so we need to rebuild the
+ cfg when this pass is complete. */
+ removed_phis = true;
+ }
+ }
+ }
+
+ /* 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 ();
+}
+
+/* Return TRUE if block BB has no executable statements, otherwise return
+ FALSE. */
+static bool
+empty_block_p (basic_block bb)
+{
+ block_stmt_iterator bsi;
+
+ /* BB must have no executable statements. */
+ bsi = bsi_start (bb);
+ 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;
+
+ return true;
+}
+
+/* BB is a basic block which has only one PHI node with precisely two
+ arguments.
+
+ Examine both of BB's predecessors to see if one ends with a
+ COND_EXPR and the other is a successor of the COND_EXPR. If so, then
+ we may be able to optimize PHI nodes at the start of BB.
+
+ If so, mark store the block with the COND_EXPR into COND_BLOCK_P
+ and the other block into OTHER_BLOCK_P and return true, otherwise
+ return false. */
+
+static bool
+candidate_bb_for_phi_optimization (basic_block bb,
+ basic_block *cond_block_p,
+ basic_block *other_block_p)
+{
+ tree last0, last1;
+ basic_block cond_block, other_block;
+
+ /* One of the alternatives must come from a block ending with
+ a COND_EXPR. */
+ 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;
+
+ *cond_block_p = cond_block;
+ *other_block_p = other_block;
+ /* Everything looks OK. */
+ return true;
+}
+
+/* Replace PHI in block BB with statement NEW. NEW is inserted after
+ BSI. Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
+ is known to have two edges, one of which must reach BB). */
+
+static void
+replace_phi_with_stmt (block_stmt_iterator bsi, basic_block bb,
+ basic_block cond_block, tree phi, tree new)
+{
+ /* Insert our new statement at the head of our block. */
+ 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);
+}
+
+/* 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 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 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;
+
+ if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block)
+ || !empty_block_p (other_block))
+ 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 it 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);
+ }
+
+ replace_phi_with_stmt (bsi, bb, cond_block, phi, new);
+
+ /* Note that we optimized this PHI. */
+ return true;
+}
+
+/* The function value_replacement does the main work of doing the value
+ 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
+value_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
+{
+ tree result;
+ basic_block other_block = NULL;
+ basic_block cond_block = NULL;
+ tree new, cond;
+ edge true_edge, false_edge;
+
+ /* If the type says honor signed zeros we cannot do this
+ optimization. */
+ if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
+ return false;
+
+ if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block)
+ || !empty_block_p (other_block))
+ return false;
+
+ cond = COND_EXPR_COND (last_stmt (cond_block));
+ result = PHI_RESULT (phi);
+
+ /* This transformation is only valid for equality comparisons. */
+ if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
+ return false;
+
+ /* We need to know which is the true edge and which is the false
+ edge so that we know if have abs or negative abs. */
+ extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
+
+ /* 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.
+
+ The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
+
+ There is a single PHI node at the join point (BB) with two arguments.
+
+ We now need to verify that the two arguments in the PHI node match
+ the two arguments to the equality comparison. */
+
+ if ((operand_equal_p (arg0, TREE_OPERAND (cond, 0), 0)
+ && operand_equal_p (arg1, TREE_OPERAND (cond, 1), 0))
+ || (operand_equal_p (arg1, TREE_OPERAND (cond, 0), 0)
+ && operand_equal_p (arg0, TREE_OPERAND (cond, 1), 0)))
+ {
+ edge e;
+ tree arg;
+
+ /* For NE_EXPR, we want to build an assignment result = arg where
+ arg is the PHI argument associated with the true edge. For
+ EQ_EXPR we want the PHI argument associated with the false edge. */
+ e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
+
+ /* Unfortunately, E may not reach BB (it may instead have gone to
+ OTHER_BLOCK). If that is the case, then we want the single outgoing
+ edge from OTHER_BLOCK which reaches BB and represents the desired
+ path from COND_BLOCK. */
+ if (e->dest == other_block)
+ e = e->dest->succ;
+
+ /* Now we know the incoming edge to BB that has the argument for the
+ RHS of our new assignment statement. */
+ if (PHI_ARG_EDGE (phi, 0) == e)
+ arg = arg0;
+ else
+ arg = arg1;
+
+ /* Build the new assignment. */
+ new = build (MODIFY_EXPR, TREE_TYPE (result), result, arg);
+
+ replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new);
+
+ /* Note that we optimized this PHI. */
+ return true;
+ }
+ return false;
+}
+
+/* The function absolute_replacement does the main work of doing the absolute
+ 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
+abs_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
+{
+ tree result;
+ basic_block other_block = NULL;
+ basic_block cond_block = NULL;
+ tree new, cond;
+ block_stmt_iterator bsi;
+ edge true_edge, false_edge;
+ tree assign = NULL;
+ edge e;
+ tree rhs = NULL, lhs = NULL;
+ bool negate;
+ enum tree_code cond_code;
+
+ /* If the type says honor signed zeros we cannot do this
+ optimization. */
+ if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
+ return false;
+
+ if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block))
+ return false;
+
+ /* OTHER_BLOCK must have only one executable statement which must have the
+ form arg0 = -arg1 or arg1 = -arg0. */
+ bsi = bsi_start (other_block);
+ while (!bsi_end_p (bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ /* Empty statements and labels are uninteresting. */
+ if (TREE_CODE (stmt) == LABEL_EXPR
+ || IS_EMPTY_STMT (stmt))
+ {
+ bsi_next (&bsi);
+ continue;
+ }
+
+ /* If we found the assignment, but it was not the only executable
+ statement in OTHER_BLOCK, then we can not optimize. */
+ if (assign)
+ return false;
+
+ /* If we got here, then we have found the first executable statement
+ in OTHER_BLOCK. If it is anything other than arg = -arg1 or
+ arg1 = -arg0, then we can not optimize. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ lhs = TREE_OPERAND (stmt, 0);
+ rhs = TREE_OPERAND (stmt, 1);
+
+ if (TREE_CODE (rhs) == NEGATE_EXPR)
+ {
+ rhs = TREE_OPERAND (rhs, 0);
+
+ /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
+ if ((lhs == arg0 && rhs == arg1)
+ || (lhs == arg1 && rhs == arg0))
+ {
+ assign = stmt;
+ bsi_next (&bsi);
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+
+ /* If we did not find the proper negation assignment, then we can not
+ optimize. */
+ if (assign == NULL)
+ return false;
+
+ cond = COND_EXPR_COND (last_stmt (cond_block));
+ result = PHI_RESULT (phi);
+
+ /* Only relationals comparing arg[01] against zero are interesting. */
+ cond_code = TREE_CODE (cond);
+ if (cond_code != GT_EXPR && cond_code != GE_EXPR
+ && cond_code != LT_EXPR && cond_code != LE_EXPR)
+ return false;
+
+ /* Make sure the conditional is arg[01] OP y. */
+ if (TREE_OPERAND (cond, 0) != rhs)
+ return false;
+
+ if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
+ ? real_zerop (TREE_OPERAND (cond, 1))
+ : integer_zerop (TREE_OPERAND (cond, 1)))
+ ;
+ else
+ return false;
+
+ /* We need to know which is the true edge and which is the false
+ edge so that we know if have abs or negative abs. */
+ extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
+
+ /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
+ will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
+ the false edge goes to OTHER_BLOCK. */
+ if (cond_code == GT_EXPR || cond_code == GE_EXPR)
+ e = true_edge;
+ else
+ e = false_edge;
+
+ if (e->dest == other_block)
+ negate = true;
+ else
+ negate = false;
+
+ if (negate)
+ lhs = make_rename_temp (TREE_TYPE (result), NULL);
+ else
+ lhs = result;
+
+ /* Build the modify expression with abs expression. */
+ new = build (MODIFY_EXPR, TREE_TYPE (lhs),
+ lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
+
+ replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new);
+
+ if (negate)
+ {
+
+ /* Get the right BSI. We want to insert after the recently
+ added ABS_EXPR statement (which we know is the first statement
+ in the block. */
+ bsi = bsi_start (bb);
+ bsi_next (&bsi);
+ new = build (MODIFY_EXPR, TREE_TYPE (result),
+ result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
+
+ bsi_insert_after (&bsi, new, BSI_NEW_STMT);
+
+ /* Register the new statement as defining the temporary -- this is
+ normally done by replace_phi_with_stmt, but the link will be wrong
+ if we had to negate the resulting value. */
+ SSA_NAME_DEF_STMT (result) = new;
+ }
+
+ /* 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..848bd6a3941
--- /dev/null
+++ b/gcc/tree-ssa-pre.c
@@ -0,0 +1,2066 @@
+/* SSA-PRE for trees.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dan@dberlin.org> and Steven Bosscher
+ <stevenb@suse.de>
+
+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 "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"
+#include "splay-tree.h"
+#include "bitmap.h"
+#include "langhooks.h"
+
+/* TODO:
+
+ 1. Avail sets can be shared by making an avail_find_leader that
+ walks up the dominator tree and looks in those avail sets.
+ This might affect code optimality, it's unclear right now.
+ 2. Load motion can be performed by value numbering the loads the
+ same as we do other expressions. This requires iterative
+ hashing the vuses into the values. Right now we simply assign
+ a new value every time we see a statement with a vuse.
+ 3. Strength reduction can be performed by anticipating expressions
+ we can repair later on.
+ 4. Our canonicalization of expressions during lookups don't take
+ constants into account very well. In particular, we don't fold
+ anywhere, so we can get situations where we stupidly think
+ something is a new value (a + 1 + 1 vs a + 2). This is somewhat
+ expensive to fix, but it does expose a lot more eliminations.
+ It may or not be worth it, depending on how critical you
+ consider PRE vs just plain GRE.
+*/
+
+/* For ease of terminology, "expression node" in the below refers to
+ every expression node but MODIFY_EXPR, because MODIFY_EXPR's represent
+ the actual statement containing the expressions we care about, and
+ we cache the value number by putting it in the expression. */
+
+/* Basic algorithm
+
+ First we walk the statements to generate the AVAIL sets, the
+ EXP_GEN sets, and the tmp_gen sets. EXP_GEN sets represent the
+ generation of values/expressions by a given block. We use them
+ when computing the ANTIC sets. The AVAIL sets consist of
+ SSA_NAME's that represent values, so we know what values are
+ available in what blocks. AVAIL is a forward dataflow problem. In
+ SSA, values are never killed, so we don't need a kill set, or a
+ fixpoint iteration, in order to calculate the AVAIL sets. In
+ traditional parlance, AVAIL sets tell us the downsafety of the
+ expressions/values.
+
+ Next, we generate the ANTIC sets. These sets represent the
+ anticipatable expressions. ANTIC is a backwards dataflow
+ problem.An expression is anticipatable in a given block if it could
+ be generated in that block. This means that if we had to perform
+ an insertion in that block, of the value of that expression, we
+ could. Calculating the ANTIC sets requires phi translation of
+ expressions, because the flow goes backwards through phis. We must
+ iterate to a fixpoint of the ANTIC sets, because we have a kill
+ set. Even in SSA form, values are not live over the entire
+ function, only from their definition point onwards. So we have to
+ remove values from the ANTIC set once we go past the definition
+ point of the leaders that make them up.
+ compute_antic/compute_antic_aux performs this computation.
+
+ Third, we perform insertions to make partially redundant
+ expressions fully redundant.
+
+ An expression is partially redundant (excluding partial
+ anticipation) if:
+
+ 1. It is AVAIL in some, but not all, of the predecessors of a
+ given block.
+ 2. It is ANTIC in all the predecessors.
+
+ In order to make it fully redundant, we insert the expression into
+ the predecessors where it is not available, but is ANTIC.
+ insert/insert_aux performs this insertion.
+
+ Fourth, we eliminate fully redundant expressions.
+ This is a simple statement walk that replaces redundant
+ calculations with the now available values. */
+
+/* Representations of value numbers:
+
+ Value numbers are represented using the "value handle" approach.
+ This means that each SSA_NAME (and for other reasons to be
+ disclosed in a moment, expression nodes) has a value handle that
+ can be retrieved through get_value_handle. This value handle, *is*
+ the value number of the SSA_NAME. You can pointer compare the
+ value handles for equivalence purposes.
+
+ For debugging reasons, the value handle is internally more than
+ just a number, it is a VAR_DECL named "value.x", where x is a
+ unique number for each value number in use. This allows
+ expressions with SSA_NAMES replaced by value handles to still be
+ pretty printed in a sane way. They simply print as "value.3 *
+ value.5", etc.
+
+ Expression nodes have value handles associated with them as a
+ cache. Otherwise, we'd have to look them up again in the hash
+ table This makes significant difference (factor of two or more) on
+ some test cases. They can be thrown away after the pass is
+ finished. */
+
+/* Representation of expressions on value numbers:
+
+ In some portions of this code, you will notice we allocate "fake"
+ analogues to the expression we are value numbering, and replace the
+ operands with the values of the expression. Since we work on
+ values, and not just names, we canonicalize expressions to value
+ expressions for use in the ANTIC sets, the EXP_GEN set, etc.
+
+ This is theoretically unnecessary, it just saves a bunch of
+ repeated get_value_handle and find_leader calls in the remainder of
+ the code, trading off temporary memory usage for speed. The tree
+ nodes aren't actually creating more garbage, since they are
+ allocated in a special pools which are thrown away at the end of
+ this pass.
+
+ All of this also means that if you print the EXP_GEN or ANTIC sets,
+ you will see "value.5 + value.7" in the set, instead of "a_55 +
+ b_66" or something. The only thing that actually cares about
+ seeing the value leaders is phi translation, and it needs to be
+ able to find the leader for a value in an arbitrary block, so this
+ "value expression" form is perfect for it (otherwise you'd do
+ get_value_handle->find_leader->translate->get_value_handle->find_leader).*/
+
+
+/* Representation of sets:
+
+ There are currently two types of sets used, hopefully to be unified soon.
+ The AVAIL sets do not need to be sorted in any particular order,
+ and thus, are simply represented as two bitmaps, one that keeps
+ track of values present in the set, and one that keeps track of
+ expressions present in the set.
+
+ The other sets are represented as doubly linked lists kept in topological
+ order, with an optional supporting bitmap of values present in the
+ set. The sets represent values, and the elements can be values or
+ expressions. The elements can appear in different sets, but each
+ element can only appear once in each set.
+
+ Since each node in the set represents a value, we also want to be
+ able to map expression, set pairs to something that tells us
+ whether the value is present is a set. We use a per-set bitmap for
+ that. The value handles also point to a linked list of the
+ expressions they represent via a tree annotation. This is mainly
+ useful only for debugging, since we don't do identity lookups. */
+
+
+/* A value set element. Basically a single linked list of
+ expressions/values. */
+typedef struct value_set_node
+{
+ /* An expression. */
+ tree expr;
+
+ /* A pointer to the next element of the value set. */
+ struct value_set_node *next;
+} *value_set_node_t;
+
+
+/* A value set. This is a singly linked list of value_set_node
+ elements with a possible bitmap that tells us what values exist in
+ the set. This set must be kept in topologically sorted order. */
+typedef struct value_set
+{
+ /* The head of the list. Used for iterating over the list in
+ order. */
+ value_set_node_t head;
+
+ /* The tail of the list. Used for tail insertions, which are
+ necessary to keep the set in topologically sorted order because
+ of how the set is built. */
+ value_set_node_t tail;
+
+ /* The length of the list. */
+ size_t length;
+
+ /* True if the set is indexed, which means it contains a backing
+ bitmap for quick determination of whether certain values exist in the
+ set. */
+ bool indexed;
+
+ /* The bitmap of values that exist in the set. May be NULL in an
+ empty or non-indexed set. */
+ bitmap values;
+
+} *value_set_t;
+
+
+/* An unordered bitmap set. One bitmap tracks values, the other,
+ expressions. */
+typedef struct bitmap_set
+{
+ bitmap expressions;
+ bitmap values;
+} *bitmap_set_t;
+
+/* Sets that we need to keep track of. */
+typedef struct bb_value_sets
+{
+ /* The EXP_GEN set, which represents expressions/values generated in
+ a basic block. */
+ value_set_t exp_gen;
+
+ /* The PHI_GEN set, which represents PHI results generated in a
+ basic block. */
+ bitmap_set_t phi_gen;
+
+ /* The TMP_GEN set, which represents results/temporaries generated
+ in a basic block. IE the LHS of an expression. */
+ bitmap_set_t tmp_gen;
+
+ /* The AVAIL_OUT set, which represents which values are available in
+ a given basic block. */
+ bitmap_set_t avail_out;
+
+ /* The ANTIC_IN set, which represents which values are anticiptable
+ in a given basic block. */
+ value_set_t antic_in;
+
+ /* The NEW_SETS set, which is used during insertion to augment the
+ AVAIL_OUT set of blocks with the new insertions performed during
+ the current iteration. */
+ bitmap_set_t new_sets;
+} *bb_value_sets_t;
+
+#define EXP_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->exp_gen
+#define PHI_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->phi_gen
+#define TMP_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->tmp_gen
+#define AVAIL_OUT(BB) ((bb_value_sets_t) ((BB)->aux))->avail_out
+#define ANTIC_IN(BB) ((bb_value_sets_t) ((BB)->aux))->antic_in
+#define NEW_SETS(BB) ((bb_value_sets_t) ((BB)->aux))->new_sets
+
+/* This structure is used to keep track of statistics on what
+ optimization PRE was able to perform. */
+static struct
+{
+ /* The number of RHS computations eliminated by PRE. */
+ int eliminations;
+
+ /* The number of new expressions/temporaries generated by PRE. */
+ int insertions;
+
+ /* The number of new PHI nodes added by PRE. */
+ int phis;
+} pre_stats;
+
+
+static tree bitmap_find_leader (bitmap_set_t, tree);
+static tree find_leader (value_set_t, tree);
+static void value_insert_into_set (value_set_t, tree);
+static void bitmap_value_insert_into_set (bitmap_set_t, tree);
+static void bitmap_value_replace_in_set (bitmap_set_t, tree);
+static void insert_into_set (value_set_t, tree);
+static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
+static bool bitmap_set_contains_value (bitmap_set_t, tree);
+static bitmap_set_t bitmap_set_new (void);
+static value_set_t set_new (bool);
+static bool is_undefined_value (tree);
+static tree create_expression_by_pieces (basic_block, tree, tree);
+
+
+/* We can add and remove elements and entries to and from sets
+ and hash tables, so we use alloc pools for them. */
+
+static alloc_pool value_set_pool;
+static alloc_pool bitmap_set_pool;
+static alloc_pool value_set_node_pool;
+static alloc_pool binary_node_pool;
+static alloc_pool unary_node_pool;
+static alloc_pool reference_node_pool;
+
+/* The phi_translate_table caches phi translations for a given
+ expression and predecessor. */
+
+static htab_t phi_translate_table;
+
+/* A three tuple {e, pred, v} used to cache phi translations in the
+ phi_translate_table. */
+
+typedef struct expr_pred_trans_d
+{
+ /* The expression. */
+ tree e;
+
+ /* The predecessor block along which we translated the expression. */
+ basic_block pred;
+
+ /* The value that resulted from the translation. */
+ tree v;
+
+ /* The hashcode for the expression, pred pair. This is cached for
+ speed reasons. */
+ hashval_t hashcode;
+} *expr_pred_trans_t;
+
+/* Return the hash value for a phi translation table entry. */
+
+static hashval_t
+expr_pred_trans_hash (const void *p)
+{
+ const expr_pred_trans_t ve = (expr_pred_trans_t) p;
+ return ve->hashcode;
+}
+
+/* Return true if two phi translation table entries are the same.
+ P1 and P2 should point to the expr_pred_trans_t's to be compared.*/
+
+static int
+expr_pred_trans_eq (const void *p1, const void *p2)
+{
+ const expr_pred_trans_t ve1 = (expr_pred_trans_t) p1;
+ const expr_pred_trans_t ve2 = (expr_pred_trans_t) p2;
+ basic_block b1 = ve1->pred;
+ basic_block b2 = ve2->pred;
+
+
+ /* If they are not translations for the same basic block, they can't
+ be equal. */
+ if (b1 != b2)
+ return false;
+
+ /* If they are for the same basic block, determine if the
+ expressions are equal. */
+ if (expressions_equal_p (ve1->e, ve2->e))
+ return true;
+
+ return false;
+}
+
+/* Search in the phi translation table for the translation of
+ expression E in basic block PRED. Return the translated value, if
+ found, NULL otherwise. */
+
+static inline tree
+phi_trans_lookup (tree e, basic_block pred)
+{
+ void **slot;
+ struct expr_pred_trans_d ept;
+ ept.e = e;
+ ept.pred = pred;
+ ept.hashcode = vn_compute (e, (unsigned long) pred, NULL);
+ slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
+ NO_INSERT);
+ if (!slot)
+ return NULL;
+ else
+ return ((expr_pred_trans_t) *slot)->v;
+}
+
+
+/* Add the tuple mapping from {expression E, basic block PRED} to
+ value V, to the phi translation table. */
+
+static inline void
+phi_trans_add (tree e, tree v, basic_block pred)
+{
+ void **slot;
+ expr_pred_trans_t new_pair = xmalloc (sizeof (*new_pair));
+ new_pair->e = e;
+ new_pair->pred = pred;
+ new_pair->v = v;
+ new_pair->hashcode = vn_compute (e, (unsigned long) pred, NULL);
+ slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
+ new_pair->hashcode, INSERT);
+ if (*slot)
+ free (*slot);
+ *slot = (void *) new_pair;
+}
+
+
+/* Add expression E to the expression set of value V. */
+
+void
+add_to_value (tree v, tree e)
+{
+ /* Constants have no expression sets. */
+ if (is_gimple_min_invariant (v))
+ return;
+
+ if (VALUE_HANDLE_EXPR_SET (v) == NULL)
+ VALUE_HANDLE_EXPR_SET (v) = set_new (false);
+
+ insert_into_set (VALUE_HANDLE_EXPR_SET (v), e);
+}
+
+
+/* Return true if value V exists in the bitmap for SET. */
+
+static inline bool
+value_exists_in_set_bitmap (value_set_t set, tree v)
+{
+ if (!set->values)
+ return false;
+
+ return bitmap_bit_p (set->values, VALUE_HANDLE_ID (v));
+}
+
+
+/* Remove value V from the bitmap for SET. */
+
+static void
+value_remove_from_set_bitmap (value_set_t set, tree v)
+{
+#ifdef ENABLE_CHECKING
+ if (!set->indexed)
+ abort ();
+#endif
+
+ if (!set->values)
+ return;
+
+ bitmap_clear_bit (set->values, VALUE_HANDLE_ID (v));
+}
+
+
+/* Insert the value number V into the bitmap of values existing in
+ SET. */
+
+static inline void
+value_insert_into_set_bitmap (value_set_t set, tree v)
+{
+#ifdef ENABLE_CHECKING
+ if (!set->indexed)
+ abort ();
+#endif
+
+ if (set->values == NULL)
+ {
+ set->values = BITMAP_GGC_ALLOC ();
+ bitmap_clear (set->values);
+ }
+
+ bitmap_set_bit (set->values, VALUE_HANDLE_ID (v));
+}
+
+
+/* Create a new bitmap set and return it. */
+
+static bitmap_set_t
+bitmap_set_new (void)
+{
+ bitmap_set_t ret = pool_alloc (bitmap_set_pool);
+ ret->expressions = BITMAP_GGC_ALLOC ();
+ ret->values = BITMAP_GGC_ALLOC ();
+ bitmap_clear (ret->expressions);
+ bitmap_clear (ret->values);
+ return ret;
+}
+
+/* Create a new set. */
+
+static value_set_t
+set_new (bool indexed)
+{
+ value_set_t ret;
+ ret = pool_alloc (value_set_pool);
+ ret->head = ret->tail = NULL;
+ ret->length = 0;
+ ret->indexed = indexed;
+ ret->values = NULL;
+ return ret;
+}
+
+/* Insert an expression EXPR into a bitmapped set. */
+
+static void
+bitmap_insert_into_set (bitmap_set_t set, tree expr)
+{
+ tree val;
+ /* XXX: For now, we only let SSA_NAMES into the bitmap sets. */
+ if (TREE_CODE (expr) != SSA_NAME)
+ abort ();
+ val = get_value_handle (expr);
+
+ if (val == NULL)
+ abort ();
+ if (!is_gimple_min_invariant (val))
+ bitmap_set_bit (set->values, VALUE_HANDLE_ID (val));
+ bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
+}
+
+/* Insert EXPR into SET. */
+
+static void
+insert_into_set (value_set_t set, tree expr)
+{
+ value_set_node_t newnode = pool_alloc (value_set_node_pool);
+ tree val = get_value_handle (expr);
+
+ if (val == NULL)
+ abort ();
+
+ /* For indexed sets, insert the value into the set value bitmap.
+ For all sets, add it to the linked list and increment the list
+ length. */
+ if (set->indexed)
+ value_insert_into_set_bitmap (set, val);
+
+ newnode->next = NULL;
+ newnode->expr = expr;
+ set->length ++;
+ if (set->head == NULL)
+ {
+ set->head = set->tail = newnode;
+ }
+ else
+ {
+ set->tail->next = newnode;
+ set->tail = newnode;
+ }
+}
+
+/* Copy a bitmapped set ORIG, into bitmapped set DEST. */
+
+static void
+bitmap_set_copy (bitmap_set_t dest, bitmap_set_t orig)
+{
+ bitmap_copy (dest->expressions, orig->expressions);
+ bitmap_copy (dest->values, orig->values);
+}
+
+/* Copy the set ORIG to the set DEST. */
+
+static void
+set_copy (value_set_t dest, value_set_t orig)
+{
+ value_set_node_t node;
+
+ if (!orig || !orig->head)
+ return;
+
+ for (node = orig->head;
+ node;
+ node = node->next)
+ {
+ insert_into_set (dest, node->expr);
+ }
+}
+
+/* Remove EXPR from SET. */
+
+static void
+set_remove (value_set_t set, tree expr)
+{
+ value_set_node_t node, prev;
+
+ /* Remove the value of EXPR from the bitmap, decrement the set
+ length, and remove it from the actual double linked list. */
+ value_remove_from_set_bitmap (set, get_value_handle (expr));
+ set->length--;
+ prev = NULL;
+ for (node = set->head;
+ node != NULL;
+ prev = node, node = node->next)
+ {
+ if (node->expr == expr)
+ {
+ if (prev == NULL)
+ set->head = node->next;
+ else
+ prev->next= node->next;
+
+ if (node == set->tail)
+ set->tail = prev;
+ pool_free (value_set_node_pool, node);
+ return;
+ }
+ }
+}
+
+/* Return true if SET contains the value VAL. */
+
+static bool
+set_contains_value (value_set_t set, tree val)
+{
+ /* All constants are in every set. */
+ if (is_gimple_min_invariant (val))
+ return true;
+
+ if (set->length == 0)
+ return false;
+
+ return value_exists_in_set_bitmap (set, val);
+}
+
+/* Return true if bitmapped set SET contains the expression EXPR. */
+static bool
+bitmap_set_contains (bitmap_set_t set, tree expr)
+{
+ /* XXX: Bitmapped sets only contain SSA_NAME's for now. */
+ if (TREE_CODE (expr) != SSA_NAME)
+ return false;
+ return bitmap_bit_p (set->expressions, SSA_NAME_VERSION (expr));
+}
+
+
+/* Return true if bitmapped set SET contains the value VAL. */
+
+static bool
+bitmap_set_contains_value (bitmap_set_t set, tree val)
+{
+ if (is_gimple_min_invariant (val))
+ return true;
+ return bitmap_bit_p (set->values, VALUE_HANDLE_ID (val));
+}
+
+/* Replace an instance of value LOOKFOR with expression EXPR in SET. */
+
+static void
+bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr)
+{
+ value_set_t exprset;
+ value_set_node_t node;
+ if (is_gimple_min_invariant (lookfor))
+ return;
+ if (!bitmap_set_contains_value (set, lookfor))
+ return;
+ /* The number of expressions having a given value is usually
+ significantly less than the total number of expressions in SET.
+ Thus, rather than check, for each expression in SET, whether it
+ has the value LOOKFOR, we walk the reverse mapping that tells us
+ what expressions have a given value, and see if any of those
+ expressions are in our set. For large testcases, this is about
+ 5-10x faster than walking the bitmap. If this is somehow a
+ significant lose for some cases, we can choose which set to walk
+ based on the set size. */
+ exprset = VALUE_HANDLE_EXPR_SET (lookfor);
+ for (node = exprset->head; node; node = node->next)
+ {
+ if (TREE_CODE (node->expr) == SSA_NAME)
+ {
+ if (bitmap_bit_p (set->expressions, SSA_NAME_VERSION (node->expr)))
+ {
+ bitmap_clear_bit (set->expressions, SSA_NAME_VERSION (node->expr));
+ bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
+ return;
+ }
+ }
+ }
+}
+
+/* Subtract bitmapped set B from value set A, and return the new set. */
+
+static value_set_t
+bitmap_set_subtract_from_value_set (value_set_t a, bitmap_set_t b,
+ bool indexed)
+{
+ value_set_t ret = set_new (indexed);
+ value_set_node_t node;
+ for (node = a->head;
+ node;
+ node = node->next)
+ {
+ if (!bitmap_set_contains (b, node->expr))
+ insert_into_set (ret, node->expr);
+ }
+ return ret;
+}
+
+/* Return true if two sets are equal. */
+
+static bool
+set_equal (value_set_t a, value_set_t b)
+{
+ value_set_node_t node;
+
+ if (a->length != b->length)
+ return false;
+ for (node = a->head;
+ node;
+ node = node->next)
+ {
+ if (!set_contains_value (b, get_value_handle (node->expr)))
+ return false;
+ }
+ return true;
+}
+
+/* Replace an instance of EXPR's VALUE with EXPR in SET. */
+
+static void
+bitmap_value_replace_in_set (bitmap_set_t set, tree expr)
+{
+ tree val = get_value_handle (expr);
+ bitmap_set_replace_value (set, val, expr);
+}
+
+/* Insert EXPR into SET if EXPR's value is not already present in
+ SET. */
+
+static void
+bitmap_value_insert_into_set (bitmap_set_t set, tree expr)
+{
+ tree val = get_value_handle (expr);
+ if (is_gimple_min_invariant (val))
+ return;
+
+ if (!bitmap_set_contains_value (set, val))
+ bitmap_insert_into_set (set, expr);
+}
+
+/* Insert the value for EXPR into SET, if it doesn't exist already. */
+
+static void
+value_insert_into_set (value_set_t set, tree expr)
+{
+ tree val = get_value_handle (expr);
+
+ /* Constant and invariant values exist everywhere, and thus,
+ actually keeping them in the sets is pointless. */
+ if (is_gimple_min_invariant (val))
+ return;
+
+ if (!set_contains_value (set, val))
+ insert_into_set (set, expr);
+}
+
+
+/* Print out SET to OUTFILE. */
+
+static void
+bitmap_print_value_set (FILE *outfile, bitmap_set_t set,
+ const char *setname, int blockindex)
+{
+ fprintf (outfile, "%s[%d] := { ", setname, blockindex);
+ if (set)
+ {
+ int i;
+ EXECUTE_IF_SET_IN_BITMAP (set->expressions, 0, i,
+ {
+ print_generic_expr (outfile, ssa_name (i), 0);
+
+ fprintf (outfile, " (");
+ print_generic_expr (outfile, get_value_handle (ssa_name (i)), 0);
+ fprintf (outfile, ") ");
+ if (bitmap_last_set_bit (set->expressions) != i)
+ fprintf (outfile, ", ");
+ });
+ }
+ fprintf (outfile, " }\n");
+}
+/* Print out the value_set SET to OUTFILE. */
+
+static void
+print_value_set (FILE *outfile, value_set_t set,
+ const char *setname, int blockindex)
+{
+ value_set_node_t node;
+ fprintf (outfile, "%s[%d] := { ", setname, blockindex);
+ if (set)
+ {
+ for (node = set->head;
+ node;
+ node = node->next)
+ {
+ print_generic_expr (outfile, node->expr, 0);
+
+ fprintf (outfile, " (");
+ print_generic_expr (outfile, get_value_handle (node->expr), 0);
+ fprintf (outfile, ") ");
+
+ if (node->next)
+ fprintf (outfile, ", ");
+ }
+ }
+
+ fprintf (outfile, " }\n");
+}
+
+/* Print out the expressions that have VAL to OUTFILE. */
+
+void
+print_value_expressions (FILE *outfile, tree val)
+{
+ if (VALUE_HANDLE_EXPR_SET (val))
+ {
+ char s[10];
+ sprintf (s, "VH.%04d", VALUE_HANDLE_ID (val));
+ print_value_set (outfile, VALUE_HANDLE_EXPR_SET (val), s, 0);
+ }
+}
+
+
+void
+debug_value_expressions (tree val)
+{
+ print_value_expressions (stderr, val);
+}
+
+
+void debug_value_set (value_set_t, const char *, int);
+
+void
+debug_value_set (value_set_t set, const char *setname, int blockindex)
+{
+ print_value_set (stderr, set, setname, blockindex);
+}
+
+/* Translate EXPR using phis in PHIBLOCK, so that it has the values of
+ the phis in PRED. Return NULL if we can't find a leader for each
+ part of the translated expression. */
+
+static tree
+phi_translate (tree expr, value_set_t set, basic_block pred,
+ basic_block phiblock)
+{
+ tree phitrans = NULL;
+ tree oldexpr = expr;
+
+ if (expr == NULL)
+ return NULL;
+
+ /* Phi translations of a given expression don't change, */
+ phitrans = phi_trans_lookup (expr, pred);
+ if (phitrans)
+ return phitrans;
+
+
+ switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ {
+ case '2':
+ {
+ tree oldop1 = TREE_OPERAND (expr, 0);
+ tree oldop2 = TREE_OPERAND (expr, 1);
+ tree newop1;
+ tree newop2;
+ tree newexpr;
+
+ newop1 = phi_translate (find_leader (set, oldop1),
+ set, pred, phiblock);
+ if (newop1 == NULL)
+ return NULL;
+ newop2 = phi_translate (find_leader (set, oldop2),
+ set, pred, phiblock);
+ if (newop2 == NULL)
+ return NULL;
+ if (newop1 != oldop1 || newop2 != oldop2)
+ {
+ newexpr = pool_alloc (binary_node_pool);
+ memcpy (newexpr, expr, tree_size (expr));
+ create_tree_ann (newexpr);
+ TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldop1 : get_value_handle (newop1);
+ TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
+ vn_lookup_or_add (newexpr, NULL);
+ expr = newexpr;
+ phi_trans_add (oldexpr, newexpr, pred);
+ }
+ }
+ break;
+ /* XXX: Until we have PRE of loads working, none will be ANTIC.
+ */
+ case 'r':
+ return NULL;
+ break;
+ case '1':
+ {
+ tree oldop1 = TREE_OPERAND (expr, 0);
+ tree newop1;
+ tree newexpr;
+
+ newop1 = phi_translate (find_leader (set, oldop1),
+ set, pred, phiblock);
+ if (newop1 == NULL)
+ return NULL;
+ if (newop1 != oldop1)
+ {
+ newexpr = pool_alloc (unary_node_pool);
+ memcpy (newexpr, expr, tree_size (expr));
+ create_tree_ann (newexpr);
+ TREE_OPERAND (newexpr, 0) = get_value_handle (newop1);
+ vn_lookup_or_add (newexpr, NULL);
+ expr = newexpr;
+ phi_trans_add (oldexpr, newexpr, pred);
+ }
+ }
+ break;
+ case 'd':
+ abort ();
+ case 'x':
+ {
+ tree phi = NULL;
+ int i;
+ if (TREE_CODE (expr) != SSA_NAME)
+ abort ();
+ if (TREE_CODE (SSA_NAME_DEF_STMT (expr)) == PHI_NODE)
+ phi = SSA_NAME_DEF_STMT (expr);
+ else
+ return expr;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ if (PHI_ARG_EDGE (phi, i)->src == pred)
+ {
+ tree val;
+ if (is_undefined_value (PHI_ARG_DEF (phi, i)))
+ return NULL;
+ val = vn_lookup_or_add (PHI_ARG_DEF (phi, i), NULL);
+ return PHI_ARG_DEF (phi, i);
+ }
+ }
+ break;
+ }
+ return expr;
+}
+
+static void
+phi_translate_set (value_set_t dest, value_set_t set, basic_block pred,
+ basic_block phiblock)
+{
+ value_set_node_t node;
+ for (node = set->head;
+ node;
+ node = node->next)
+ {
+ tree translated;
+ translated = phi_translate (node->expr, set, pred, phiblock);
+ phi_trans_add (node->expr, translated, pred);
+
+ if (translated != NULL)
+ value_insert_into_set (dest, translated);
+ }
+}
+
+/* Find the leader for a value (i.e., the name representing that
+ value) in a given set, and return it. Return NULL if no leader is
+ found. */
+
+static tree
+bitmap_find_leader (bitmap_set_t set, tree val)
+{
+ if (val == NULL)
+ return NULL;
+
+ if (is_gimple_min_invariant (val))
+ return val;
+ if (bitmap_set_contains_value (set, val))
+ {
+ /* Rather than walk the entire bitmap of expressions, and see
+ whether any of them has the value we are looking for, we look
+ at the reverse mapping, which tells us the set of expressions
+ that have a given value (IE value->expressions with that
+ value) and see if any of those expressions are in our set.
+ The number of expressions per value is usually significantly
+ less than the number of expressions in the set. In fact, for
+ large testcases, doing it this way is roughly 5-10x faster
+ than walking the bitmap.
+ If this is somehow a significant lose for some cases, we can
+ choose which set to walk based on which set is smaller. */
+ value_set_t exprset;
+ value_set_node_t node;
+ exprset = VALUE_HANDLE_EXPR_SET (val);
+ for (node = exprset->head; node; node = node->next)
+ {
+ if (TREE_CODE (node->expr) == SSA_NAME)
+ {
+ if (bitmap_bit_p (set->expressions,
+ SSA_NAME_VERSION (node->expr)))
+ return node->expr;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+/* Find the leader for a value (i.e., the name representing that
+ value) in a given set, and return it. Return NULL if no leader is
+ found. */
+
+static tree
+find_leader (value_set_t set, tree val)
+{
+ value_set_node_t node;
+
+ if (val == NULL)
+ return NULL;
+
+ /* Constants represent themselves. */
+ if (is_gimple_min_invariant (val))
+ return val;
+
+ if (set->length == 0)
+ return NULL;
+
+ if (value_exists_in_set_bitmap (set, val))
+ {
+ for (node = set->head;
+ node;
+ node = node->next)
+ {
+ if (get_value_handle (node->expr) == val)
+ return node->expr;
+ }
+ }
+
+ return NULL;
+}
+
+/* Determine if the expression EXPR is valid in SET. This means that
+ we have a leader for each part of the expression (if it consists of
+ values), or the expression is an SSA_NAME.
+
+ NB: We never should run into a case where we have SSA_NAME +
+ SSA_NAME or SSA_NAME + value. The sets valid_in_set is called on,
+ the ANTIC sets, will only ever have SSA_NAME's or binary value
+ expression (IE VALUE1 + VALUE2) */
+
+static bool
+valid_in_set (value_set_t set, tree expr)
+{
+ switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ {
+ case '2':
+ {
+ tree op1 = TREE_OPERAND (expr, 0);
+ tree op2 = TREE_OPERAND (expr, 1);
+ return set_contains_value (set, op1) && set_contains_value (set, op2);
+ }
+ break;
+ case '1':
+ {
+ tree op1 = TREE_OPERAND (expr, 0);
+ return set_contains_value (set, op1);
+ }
+ break;
+ /* XXX: Until PRE of loads works, no reference nodes are ANTIC.
+ */
+ case 'r':
+ {
+ return false;
+ }
+ case 'x':
+ {
+ if (TREE_CODE (expr) == SSA_NAME)
+ return true;
+ abort ();
+ }
+ case 'c':
+ abort ();
+ }
+ return false;
+}
+
+/* Clean the set of expressions that are no longer valid in SET. This
+ means expressions that are made up of values we have no leaders for
+ in SET. */
+
+static void
+clean (value_set_t set)
+{
+ value_set_node_t node;
+ value_set_node_t next;
+ node = set->head;
+ while (node)
+ {
+ next = node->next;
+ if (!valid_in_set (set, node->expr))
+ set_remove (set, node->expr);
+ node = next;
+ }
+}
+
+/* Compute the ANTIC set for BLOCK.
+
+ANTIC_OUT[BLOCK] = intersection of ANTIC_IN[b] for all succ(BLOCK), if
+succs(BLOCK) > 1
+ANTIC_OUT[BLOCK] = phi_translate (ANTIC_IN[succ(BLOCK)]) if
+succs(BLOCK) == 1
+
+ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] -
+TMP_GEN[BLOCK])
+
+Iterate until fixpointed.
+
+XXX: It would be nice to either write a set_clear, and use it for
+antic_out, or to mark the antic_out set as deleted at the end
+of this routine, so that the pool can hand the same memory back out
+again for the next antic_out. */
+
+
+static bool
+compute_antic_aux (basic_block block)
+{
+ basic_block son;
+ edge e;
+ bool changed = false;
+ value_set_t S, old, ANTIC_OUT;
+ value_set_node_t node;
+
+ ANTIC_OUT = S = NULL;
+ /* If any edges from predecessors are abnormal, antic_in is empty, so
+ punt. Remember that the block has an incoming abnormal edge by
+ setting the BB_VISITED flag. */
+ if (! (block->flags & BB_VISITED))
+ {
+ for (e = block->pred; e; e = e->pred_next)
+ if (e->flags & EDGE_ABNORMAL)
+ {
+ block->flags |= BB_VISITED;
+ break;
+ }
+ }
+ if (block->flags & BB_VISITED)
+ {
+ S = NULL;
+ goto visit_sons;
+ }
+
+
+ old = set_new (false);
+ set_copy (old, ANTIC_IN (block));
+ ANTIC_OUT = set_new (true);
+
+ /* If the block has no successors, ANTIC_OUT is empty, because it is
+ the exit block. */
+ if (block->succ == NULL);
+
+ /* If we have one successor, we could have some phi nodes to
+ translate through. */
+ else if (block->succ->succ_next == NULL)
+ {
+ phi_translate_set (ANTIC_OUT, ANTIC_IN(block->succ->dest),
+ block, block->succ->dest);
+ }
+ /* If we have multiple successors, we take the intersection of all of
+ them. */
+ else
+ {
+ varray_type worklist;
+ edge e;
+ size_t i;
+ basic_block bprime, first;
+
+ VARRAY_BB_INIT (worklist, 1, "succ");
+ e = block->succ;
+ while (e)
+ {
+ VARRAY_PUSH_BB (worklist, e->dest);
+ e = e->succ_next;
+ }
+ first = VARRAY_BB (worklist, 0);
+ set_copy (ANTIC_OUT, ANTIC_IN (first));
+
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (worklist); i++)
+ {
+ bprime = VARRAY_BB (worklist, i);
+ node = ANTIC_OUT->head;
+ while (node)
+ {
+ tree val;
+ value_set_node_t next = node->next;
+ val = get_value_handle (node->expr);
+ if (!set_contains_value (ANTIC_IN (bprime), val))
+ set_remove (ANTIC_OUT, node->expr);
+ node = next;
+ }
+ }
+ VARRAY_CLEAR (worklist);
+ }
+
+ /* Generate ANTIC_OUT - TMP_GEN */
+ S = bitmap_set_subtract_from_value_set (ANTIC_OUT, TMP_GEN (block), false);
+
+ /* Start ANTIC_IN with EXP_GEN - TMP_GEN */
+ ANTIC_IN (block) = bitmap_set_subtract_from_value_set (EXP_GEN (block),
+ TMP_GEN (block),
+ true);
+
+ /* Then union in the ANTIC_OUT - TMP_GEN values, to get ANTIC_OUT U
+ EXP_GEN - TMP_GEN */
+ for (node = S->head;
+ node;
+ node = node->next)
+ {
+ value_insert_into_set (ANTIC_IN (block), node->expr);
+ }
+ clean (ANTIC_IN (block));
+
+
+ if (!set_equal (old, ANTIC_IN (block)))
+ changed = true;
+
+ visit_sons:
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ if (ANTIC_OUT)
+ print_value_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);
+ print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index);
+ if (S)
+ print_value_set (dump_file, S, "S", block->index);
+
+ }
+
+ for (son = first_dom_son (CDI_POST_DOMINATORS, block);
+ son;
+ son = next_dom_son (CDI_POST_DOMINATORS, son))
+ {
+ changed |= compute_antic_aux (son);
+ }
+ return changed;
+}
+
+/* Compute ANTIC sets. */
+
+static void
+compute_antic (void)
+{
+ bool changed = true;
+ basic_block bb;
+ int num_iterations = 0;
+ FOR_ALL_BB (bb)
+ {
+ ANTIC_IN (bb) = set_new (true);
+ if (bb->flags & BB_VISITED)
+ abort ();
+ }
+
+ while (changed)
+ {
+ num_iterations++;
+ changed = false;
+ changed = compute_antic_aux (EXIT_BLOCK_PTR);
+ }
+ FOR_ALL_BB (bb)
+ {
+ bb->flags &= ~BB_VISITED;
+ }
+ if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
+ fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
+}
+
+
+/* Find a leader for an expression, or generate one using
+ create_expression_by_pieces if it's ANTIC but
+ complex.
+ BLOCK is the basic_block we are looking for leaders in.
+ EXPR is the expression to find a leader or generate for.
+ STMTS is the statement list to put the inserted expressions on.
+ Returns the SSA_NAME of the LHS of the generated expression or the
+ leader. */
+
+static tree
+find_or_generate_expression (basic_block block, tree expr, tree stmts)
+{
+ tree genop;
+ genop = bitmap_find_leader (AVAIL_OUT (block), expr);
+ /* Depending on the order we process DOM branches in, the value
+ may not have propagated to all the dom children yet during
+ this iteration. In this case, the value will always be in
+ the NEW_SETS for us already, having been propagated from our
+ dominator. */
+ if (genop == NULL)
+ genop = bitmap_find_leader (NEW_SETS (block), expr);
+ /* If it's still NULL, see if it is a complex expression, and if
+ so, generate it recursively, otherwise, abort, because it's
+ not really . */
+ if (genop == NULL)
+ {
+ genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
+ if (TREE_CODE_CLASS (TREE_CODE (genop)) != '1'
+ && TREE_CODE_CLASS (TREE_CODE (genop)) != '2'
+ && TREE_CODE_CLASS (TREE_CODE (genop)) != 'r')
+ abort ();
+ genop = create_expression_by_pieces (block, genop, stmts);
+ }
+ return genop;
+}
+
+
+/* Create an expression in pieces, so that we can handle very complex
+ expressions that may be ANTIC, but not necessary GIMPLE.
+ BLOCK is the basic block the expression will be inserted into,
+ EXPR is the expression to insert (in value form)
+ STMTS is a statement list to append the necessary insertions into.
+
+ This function will abort if we hit some value that shouldn't be
+ ANTIC but is (IE there is no leader for it, or its components).
+ This function may also generate expressions that are themselves
+ partially or fully redundant. Those that are will be either made
+ fully redundant during the next iteration of insert (for partially
+ redundant ones), or eliminated by eliminate (for fully redundant
+ ones). */
+
+static tree
+create_expression_by_pieces (basic_block block, tree expr, tree stmts)
+{
+ tree name = NULL_TREE;
+ tree newexpr = NULL_TREE;
+ tree v;
+
+ switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ {
+ case '2':
+ {
+ tree_stmt_iterator tsi;
+ tree genop1, genop2;
+ tree temp;
+ tree op1 = TREE_OPERAND (expr, 0);
+ tree op2 = TREE_OPERAND (expr, 1);
+ genop1 = find_or_generate_expression (block, op1, stmts);
+ genop2 = find_or_generate_expression (block, op2, stmts);
+ temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
+ add_referenced_tmp_var (temp);
+ newexpr = build (TREE_CODE (expr), TREE_TYPE (expr),
+ genop1, genop2);
+ newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
+ temp, newexpr);
+ name = make_ssa_name (temp, newexpr);
+ TREE_OPERAND (newexpr, 0) = name;
+ tsi = tsi_last (stmts);
+ tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
+ pre_stats.insertions++;
+ break;
+ }
+ case '1':
+ {
+ tree_stmt_iterator tsi;
+ tree genop1;
+ tree temp;
+ tree op1 = TREE_OPERAND (expr, 0);
+ genop1 = find_or_generate_expression (block, op1, stmts);
+ temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
+ add_referenced_tmp_var (temp);
+ newexpr = build (TREE_CODE (expr), TREE_TYPE (expr),
+ genop1);
+ newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
+ temp, newexpr);
+ name = make_ssa_name (temp, newexpr);
+ TREE_OPERAND (newexpr, 0) = name;
+ tsi = tsi_last (stmts);
+ tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
+ pre_stats.insertions++;
+
+ break;
+ }
+ default:
+ abort ();
+
+ }
+ v = get_value_handle (expr);
+ vn_add (name, v, NULL);
+ bitmap_insert_into_set (NEW_SETS (block), name);
+ bitmap_value_insert_into_set (AVAIL_OUT (block), name);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Inserted ");
+ print_generic_expr (dump_file, newexpr, 0);
+ fprintf (dump_file, " in predecessor %d\n", block->index);
+ }
+ return name;
+}
+
+/* Perform insertion of partially redundant values.
+ For BLOCK, do the following:
+ 1. Propagate the NEW_SETS of the dominator into the current block.
+ If the block has multiple predecessors,
+ 2a. Iterate over the ANTIC expressions for the block to see if
+ any of them are partially redundant.
+ 2b. If so, insert them into the necessary predecessors to make
+ the expression fully redundant.
+ 2c. Insert a new PHI merging the values of the predecessors.
+ 2d. Insert the new PHI, and the new expressions, into the
+ NEW_SETS set.
+ 3. Recursively call ourselves on the dominator children of BLOCK.
+
+*/
+static bool
+insert_aux (basic_block block)
+{
+ basic_block son;
+ bool new_stuff = false;
+
+ if (block)
+ {
+ basic_block dom;
+ dom = get_immediate_dominator (CDI_DOMINATORS, block);
+ if (dom)
+ {
+ int i;
+ bitmap_set_t newset = NEW_SETS (dom);
+ EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i,
+ {
+ bitmap_insert_into_set (NEW_SETS (block), ssa_name (i));
+ bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i));
+ });
+ if (block->pred->pred_next)
+ {
+ value_set_node_t node;
+ for (node = ANTIC_IN (block)->head;
+ node;
+ node = node->next)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (node->expr)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (node->expr)) == '1')
+ {
+ tree *avail;
+ tree val;
+ bool by_some = false;
+ bool cant_insert = false;
+ bool all_same = true;
+ tree first_s = NULL;
+ edge pred;
+ basic_block bprime;
+ tree eprime;
+
+ val = get_value_handle (node->expr);
+ if (bitmap_set_contains_value (PHI_GEN (block), val))
+ continue;
+ if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Found fully redundant value\n");
+ continue;
+ }
+
+ avail = xcalloc (last_basic_block, sizeof (tree));
+ for (pred = block->pred;
+ pred;
+ pred = pred->pred_next)
+ {
+ tree vprime;
+ tree edoubleprime;
+ bprime = pred->src;
+ eprime = phi_translate (node->expr,
+ ANTIC_IN (block),
+ bprime, block);
+
+ /* eprime will generally only be NULL if the
+ value of the expression, translated
+ through the PHI for this predecessor, is
+ undefined. If that is the case, we can't
+ make the expression fully redundant,
+ because its value is undefined along a
+ predecessor path. We can thus break out
+ early because it doesn't matter what the
+ rest of the results are. */
+ if (eprime == NULL)
+ {
+ cant_insert = true;
+ break;
+ }
+
+ vprime = get_value_handle (eprime);
+ if (!vprime)
+ abort ();
+ edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
+ vprime);
+ if (edoubleprime == NULL)
+ {
+ avail[bprime->index] = eprime;
+ all_same = false;
+ }
+ else
+ {
+ avail[bprime->index] = edoubleprime;
+ by_some = true;
+ if (first_s == NULL)
+ first_s = edoubleprime;
+ else if (first_s != edoubleprime)
+ all_same = false;
+ if (first_s != edoubleprime
+ && operand_equal_p (first_s, edoubleprime, 0))
+ abort ();
+ }
+ }
+ /* If we can insert it, it's not the same value
+ already existing along every predecessor, and
+ it's defined by some predecessor, it is
+ partially redundant. */
+ if (!cant_insert && !all_same && by_some)
+ {
+ tree type = TREE_TYPE (avail[block->pred->src->index]);
+ tree temp;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Found partial redundancy for expression ");
+ print_generic_expr (dump_file, node->expr, 0);
+ fprintf (dump_file, "\n");
+ }
+
+ /* Make the necessary insertions. */
+ for (pred = block->pred;
+ pred;
+ pred = pred->pred_next)
+ {
+ tree stmts = alloc_stmt_list ();
+ tree builtexpr;
+ bprime = pred->src;
+ eprime = avail[bprime->index];
+ if (TREE_CODE_CLASS (TREE_CODE (eprime)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (eprime)) == '1')
+ {
+ builtexpr = create_expression_by_pieces (bprime,
+ eprime,
+ stmts);
+ bsi_insert_on_edge (pred, stmts);
+ bsi_commit_edge_inserts (NULL);
+ avail[bprime->index] = builtexpr;
+ }
+ }
+ /* Now build a phi for the new variable. */
+ temp = create_tmp_var (type, "prephitmp");
+ add_referenced_tmp_var (temp);
+ temp = create_phi_node (temp, block);
+ vn_add (PHI_RESULT (temp), val, NULL);
+
+#if 0
+ if (!set_contains_value (AVAIL_OUT (block), val))
+ insert_into_set (AVAIL_OUT (block),
+ PHI_RESULT (temp));
+ else
+#endif
+ bitmap_value_replace_in_set (AVAIL_OUT (block),
+ PHI_RESULT (temp));
+ for (pred = block->pred;
+ pred;
+ pred = pred->pred_next)
+ {
+ add_phi_arg (&temp, avail[pred->src->index],
+ pred);
+ }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Created phi ");
+ print_generic_expr (dump_file, temp, 0);
+ fprintf (dump_file, " in block %d\n", block->index);
+ }
+ pre_stats.phis++;
+ new_stuff = true;
+ bitmap_insert_into_set (NEW_SETS (block),
+ PHI_RESULT (temp));
+ bitmap_insert_into_set (PHI_GEN (block),
+ PHI_RESULT (temp));
+ }
+
+ free (avail);
+ }
+ }
+ }
+ }
+ }
+ for (son = first_dom_son (CDI_DOMINATORS, block);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ {
+ new_stuff |= insert_aux (son);
+ }
+
+ return new_stuff;
+}
+
+/* Perform insertion of partially redundant values. */
+
+static void
+insert (void)
+{
+ bool new_stuff = true;
+ basic_block bb;
+ int num_iterations = 0;
+
+ FOR_ALL_BB (bb)
+ NEW_SETS (bb) = bitmap_set_new ();
+
+ while (new_stuff)
+ {
+ num_iterations++;
+ new_stuff = false;
+ new_stuff = insert_aux (ENTRY_BLOCK_PTR);
+ }
+ if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
+ fprintf (dump_file, "insert required %d iterations\n", num_iterations);
+}
+
+
+/* Return true if VAR is an SSA variable with no defining statement in
+ this procedure, *AND* isn't a live-on-entry parameter. */
+
+static bool
+is_undefined_value (tree expr)
+{
+ return (TREE_CODE (expr) == SSA_NAME
+ && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
+ /* PARM_DECLs and hard registers are always defined. */
+ && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL
+ && !DECL_HARD_REGISTER (SSA_NAME_VAR (expr)));
+}
+
+
+/* Given an SSA variable VAR and an expression EXPR, compute the value
+ number for EXPR and create a value handle (VAL) for it. If VAR and
+ EXPR are not the same, associate VAL with VAR. Finally, add VAR to
+ S1 and its value handle to S2.
+
+ VUSES represent the virtual use operands associated with EXPR (if
+ any). They are used when computing the hash value for EXPR. */
+
+static inline void
+add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1,
+ bitmap_set_t s2)
+{
+ tree val = vn_lookup_or_add (expr, vuses);
+
+ /* VAR and EXPR may be the same when processing statements for which
+ we are not computing value numbers (e.g., non-assignments, or
+ statements that make aliased stores). In those cases, we are
+ only interested in making VAR available as its own value. */
+ if (var != expr)
+ vn_add (var, val, NULL);
+
+ bitmap_insert_into_set (s1, var);
+ bitmap_value_insert_into_set (s2, var);
+}
+
+
+/* Given a unary or binary expression EXPR, create and return a new
+ expression with the same structure as EXPR but with its operands
+ replaced with the value handles of each of the operands of EXPR.
+ Insert EXPR's operands into the EXP_GEN set for BLOCK.
+
+ VUSES represent the virtual use operands associated with EXPR (if
+ any). They are used when computing the hash value for EXPR. */
+
+static inline tree
+create_value_expr_from (tree expr, basic_block block, vuse_optype vuses)
+{
+ int i;
+ enum tree_code code = TREE_CODE (expr);
+ tree vexpr;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE_CLASS (code) != '1'
+ && TREE_CODE_CLASS (code) != '2'
+ && TREE_CODE_CLASS (code) != 'r')
+ abort ();
+#endif
+
+ if (TREE_CODE_CLASS (code) == '1')
+ vexpr = pool_alloc (unary_node_pool);
+ else if (TREE_CODE_CLASS (code) == 'r')
+ vexpr = pool_alloc (reference_node_pool);
+ else
+ vexpr = pool_alloc (binary_node_pool);
+
+ memcpy (vexpr, expr, tree_size (expr));
+
+ for (i = 0; i < TREE_CODE_LENGTH (code); i++)
+ {
+ tree op = TREE_OPERAND (expr, i);
+ if (op != NULL)
+ {
+ tree val = vn_lookup_or_add (op, vuses);
+ if (!is_undefined_value (op))
+ value_insert_into_set (EXP_GEN (block), op);
+ TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
+ TREE_OPERAND (vexpr, i) = val;
+ }
+ }
+
+ return vexpr;
+}
+
+
+/* Compute the AVAIL set for BLOCK.
+ This function performs value numbering of the statements in BLOCK.
+ The AVAIL sets are built from information we glean while doing this
+ value numbering, since the AVAIL sets contain only one entry per
+ value.
+
+ AVAIL_IN[BLOCK] = AVAIL_OUT[dom(BLOCK)].
+ AVAIL_OUT[BLOCK] = AVAIL_IN[BLOCK] U PHI_GEN[BLOCK] U TMP_GEN[BLOCK]. */
+
+static void
+compute_avail (basic_block block)
+{
+ basic_block son;
+
+ /* For arguments with default definitions, we pretend they are
+ defined in the entry block. */
+ if (block == ENTRY_BLOCK_PTR)
+ {
+ tree param;
+ for (param = DECL_ARGUMENTS (current_function_decl);
+ param;
+ param = TREE_CHAIN (param))
+ {
+ if (default_def (param) != NULL)
+ {
+ tree val;
+ tree def = default_def (param);
+ val = vn_lookup_or_add (def, NULL);
+ bitmap_insert_into_set (TMP_GEN (block), def);
+ bitmap_value_insert_into_set (AVAIL_OUT (block), def);
+ }
+ }
+ }
+ else if (block)
+ {
+ block_stmt_iterator bsi;
+ tree stmt, phi;
+ basic_block dom;
+
+ /* Initially, the set of available values in BLOCK is that of
+ its immediate dominator. */
+ dom = get_immediate_dominator (CDI_DOMINATORS, block);
+ if (dom)
+ bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
+
+ /* Generate values for PHI nodes. */
+ for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
+ /* We have no need for virtual phis, as they don't represent
+ actual computations. */
+ if (is_gimple_reg (PHI_RESULT (phi)))
+ add_to_sets (PHI_RESULT (phi), PHI_RESULT (phi), NULL,
+ PHI_GEN (block), AVAIL_OUT (block));
+
+ /* Now compute value numbers and populate value sets with all
+ the expressions computed in BLOCK. */
+ for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt_ann_t ann;
+ size_t j;
+
+ stmt = bsi_stmt (bsi);
+ ann = stmt_ann (stmt);
+ get_stmt_operands (stmt);
+
+ /* We are only interested in assignments of the form
+ X_i = EXPR, where EXPR represents an "interesting"
+ computation, it has no volatile operands and X_i
+ doesn't flow through an abnormal edge. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && !ann->has_volatile_ops
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (stmt, 0)))
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+ tree rhs = TREE_OPERAND (stmt, 1);
+ vuse_optype vuses = STMT_VUSE_OPS (stmt);
+
+ STRIP_USELESS_TYPE_CONVERSION (rhs);
+ if (TREE_CODE (rhs) == SSA_NAME
+ || is_gimple_min_invariant (rhs))
+ {
+ /* Compute a value number for the RHS of the statement
+ and add its value to the AVAIL_OUT set for the block.
+ Add the LHS to TMP_GEN. */
+ add_to_sets (lhs, rhs, vuses, TMP_GEN (block),
+ AVAIL_OUT (block));
+
+ if (TREE_CODE (rhs) == SSA_NAME
+ && !is_undefined_value (rhs))
+ value_insert_into_set (EXP_GEN (block), rhs);
+ continue;
+ }
+ else if (TREE_CODE_CLASS (TREE_CODE (rhs)) == '1'
+ || TREE_CODE_CLASS (TREE_CODE (rhs)) == '2'
+ || TREE_CODE (rhs) == INDIRECT_REF)
+ {
+ /* For binary, unary, and reference expressions,
+ create a duplicate expression with the operands
+ replaced with the value handles of the original
+ RHS. */
+ tree newt = create_value_expr_from (rhs, block, vuses);
+ add_to_sets (lhs, newt, vuses, TMP_GEN (block),
+ AVAIL_OUT (block));
+ value_insert_into_set (EXP_GEN (block), newt);
+ continue;
+ }
+ }
+
+ /* For any other statement that we don't recognize, simply
+ make the names generated by the statement available in
+ AVAIL_OUT and TMP_GEN. */
+ for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
+ {
+ tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
+ add_to_sets (def, def, NULL, TMP_GEN (block),
+ AVAIL_OUT (block));
+ }
+
+ for (j = 0; j < NUM_USES (STMT_USE_OPS (stmt)); j++)
+ {
+ tree use = USE_OP (STMT_USE_OPS (stmt), j);
+ add_to_sets (use, use, NULL, TMP_GEN (block),
+ AVAIL_OUT (block));
+ }
+ }
+ }
+
+ /* Compute available sets for the dominator children of BLOCK. */
+ for (son = first_dom_son (CDI_DOMINATORS, block);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ compute_avail (son);
+}
+
+
+/* Eliminate fully redundant computations. */
+
+static void
+eliminate (void)
+{
+ basic_block b;
+
+ FOR_EACH_BB (b)
+ {
+ block_stmt_iterator i;
+
+ for (i = bsi_start (b); !bsi_end_p (i); bsi_next (&i))
+ {
+ tree stmt = bsi_stmt (i);
+
+ /* Lookup the RHS of the expression, see if we have an
+ available computation for it. If so, replace the RHS with
+ the available computation. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
+ && TREE_CODE (TREE_OPERAND (stmt ,1)) != SSA_NAME
+ && !is_gimple_min_invariant (TREE_OPERAND (stmt, 1))
+ && !stmt_ann (stmt)->has_volatile_ops)
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+ tree *rhs_p = &TREE_OPERAND (stmt, 1);
+ tree sprime;
+
+ sprime = bitmap_find_leader (AVAIL_OUT (b),
+ vn_lookup (lhs, NULL));
+ if (sprime
+ && sprime != lhs
+ && (TREE_CODE (*rhs_p) != SSA_NAME
+ || may_propagate_copy (*rhs_p, sprime)))
+ {
+ if (sprime == *rhs_p)
+ abort ();
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Replaced ");
+ print_generic_expr (dump_file, *rhs_p, 0);
+ fprintf (dump_file, " with ");
+ print_generic_expr (dump_file, sprime, 0);
+ fprintf (dump_file, " in ");
+ print_generic_stmt (dump_file, stmt, 0);
+ }
+ pre_stats.eliminations++;
+ propagate_tree_value (rhs_p, sprime);
+ modify_stmt (stmt);
+ }
+ }
+ }
+ }
+}
+
+
+/* Initialize data structures used by PRE. */
+
+static void
+init_pre (void)
+{
+ size_t tsize;
+ basic_block bb;
+
+ vn_init ();
+ memset (&pre_stats, 0, sizeof (pre_stats));
+ FOR_ALL_BB (bb)
+ bb->aux = xcalloc (1, sizeof (struct bb_value_sets));
+
+ phi_translate_table = htab_create (511, expr_pred_trans_hash,
+ expr_pred_trans_eq, free);
+ value_set_pool = create_alloc_pool ("Value sets",
+ sizeof (struct value_set), 30);
+ bitmap_set_pool = create_alloc_pool ("Bitmap sets",
+ sizeof (struct bitmap_set), 30);
+ value_set_node_pool = create_alloc_pool ("Value set nodes",
+ sizeof (struct value_set_node), 30);
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
+ tsize = tree_size (build (PLUS_EXPR, void_type_node, NULL_TREE, NULL_TREE));
+ binary_node_pool = create_alloc_pool ("Binary tree nodes", tsize, 30);
+ tsize = tree_size (build1 (NEGATE_EXPR, void_type_node, NULL_TREE));
+ unary_node_pool = create_alloc_pool ("Unary tree nodes", tsize, 30);
+ tsize = tree_size (build (COMPONENT_REF, void_type_node, NULL_TREE, NULL_TREE, NULL_TREE));
+ reference_node_pool = create_alloc_pool ("Reference tree nodes", tsize, 30);
+ FOR_ALL_BB (bb)
+ {
+ EXP_GEN (bb) = set_new (true);
+ PHI_GEN (bb) = bitmap_set_new ();
+ TMP_GEN (bb) = bitmap_set_new ();
+ AVAIL_OUT (bb) = bitmap_set_new ();
+ }
+}
+
+
+/* Deallocate data structures used by PRE. */
+
+static void
+fini_pre (void)
+{
+ basic_block bb;
+
+ free_alloc_pool (value_set_pool);
+ free_alloc_pool (bitmap_set_pool);
+ free_alloc_pool (value_set_node_pool);
+ free_alloc_pool (binary_node_pool);
+ free_alloc_pool (reference_node_pool);
+ free_alloc_pool (unary_node_pool);
+ htab_delete (phi_translate_table);
+
+ FOR_ALL_BB (bb)
+ {
+ free (bb->aux);
+ bb->aux = NULL;
+ }
+ free_dominance_info (CDI_POST_DOMINATORS);
+ vn_delete ();
+}
+
+
+/* Main entry point to the SSA-PRE pass. DO_FRE is true if the caller
+ only wants to do full redundancy elimination. */
+
+static void
+execute_pre (bool do_fre)
+{
+ init_pre ();
+
+ /* Collect and value number expressions computed in each basic
+ block. */
+ compute_avail (ENTRY_BLOCK_PTR);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ basic_block bb;
+
+ FOR_ALL_BB (bb)
+ {
+ print_value_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
+ bitmap_print_value_set (dump_file, TMP_GEN (bb), "tmp_gen",
+ bb->index);
+ bitmap_print_value_set (dump_file, AVAIL_OUT (bb), "avail_out",
+ bb->index);
+ }
+ }
+
+ /* Insert can get quite slow on an incredibly large number of basic
+ blocks due to some quadratic behavior. Until this behavior is
+ fixed, don't run it when he have an incredibly large number of
+ bb's. If we aren't going to run insert, there is no point in
+ computing ANTIC, either, even though it's plenty fast. */
+ if (!do_fre && n_basic_blocks < 4000)
+ {
+ compute_antic ();
+ insert ();
+ }
+
+ /* Remove all the redundant expressions. */
+ eliminate ();
+
+ if (dump_file && (dump_flags & TDF_STATS))
+ {
+ fprintf (dump_file, "Insertions:%d\n", pre_stats.insertions);
+ fprintf (dump_file, "New PHIs:%d\n", pre_stats.phis);
+ fprintf (dump_file, "Eliminated:%d\n", pre_stats.eliminations);
+ }
+
+ fini_pre ();
+}
+
+
+/* Gate and execute functions for PRE. */
+
+static void
+do_pre (void)
+{
+ execute_pre (false);
+}
+
+static bool
+gate_pre (void)
+{
+ return flag_tree_pre != 0;
+}
+
+struct tree_opt_pass pass_pre =
+{
+ "pre", /* name */
+ gate_pre, /* gate */
+ do_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_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
+
+
+/* Gate and execute functions for FRE. */
+
+static void
+do_fre (void)
+{
+ execute_pre (true);
+}
+
+static bool
+gate_fre (void)
+{
+ return flag_tree_fre != 0;
+}
+
+struct tree_opt_pass pass_fre =
+{
+ "fre", /* name */
+ gate_fre, /* gate */
+ do_fre, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_FRE, /* 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_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..4cdfd3ddf22
--- /dev/null
+++ b/gcc/tree-ssa.c
@@ -0,0 +1,1165 @@
+/* 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 = PHI_CHAIN (phi);
+ remove_phi_arg (phi, e->src);
+ }
+
+ remove_edge (e);
+}
+
+/* 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 = PHI_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 (num_ssa_names, 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 = PHI_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;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
+ def_optype defs;
+
+ stmt = bsi_stmt (bsi);
+ ann = stmt_ann (stmt);
+ get_stmt_operands (stmt);
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ if (ann->makes_aliased_stores && NUM_V_MAY_DEFS (v_may_defs) == 0)
+ error ("Makes aliased stores, but no V_MAY_DEFS");
+
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+ {
+ tree op = V_MAY_DEF_RESULT (v_may_defs, 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);
+ }
+
+ v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+ for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, j);
+ if (is_gimple_reg (op))
+ {
+ error ("Found a virtual must-def 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 = PHI_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 V_MAY_DEF 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;
+ v_may_def_optype v_may_defs;
+ 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);
+ }
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+ {
+ tree op = V_MAY_DEF_OP (v_may_defs, 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;
+
+ if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
+ t = TREE_OPERAND (t, 0);
+ else
+ while (handled_component_p (t))
+ t = TREE_OPERAND (t, 0);
+ }
+
+ 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 (TREE_TYPE (inner_type),
+ TREE_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
+ || TREE_CODE (expr) == VIEW_CONVERT_EXPR
+ || TREE_CODE (expr) == NON_LVALUE_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 VAR with REPL in memory reference expression *X in
+ statement STMT. */
+
+static void
+propagate_into_addr (tree stmt, tree var, tree *x, tree repl)
+{
+ tree new_var, ass_stmt, addr_var;
+ basic_block bb;
+ block_stmt_iterator bsi;
+
+ /* There is nothing special to handle in the other cases. */
+ if (TREE_CODE (repl) != ADDR_EXPR)
+ return;
+ addr_var = TREE_OPERAND (repl, 0);
+
+ while (TREE_CODE (*x) == ARRAY_REF
+ || TREE_CODE (*x) == COMPONENT_REF
+ || TREE_CODE (*x) == BIT_FIELD_REF)
+ x = &TREE_OPERAND (*x, 0);
+
+ if (TREE_CODE (*x) != INDIRECT_REF
+ || TREE_OPERAND (*x, 0) != var)
+ return;
+
+ modify_stmt (stmt);
+ if (TREE_TYPE (*x) == TREE_TYPE (addr_var))
+ {
+ *x = addr_var;
+ mark_new_vars_to_rename (stmt, vars_to_rename);
+ return;
+ }
+
+ /* Frontends sometimes produce expressions like *&a instead of a[0].
+ Create a temporary variable to handle this case. */
+ ass_stmt = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, repl);
+ new_var = duplicate_ssa_name (var, ass_stmt);
+ TREE_OPERAND (*x, 0) = new_var;
+ TREE_OPERAND (ass_stmt, 0) = new_var;
+
+ bb = bb_for_stmt (stmt);
+ tree_block_label (bb);
+ bsi = bsi_after_labels (bb);
+ bsi_insert_after (&bsi, ass_stmt, BSI_NEW_STMT);
+
+ mark_new_vars_to_rename (stmt, vars_to_rename);
+}
+
+/* Replaces immediate uses of VAR by REPL. */
+
+static void
+replace_immediate_uses (tree var, tree repl)
+{
+ use_optype uses;
+ vuse_optype vuses;
+ v_may_def_optype v_may_defs;
+ int i, j, n;
+ dataflow_t df;
+ tree stmt;
+ stmt_ann_t ann;
+ bool mark_new_vars;
+
+ 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)
+ {
+ SET_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);
+ mark_new_vars = false;
+ if (is_gimple_reg (SSA_NAME_VAR (var)))
+ {
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 0), repl);
+ propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 1), repl);
+ }
+
+ 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);
+ mark_new_vars = POINTER_TYPE_P (TREE_TYPE (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);
+
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (j = 0; j < (int) NUM_V_MAY_DEFS (v_may_defs); j++)
+ if (V_MAY_DEF_OP (v_may_defs, j) == var)
+ propagate_value (V_MAY_DEF_OP_PTR (v_may_defs, j), repl);
+ }
+
+ /* 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 (mark_new_vars)
+ mark_new_vars_to_rename (stmt, vars_to_rename);
+ else
+ modify_stmt (stmt);
+ }
+}
+
+/* Gets the value VAR is equivalent to according to EQ_TO. */
+
+static tree
+get_eq_name (tree *eq_to, tree var)
+{
+ unsigned ver;
+ tree val = var;
+
+ while (TREE_CODE (val) == SSA_NAME)
+ {
+ ver = SSA_NAME_VERSION (val);
+ if (!eq_to[ver])
+ break;
+
+ val = eq_to[ver];
+ }
+
+ while (TREE_CODE (var) == SSA_NAME)
+ {
+ ver = SSA_NAME_VERSION (var);
+ if (!eq_to[ver])
+ break;
+
+ var = eq_to[ver];
+ eq_to[ver] = val;
+ }
+
+ return val;
+}
+
+/* Checks whether phi node PHI is redundant and if it is, records the ssa name
+ its result is redundant to to EQ_TO array. */
+
+static void
+check_phi_redundancy (tree phi, tree *eq_to)
+{
+ tree val = NULL_TREE, def, res = PHI_RESULT (phi), stmt;
+ unsigned i, ver = SSA_NAME_VERSION (res), n;
+ dataflow_t df;
+
+ /* It is unlikely that such large phi node would be redundant. */
+ if (PHI_NUM_ARGS (phi) > 16)
+ return;
+
+ for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
+ {
+ def = PHI_ARG_DEF (phi, i);
+
+ if (TREE_CODE (def) == SSA_NAME)
+ {
+ def = get_eq_name (eq_to, def);
+ if (def == res)
+ continue;
+ }
+
+ if (val
+ && !operand_equal_p (val, def, 0))
+ return;
+
+ val = def;
+ }
+
+ /* At least one of the arguments should not be equal to the result, or
+ something strange is happening. */
+ if (!val)
+ abort ();
+
+ if (get_eq_name (eq_to, res) == val)
+ return;
+
+ if (!may_propagate_copy (res, val))
+ return;
+
+ eq_to[ver] = val;
+
+ df = get_immediate_uses (SSA_NAME_DEF_STMT (res));
+ n = num_immediate_uses (df);
+
+ for (i = 0; i < n; i++)
+ {
+ stmt = immediate_use (df, i);
+
+ if (TREE_CODE (stmt) == PHI_NODE)
+ check_phi_redundancy (stmt, 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. */
+
+void
+kill_redundant_phi_nodes (void)
+{
+ tree *eq_to;
+ unsigned i, old_num_ssa_names;
+ basic_block bb;
+ tree phi, var, repl, stmt;
+
+ /* The EQ_TO[VER] holds the value by that the ssa name VER should be
+ replaced. If EQ_TO[VER] is ssa name and it is decided to replace it by
+ other value, it may be necessary to follow the chain till the final value.
+ We perform path shortening (replacing the entries of the EQ_TO array with
+ heads of these chains) whenever we access the field to prevent quadratic
+ complexity (probably would not occur in practice anyway, but let us play
+ it safe). */
+ eq_to = xcalloc (num_ssa_names, 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);
+ old_num_ssa_names = num_ssa_names;
+
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ var = PHI_RESULT (phi);
+ check_phi_redundancy (phi, eq_to);
+ }
+ }
+
+ /* Now propagate the values. */
+ for (i = 0; i < old_num_ssa_names; i++)
+ {
+ if (!ssa_name (i))
+ continue;
+
+ repl = get_eq_name (eq_to, ssa_name (i));
+ if (repl != ssa_name (i))
+ replace_immediate_uses (ssa_name (i), repl);
+ }
+
+ /* And remove the dead phis. */
+ for (i = 0; i < old_num_ssa_names; i++)
+ {
+ if (!ssa_name (i))
+ continue;
+
+ repl = get_eq_name (eq_to, ssa_name (i));
+ if (repl != ssa_name (i))
+ {
+ stmt = SSA_NAME_DEF_STMT (ssa_name (i));
+ remove_phi_node (stmt, NULL_TREE, bb_for_stmt (stmt));
+ }
+ }
+
+ free_df ();
+ free (eq_to);
+}
+
+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 = PHI_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..d4982706676
--- /dev/null
+++ b/gcc/tree-ssanames.c
@@ -0,0 +1,219 @@
+/* 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"
+#include "tree-flow.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. */
+
+/* Array of all SSA_NAMEs used in the function. */
+varray_type ssa_names;
+
+/* 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)
+{
+ VARRAY_TREE_INIT (ssa_names, 50, "ssa_names table");
+
+ /* Version 0 is special, so reserve the first slot in the table. Though
+ currently unused, we may use version 0 in alias analysis as part of
+ the heuristics used to group aliases when the alias sets are too
+ large. */
+ VARRAY_PUSH_TREE (ssa_names, NULL_TREE);
+ 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) = num_ssa_names;
+ VARRAY_PUSH_TREE (ssa_names, t);
+#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;
+ SSA_NAME_PTR_INFO (t) = NULL;
+
+ 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;
+ }
+}
+
+/* Creates a duplicate of a ssa name NAME defined in statement STMT. */
+
+tree
+duplicate_ssa_name (tree name, tree stmt)
+{
+ tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
+ struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+ struct ptr_info_def *new_ptr_info;
+
+ if (!old_ptr_info)
+ return new_name;
+
+ new_ptr_info = ggc_alloc (sizeof (struct ptr_info_def));
+ *new_ptr_info = *old_ptr_info;
+
+ if (old_ptr_info->pt_vars)
+ {
+ new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_copy (new_ptr_info->pt_vars, old_ptr_info->pt_vars);
+ }
+
+ SSA_NAME_PTR_INFO (new_name) = new_ptr_info;
+ return new_name;
+}
+
+#include "gt-tree-ssanames.h"
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
new file mode 100644
index 00000000000..6036cfaad77
--- /dev/null
+++ b/gcc/tree-tailcall.c
@@ -0,0 +1,942 @@
+/* Tail call 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
+ analyze 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 other 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
+ classical 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 definition 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_ARG_DEF_FROM_EDGE (at, e);
+ }
+
+ /* 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);
+ tree src_var = src;
+
+ /* See if this is a simple copy operation of an SSA name to the function
+ result. In that case we may have a simple tail call. Ignore type
+ conversions that can never produce extra code between the function
+ call and the function return. */
+ STRIP_NOPS (src_var);
+ if (TREE_CODE (src_var) == SSA_NAME)
+ {
+ if (src_var != *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 (code)
+ {
+ 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 = PHI_CHAIN (phi))
+ if (PHI_ARG_DEF_FROM_EDGE (phi, e) == 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_V_MAY_DEFS (V_MAY_DEF_OPS (ann))
+ || NUM_V_MUST_DEFS (V_MUST_DEF_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;
+
+ if (!process_assignment (stmt, stmt, bsi, &m, &a, &ass_var))
+ return;
+ }
+
+ /* See if this is a tail call we can handle. */
+ ret_var = TREE_OPERAND (stmt, 0);
+ if (ret_var
+ && TREE_CODE (ret_var) == MODIFY_EXPR)
+ {
+ tree ret_op = TREE_OPERAND (ret_var, 1);
+ STRIP_NOPS (ret_op);
+ if (!tail_recursion
+ && TREE_CODE (ret_op) != 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;
+
+ /* If this is not a tail recursive call, we cannot handle addends or
+ multiplicands. */
+ if (!tail_recursion && (m || a))
+ 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 = PHI_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 = PHI_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 according 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_t) 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;
+ v_may_def_optype v_may_defs;
+ 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 = PHI_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. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
+ for (phi = phi_nodes (first); phi; phi = PHI_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, V_MAY_DEF_OP (v_may_defs, 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, fold_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, fold_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-vn.c b/gcc/tree-vn.c
new file mode 100644
index 00000000000..b686af296af
--- /dev/null
+++ b/gcc/tree-vn.c
@@ -0,0 +1,302 @@
+/* Value Numbering routines for tree expressions.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dan@dberlin.org>, Steven Bosscher
+ <stevenb@suse.de> and 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 "ggc.h"
+#include "tree.h"
+#include "tree-flow.h"
+#include "hashtab.h"
+#include "langhooks.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
+#include "diagnostic.h"
+
+/* The value table that maps expressions to values. */
+static htab_t value_table;
+
+/* Map expressions to values. These are simple pairs of expressions
+ and the values they represent. To find the value represented by
+ an expression, we use a hash table where the elements are {e,v}
+ pairs, and the expression is the key. */
+typedef struct val_expr_pair_d
+{
+ /* Value handle. */
+ tree v;
+
+ /* Associated expression. */
+ tree e;
+
+ /* Virtual uses in E. */
+ vuse_optype vuses;
+
+ /* E's hash value. */
+ hashval_t hashcode;
+} *val_expr_pair_t;
+
+static void set_value_handle (tree e, tree v);
+
+
+/* Create and return a new value handle node of type TYPE. */
+
+static tree
+make_value_handle (tree type)
+{
+ static unsigned int id = 0;
+ tree vh;
+
+ vh = build0 (VALUE_HANDLE, type);
+ VALUE_HANDLE_ID (vh) = id++;
+ return vh;
+}
+
+
+/* Given an expression EXPR, compute a hash value number using the
+ code of the expression, its real operands and virtual operands (if
+ any).
+
+ VAL can be used to iterate by passing previous value numbers (it is
+ used by iterative_hash_expr).
+
+ VUSES is the set of virtual use operands associated with EXPR. It
+ may be NULL if EXPR has no virtual operands. */
+
+hashval_t
+vn_compute (tree expr, hashval_t val, vuse_optype vuses)
+{
+ size_t i;
+
+#if defined ENABLE_CHECKING
+ /* EXPR must not be a statement. We are only interested in value
+ numbering expressions on the RHS of assignments. */
+ if (expr == NULL_TREE
+ || (expr->common.ann
+ && expr->common.ann->common.type == STMT_ANN))
+ abort ();
+#endif
+
+ val = iterative_hash_expr (expr, val);
+
+ /* If the expression has virtual uses, incorporate them into the
+ hash value computed for EXPR. */
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ val = iterative_hash_expr (VUSE_OP (vuses, i), val);
+
+ return val;
+}
+
+
+/* Compare two expressions E1 and E2 and return true if they are
+ equal. */
+
+bool
+expressions_equal_p (tree e1, tree e2)
+{
+ tree te1, te2;
+
+ if (e1 == e2)
+ return true;
+
+ te1 = TREE_TYPE (e1);
+ te2 = TREE_TYPE (e2);
+
+ if (TREE_CODE (e1) == TREE_CODE (e2)
+ && (te1 == te2 || lang_hooks.types_compatible_p (te1, te2))
+ && operand_equal_p (e1, e2, OEP_PURE_SAME))
+ return true;
+
+ return false;
+}
+
+
+/* Hash a {v,e} pair that is pointed to by P.
+ The hashcode is cached in the val_expr_pair, so we just return
+ that. */
+
+static hashval_t
+val_expr_pair_hash (const void *p)
+{
+ const val_expr_pair_t ve = (val_expr_pair_t) p;
+ return ve->hashcode;
+}
+
+
+/* Given two val_expr_pair_t's, return true if they represent the same
+ expression, false otherwise.
+ P1 and P2 should point to the val_expr_pair_t's to be compared. */
+
+static int
+val_expr_pair_expr_eq (const void *p1, const void *p2)
+{
+ const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
+ const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
+
+ if (expressions_equal_p (ve1->e, ve2->e))
+ return true;
+
+ return false;
+}
+
+
+/* Set the value handle for expression E to value V */
+
+static void
+set_value_handle (tree e, tree v)
+{
+ if (TREE_CODE (e) == SSA_NAME)
+ SSA_NAME_VALUE (e) = v;
+ else if (EXPR_P (e) || DECL_P (e))
+ get_tree_ann (e)->common.value_handle = v;
+ else if (is_gimple_min_invariant (e))
+ /* Do nothing. Constants are their own value handles. */
+ ;
+ else
+ abort ();
+}
+
+
+/* Insert EXPR into VALUE_TABLE with value VAL, and add expression
+ EXPR to the value set for value VAL. VUSES represent the virtual
+ use operands associated with EXPR (if any). They are used when
+ computing the hash value for EXPR. */
+
+void
+vn_add (tree expr, tree val, vuse_optype vuses)
+{
+ void **slot;
+ val_expr_pair_t new_pair;
+
+ new_pair = xmalloc (sizeof (struct val_expr_pair_d));
+ new_pair->e = expr;
+ new_pair->v = val;
+ new_pair->vuses = vuses;
+ new_pair->hashcode = vn_compute (expr, 0, vuses);
+ slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
+ INSERT);
+ if (*slot)
+ free (*slot);
+ *slot = (void *) new_pair;
+
+ set_value_handle (expr, val);
+ add_to_value (val, expr);
+}
+
+
+/* Search in VALUE_TABLE for an existing instance of expression EXPR,
+ and return its value, or NULL if none has been set. VUSES
+ represent the virtual use operands associated with EXPR (if any).
+ They are used when computing the hash value for EXPR. */
+
+tree
+vn_lookup (tree expr, vuse_optype vuses)
+{
+ void **slot;
+ struct val_expr_pair_d vep = {NULL, NULL, NULL, 0};
+
+ /* Constants are their own value. */
+ if (is_gimple_min_invariant (expr))
+ return expr;
+
+ vep.e = expr;
+ vep.vuses = vuses;
+ vep.hashcode = vn_compute (expr, 0, vuses);
+ slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
+ if (!slot)
+ return NULL_TREE;
+ else
+ return ((val_expr_pair_t) *slot)->v;
+}
+
+
+/* Like vn_lookup, but creates a new value for expression EXPR, if
+ EXPR doesn't already have a value. Return the existing/created
+ value for EXPR. VUSES represent the virtual use operands
+ associated with EXPR (if any). They are used when computing the
+ hash value for EXPR. */
+
+tree
+vn_lookup_or_add (tree expr, vuse_optype vuses)
+{
+ tree v = vn_lookup (expr, vuses);
+ if (v == NULL_TREE)
+ {
+ v = make_value_handle (TREE_TYPE (expr));
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Created value ");
+ print_generic_expr (dump_file, v, dump_flags);
+ fprintf (dump_file, " for ");
+ print_generic_expr (dump_file, expr, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+ vn_add (expr, v, vuses);
+ }
+
+ set_value_handle (expr, v);
+
+ return v;
+}
+
+
+/* Get the value handle of EXPR. This is the only correct way to get
+ the value handle for a "thing". If EXPR does not have a value
+ handle associated, it returns NULL_TREE. */
+
+tree
+get_value_handle (tree expr)
+{
+ if (TREE_CODE (expr) == SSA_NAME)
+ return SSA_NAME_VALUE (expr);
+ else if (EXPR_P (expr) || DECL_P (expr))
+ {
+ tree_ann_t ann = tree_ann (expr);
+ return ((ann) ? ann->common.value_handle : NULL_TREE);
+ }
+ else if (is_gimple_min_invariant (expr))
+ return expr;
+
+ abort ();
+}
+
+
+/* Initialize data structures used in value numbering. */
+
+void
+vn_init (void)
+{
+ value_table = htab_create (511, val_expr_pair_hash,
+ val_expr_pair_expr_eq, free);
+}
+
+
+/* Delete data used for value numbering. */
+
+void
+vn_delete (void)
+{
+ htab_delete (value_table);
+ value_table = NULL;
+}
diff --git a/gcc/unwind-dw2.h b/gcc/unwind-dw2.h
new file mode 100644
index 00000000000..77563e74414
--- /dev/null
+++ b/gcc/unwind-dw2.h
@@ -0,0 +1,88 @@
+/* DWARF2 frame unwind data structure.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 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.
+
+ 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 combined
+ 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. */
+
+/* A target can override (perhaps for backward compatibility) how
+ many dwarf2 columns are unwound. */
+#ifndef DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
+#endif
+
+/* The result of interpreting the frame unwind info for a frame.
+ This is all symbolic at this point, as none of the values can
+ be resolved until the target pc is located. */
+typedef struct
+{
+ /* Each register save state can be described in terms of a CFA slot,
+ another register, or a location expression. */
+ struct frame_state_reg_info
+ {
+ struct {
+ union {
+ _Unwind_Word reg;
+ _Unwind_Sword offset;
+ const unsigned char *exp;
+ } loc;
+ enum {
+ REG_UNSAVED,
+ REG_SAVED_OFFSET,
+ REG_SAVED_REG,
+ REG_SAVED_EXP
+ } how;
+ } reg[DWARF_FRAME_REGISTERS+1];
+
+ /* Used to implement DW_CFA_remember_state. */
+ struct frame_state_reg_info *prev;
+ } regs;
+
+ /* The CFA can be described in terms of a reg+offset or a
+ location expression. */
+ _Unwind_Sword cfa_offset;
+ _Unwind_Word cfa_reg;
+ const unsigned char *cfa_exp;
+ enum {
+ CFA_UNSET,
+ CFA_REG_OFFSET,
+ CFA_EXP
+ } cfa_how;
+
+ /* The PC described by the current frame state. */
+ void *pc;
+
+ /* The information we care about from the CIE/FDE. */
+ _Unwind_Personality_Fn personality;
+ _Unwind_Sword data_align;
+ _Unwind_Word code_align;
+ _Unwind_Word retaddr_column;
+ unsigned char fde_encoding;
+ unsigned char lsda_encoding;
+ unsigned char saw_z;
+ void *eh_ptr;
+} _Unwind_FrameState;
+
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
new file mode 100644
index 00000000000..32c78aefdcd
--- /dev/null
+++ b/gcc/var-tracking.c
@@ -0,0 +1,2767 @@
+/* Variable tracking routines for the GNU compiler.
+ Copyright (C) 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. */
+
+/* This file contains the variable tracking pass. It computes where
+ variables are located (which registers or where in memory) at each position
+ in instruction stream and emits notes describing the locations.
+ Debug information (DWARF2 location lists) is finally generated from
+ these notes.
+ With this debug information, it is possible to show variables
+ even when debugging optimized code.
+
+ How does the variable tracking pass work?
+
+ First, it scans RTL code for uses, stores and clobbers (register/memory
+ references in instructions), for call insns and for stack adjustments
+ separately for each basic block and saves them to an array of micro
+ operations.
+ The micro operations of one instruction are ordered so that
+ pre-modifying stack adjustment < use < use with no var < call insn <
+ < set < clobber < post-modifying stack adjustment
+
+ Then, a forward dataflow analysis is performed to find out how locations
+ of variables change through code and to propagate the variable locations
+ along control flow graph.
+ The IN set for basic block BB is computed as a union of OUT sets of BB's
+ predecessors, the OUT set for BB is copied from the IN set for BB and
+ is changed according to micro operations in BB.
+
+ The IN and OUT sets for basic blocks consist of a current stack adjustment
+ (used for adjusting offset of variables addressed using stack pointer),
+ the table of structures describing the locations of parts of a variable
+ and for each physical register a linked list for each physical register.
+ The linked list is a list of variable parts stored in the register,
+ i.e. it is a list of triplets (reg, decl, offset) where decl is
+ REG_EXPR (reg) and offset is REG_OFFSET (reg). The linked list is used for
+ effective deleting appropriate variable parts when we set or clobber the
+ register.
+
+ There may be more than one variable part in a register. The linked lists
+ should be pretty short so it is a good data structure here.
+ For example in the following code, register allocator may assign same
+ register to variables A and B, and both of them are stored in the same
+ register in CODE:
+
+ if (cond)
+ set A;
+ else
+ set B;
+ CODE;
+ if (cond)
+ use A;
+ else
+ use B;
+
+ Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
+ are emitted to appropriate positions in RTL code. Each such a note describes
+ the location of one variable at the point in instruction stream where the
+ note is. There is no need to emit a note for each variable before each
+ instruction, we only emit these notes where the location of variable changes
+ (this means that we also emit notes for changes between the OUT set of the
+ previous block and the IN set of the current block).
+
+ The notes consist of two parts:
+ 1. the declaration (from REG_EXPR or MEM_EXPR)
+ 2. the location of a variable - it is either a simple register/memory
+ reference (for simple variables, for example int),
+ or a parallel of register/memory references (for a large variables
+ which consist of several parts, for example long long).
+
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tree.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "flags.h"
+#include "output.h"
+#include "insn-config.h"
+#include "reload.h"
+#include "sbitmap.h"
+#include "alloc-pool.h"
+#include "fibheap.h"
+#include "hashtab.h"
+
+/* Type of micro operation. */
+enum micro_operation_type
+{
+ MO_USE, /* Use location (REG or MEM). */
+ MO_USE_NO_VAR,/* Use location which is not associated with a variable
+ or the variable is not trackable. */
+ MO_SET, /* Set location. */
+ MO_CLOBBER, /* Clobber location. */
+ MO_CALL, /* Call insn. */
+ MO_ADJUST /* Adjust stack pointer. */
+};
+
+/* Where shall the note be emitted? BEFORE or AFTER the instruction. */
+enum emit_note_where
+{
+ EMIT_NOTE_BEFORE_INSN,
+ EMIT_NOTE_AFTER_INSN
+};
+
+/* Structure holding information about micro operation. */
+typedef struct micro_operation_def
+{
+ /* Type of micro operation. */
+ enum micro_operation_type type;
+
+ union {
+ /* Location. */
+ rtx loc;
+
+ /* Stack adjustment. */
+ HOST_WIDE_INT adjust;
+ } u;
+
+ /* The instruction which the micro operation is in. */
+ rtx insn;
+} micro_operation;
+
+/* Structure for passing some other parameters to function
+ emit_note_insn_var_location. */
+typedef struct emit_note_data_def
+{
+ /* The instruction which the note will be emitted before/after. */
+ rtx insn;
+
+ /* Where the note will be emitted (before/after insn)? */
+ enum emit_note_where where;
+} emit_note_data;
+
+/* Description of location of a part of a variable. The content of a physical
+ register is described by a chain of these structures.
+ The chains are pretty short (usually 1 or 2 elements) and thus
+ chain is the best data structure. */
+typedef struct attrs_def
+{
+ /* Pointer to next member of the list. */
+ struct attrs_def *next;
+
+ /* The rtx of register. */
+ rtx loc;
+
+ /* The declaration corresponding to LOC. */
+ tree decl;
+
+ /* Offset from start of DECL. */
+ HOST_WIDE_INT offset;
+} *attrs;
+
+/* Structure holding the IN or OUT set for a basic block. */
+typedef struct dataflow_set_def
+{
+ /* Adjustment of stack offset. */
+ HOST_WIDE_INT stack_adjust;
+
+ /* Attributes for registers (lists of attrs). */
+ attrs regs[FIRST_PSEUDO_REGISTER];
+
+ /* Variable locations. */
+ htab_t vars;
+} dataflow_set;
+
+/* The structure (one for each basic block) containing the information
+ needed for variable tracking. */
+typedef struct variable_tracking_info_def
+{
+ /* Number of micro operations stored in the MOS array. */
+ int n_mos;
+
+ /* The array of micro operations. */
+ micro_operation *mos;
+
+ /* The IN and OUT set for dataflow analysis. */
+ dataflow_set in;
+ dataflow_set out;
+
+ /* Has the block been visited in DFS? */
+ bool visited;
+} *variable_tracking_info;
+
+/* Structure for chaining the locations. */
+typedef struct location_chain_def
+{
+ /* Next element in the chain. */
+ struct location_chain_def *next;
+
+ /* The location (REG or MEM). */
+ rtx loc;
+} *location_chain;
+
+/* Structure describing one part of variable. */
+typedef struct variable_part_def
+{
+ /* Chain of locations of the part. */
+ location_chain loc_chain;
+
+ /* Location which was last emitted to location list. */
+ rtx cur_loc;
+
+ /* The offset in the variable. */
+ HOST_WIDE_INT offset;
+} variable_part;
+
+/* Maximum number of location parts. */
+#define MAX_VAR_PARTS 16
+
+/* Structure describing where the variable is located. */
+typedef struct variable_def
+{
+ /* The declaration of the variable. */
+ tree decl;
+
+ /* Reference count. */
+ int refcount;
+
+ /* Number of variable parts. */
+ int n_var_parts;
+
+ /* The variable parts. */
+ variable_part var_part[MAX_VAR_PARTS];
+} *variable;
+
+/* Hash function for DECL for VARIABLE_HTAB. */
+#define VARIABLE_HASH_VAL(decl) ((size_t) (decl))
+
+/* Pointer to the BB's information specific to variable tracking pass. */
+#define VTI(BB) ((variable_tracking_info) (BB)->aux)
+
+/* Alloc pool for struct attrs_def. */
+static alloc_pool attrs_pool;
+
+/* Alloc pool for struct variable_def. */
+static alloc_pool var_pool;
+
+/* Alloc pool for struct location_chain_def. */
+static alloc_pool loc_chain_pool;
+
+/* Changed variables, notes will be emitted for them. */
+static htab_t changed_variables;
+
+/* Shall notes be emitted? */
+static bool emit_notes;
+
+/* Fake variable for stack pointer. */
+tree frame_base_decl;
+
+/* Stack adjust caused by function prologue. */
+static HOST_WIDE_INT frame_stack_adjust;
+
+/* Local function prototypes. */
+static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
+ HOST_WIDE_INT *);
+static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
+ HOST_WIDE_INT *);
+static void bb_stack_adjust_offset (basic_block);
+static HOST_WIDE_INT prologue_stack_adjust (void);
+static bool vt_stack_adjustments (void);
+static rtx adjust_stack_reference (rtx, HOST_WIDE_INT);
+static hashval_t variable_htab_hash (const void *);
+static int variable_htab_eq (const void *, const void *);
+static void variable_htab_free (void *);
+
+static void init_attrs_list_set (attrs *);
+static void attrs_list_clear (attrs *);
+static attrs attrs_list_member (attrs, tree, HOST_WIDE_INT);
+static void attrs_list_insert (attrs *, tree, HOST_WIDE_INT, rtx);
+static void attrs_list_copy (attrs *, attrs);
+static void attrs_list_union (attrs *, attrs);
+
+static void vars_clear (htab_t);
+static variable unshare_variable (dataflow_set *set, variable var);
+static int vars_copy_1 (void **, void *);
+static void vars_copy (htab_t, htab_t);
+static void var_reg_delete_and_set (dataflow_set *, rtx);
+static void var_reg_delete (dataflow_set *, rtx);
+static void var_regno_delete (dataflow_set *, int);
+static void var_mem_delete_and_set (dataflow_set *, rtx);
+static void var_mem_delete (dataflow_set *, rtx);
+
+static void dataflow_set_init (dataflow_set *, int);
+static void dataflow_set_clear (dataflow_set *);
+static void dataflow_set_copy (dataflow_set *, dataflow_set *);
+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, 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 *);
+static void dataflow_set_destroy (dataflow_set *);
+
+static bool contains_symbol_ref (rtx);
+static bool track_expr_p (tree);
+static int count_uses (rtx *, void *);
+static void count_uses_1 (rtx *, void *);
+static void count_stores (rtx, rtx, void *);
+static int add_uses (rtx *, void *);
+static void add_uses_1 (rtx *, void *);
+static void add_stores (rtx, rtx, void *);
+static bool compute_bb_dataflow (basic_block);
+static void vt_find_locations (void);
+
+static void dump_attrs_list (attrs);
+static int dump_variable (void **, void *);
+static void dump_vars (htab_t);
+static void dump_dataflow_set (dataflow_set *);
+static void dump_dataflow_sets (void);
+
+static void variable_was_changed (variable, htab_t);
+static void set_frame_base_location (dataflow_set *, rtx);
+static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
+static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
+static int emit_note_insn_var_location (void **, void *);
+static void emit_notes_for_changes (rtx, enum emit_note_where);
+static int emit_notes_for_differences_1 (void **, void *);
+static int emit_notes_for_differences_2 (void **, void *);
+static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
+static void emit_notes_in_bb (basic_block);
+static void vt_emit_notes (void);
+
+static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
+static void vt_add_function_parameters (void);
+static void vt_initialize (void);
+static void vt_finalize (void);
+
+/* Given a SET, calculate the amount of stack adjustment it contains
+ PRE- and POST-modifying stack pointer.
+ This function is similar to stack_adjust_offset. */
+
+static void
+stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
+ HOST_WIDE_INT *post)
+{
+ rtx src = SET_SRC (pattern);
+ rtx dest = SET_DEST (pattern);
+ enum rtx_code code;
+
+ if (dest == stack_pointer_rtx)
+ {
+ /* (set (reg sp) (plus (reg sp) (const_int))) */
+ code = GET_CODE (src);
+ if (! (code == PLUS || code == MINUS)
+ || XEXP (src, 0) != stack_pointer_rtx
+ || GET_CODE (XEXP (src, 1)) != CONST_INT)
+ return;
+
+ if (code == MINUS)
+ *post += INTVAL (XEXP (src, 1));
+ else
+ *post -= INTVAL (XEXP (src, 1));
+ }
+ else if (MEM_P (dest))
+ {
+ /* (set (mem (pre_dec (reg sp))) (foo)) */
+ src = XEXP (dest, 0);
+ code = GET_CODE (src);
+
+ switch (code)
+ {
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ if (XEXP (src, 0) == stack_pointer_rtx)
+ {
+ rtx val = XEXP (XEXP (src, 1), 1);
+ /* We handle only adjustments by constant amount. */
+ if (GET_CODE (XEXP (src, 1)) != PLUS ||
+ GET_CODE (val) != CONST_INT)
+ abort ();
+ if (code == PRE_MODIFY)
+ *pre -= INTVAL (val);
+ else
+ *post -= INTVAL (val);
+ break;
+ }
+ return;
+
+ case PRE_DEC:
+ if (XEXP (src, 0) == stack_pointer_rtx)
+ {
+ *pre += GET_MODE_SIZE (GET_MODE (dest));
+ break;
+ }
+ return;
+
+ case POST_DEC:
+ if (XEXP (src, 0) == stack_pointer_rtx)
+ {
+ *post += GET_MODE_SIZE (GET_MODE (dest));
+ break;
+ }
+ return;
+
+ case PRE_INC:
+ if (XEXP (src, 0) == stack_pointer_rtx)
+ {
+ *pre -= GET_MODE_SIZE (GET_MODE (dest));
+ break;
+ }
+ return;
+
+ case POST_INC:
+ if (XEXP (src, 0) == stack_pointer_rtx)
+ {
+ *post -= GET_MODE_SIZE (GET_MODE (dest));
+ break;
+ }
+ return;
+
+ default:
+ return;
+ }
+ }
+}
+
+/* Given an INSN, calculate the amount of stack adjustment it contains
+ PRE- and POST-modifying stack pointer. */
+
+static void
+insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
+ HOST_WIDE_INT *post)
+{
+ *pre = 0;
+ *post = 0;
+
+ if (GET_CODE (PATTERN (insn)) == SET)
+ stack_adjust_offset_pre_post (PATTERN (insn), pre, post);
+ else if (GET_CODE (PATTERN (insn)) == PARALLEL
+ || GET_CODE (PATTERN (insn)) == SEQUENCE)
+ {
+ int i;
+
+ /* There may be stack adjustments inside compound insns. Search
+ for them. */
+ for ( i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+ if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
+ stack_adjust_offset_pre_post (XVECEXP (PATTERN (insn), 0, i),
+ pre, post);
+ }
+}
+
+/* Compute stack adjustment in basic block BB. */
+
+static void
+bb_stack_adjust_offset (basic_block bb)
+{
+ HOST_WIDE_INT offset;
+ int i;
+
+ offset = VTI (bb)->in.stack_adjust;
+ for (i = 0; i < VTI (bb)->n_mos; i++)
+ {
+ if (VTI (bb)->mos[i].type == MO_ADJUST)
+ offset += VTI (bb)->mos[i].u.adjust;
+ else if (VTI (bb)->mos[i].type != MO_CALL)
+ {
+ if (MEM_P (VTI (bb)->mos[i].u.loc))
+ {
+ VTI (bb)->mos[i].u.loc
+ = adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
+ }
+ }
+ }
+ VTI (bb)->out.stack_adjust = offset;
+}
+
+/* Compute stack adjustment caused by function prologue. */
+
+static HOST_WIDE_INT
+prologue_stack_adjust (void)
+{
+ HOST_WIDE_INT offset = 0;
+ basic_block bb = ENTRY_BLOCK_PTR->next_bb;
+ rtx insn;
+ rtx end;
+
+ if (!BB_END (bb))
+ return 0;
+
+ end = NEXT_INSN (BB_END (bb));
+ for (insn = BB_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
+ break;
+
+ if (INSN_P (insn))
+ {
+ HOST_WIDE_INT tmp;
+
+ insn_stack_adjust_offset_pre_post (insn, &tmp, &tmp);
+ offset += tmp;
+ }
+ }
+
+ return offset;
+}
+
+/* Compute stack adjustments for all blocks by traversing DFS tree.
+ Return true when the adjustments on all incoming edges are consistent.
+ Heavily borrowed from flow_depth_first_order_compute. */
+
+static bool
+vt_stack_adjustments (void)
+{
+ edge *stack;
+ int sp;
+
+ /* Initialize entry block. */
+ VTI (ENTRY_BLOCK_PTR)->visited = true;
+ VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = frame_stack_adjust;
+
+ /* Allocate stack for back-tracking up CFG. */
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ sp = 0;
+
+ /* Push the first edge on to the stack. */
+ stack[sp++] = ENTRY_BLOCK_PTR->succ;
+
+ while (sp)
+ {
+ edge e;
+ basic_block src;
+ basic_block dest;
+
+ /* Look at the edge on the top of the stack. */
+ e = stack[sp - 1];
+ src = e->src;
+ dest = e->dest;
+
+ /* Check if the edge destination has been visited yet. */
+ if (!VTI (dest)->visited)
+ {
+ VTI (dest)->visited = true;
+ VTI (dest)->in.stack_adjust = VTI (src)->out.stack_adjust;
+ bb_stack_adjust_offset (dest);
+
+ if (dest->succ)
+ /* Since the DEST node has been visited for the first
+ time, check its successors. */
+ stack[sp++] = dest->succ;
+ }
+ else
+ {
+ /* Check whether the adjustments on the edges are the same. */
+ if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
+ {
+ free (stack);
+ return false;
+ }
+
+ if (e->succ_next)
+ /* Go to the next edge. */
+ stack[sp - 1] = e->succ_next;
+ else
+ /* Return to previous level if there are no more edges. */
+ sp--;
+ }
+ }
+
+ free (stack);
+ return true;
+}
+
+/* Adjust stack reference MEM by ADJUSTMENT bytes and return the new rtx. */
+
+static rtx
+adjust_stack_reference (rtx mem, HOST_WIDE_INT adjustment)
+{
+ rtx adjusted_mem;
+ rtx tmp;
+
+ if (adjustment == 0)
+ return mem;
+
+ adjusted_mem = copy_rtx (mem);
+ XEXP (adjusted_mem, 0) = replace_rtx (XEXP (adjusted_mem, 0),
+ stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ GEN_INT (adjustment)));
+ tmp = simplify_rtx (XEXP (adjusted_mem, 0));
+ if (tmp)
+ XEXP (adjusted_mem, 0) = tmp;
+
+ return adjusted_mem;
+}
+
+/* The hash function for variable_htab, computes the hash value
+ from the declaration of variable X. */
+
+static hashval_t
+variable_htab_hash (const void *x)
+{
+ const variable v = (const variable) x;
+
+ return (VARIABLE_HASH_VAL (v->decl));
+}
+
+/* Compare the declaration of variable X with declaration Y. */
+
+static int
+variable_htab_eq (const void *x, const void *y)
+{
+ const variable v = (const variable) x;
+ const tree decl = (const tree) y;
+
+ return (VARIABLE_HASH_VAL (v->decl) == VARIABLE_HASH_VAL (decl));
+}
+
+/* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
+
+static void
+variable_htab_free (void *elem)
+{
+ int i;
+ variable var = (variable) elem;
+ location_chain node, next;
+
+#ifdef ENABLE_CHECKING
+ if (var->refcount <= 0)
+ abort ();
+#endif
+
+ var->refcount--;
+ if (var->refcount > 0)
+ return;
+
+ for (i = 0; i < var->n_var_parts; i++)
+ {
+ for (node = var->var_part[i].loc_chain; node; node = next)
+ {
+ next = node->next;
+ pool_free (loc_chain_pool, node);
+ }
+ var->var_part[i].loc_chain = NULL;
+ }
+ pool_free (var_pool, var);
+}
+
+/* Initialize the set (array) SET of attrs to empty lists. */
+
+static void
+init_attrs_list_set (attrs *set)
+{
+ int i;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ set[i] = NULL;
+}
+
+/* Make the list *LISTP empty. */
+
+static void
+attrs_list_clear (attrs *listp)
+{
+ attrs list, next;
+
+ for (list = *listp; list; list = next)
+ {
+ next = list->next;
+ pool_free (attrs_pool, list);
+ }
+ *listp = NULL;
+}
+
+/* Return true if the pair of DECL and OFFSET is the member of the LIST. */
+
+static attrs
+attrs_list_member (attrs list, tree decl, HOST_WIDE_INT offset)
+{
+ for (; list; list = list->next)
+ if (list->decl == decl && list->offset == offset)
+ return list;
+ return NULL;
+}
+
+/* Insert the triplet DECL, OFFSET, LOC to the list *LISTP. */
+
+static void
+attrs_list_insert (attrs *listp, tree decl, HOST_WIDE_INT offset, rtx loc)
+{
+ attrs list;
+
+ list = pool_alloc (attrs_pool);
+ list->loc = loc;
+ list->decl = decl;
+ list->offset = offset;
+ list->next = *listp;
+ *listp = list;
+}
+
+/* Copy all nodes from SRC and create a list *DSTP of the copies. */
+
+static void
+attrs_list_copy (attrs *dstp, attrs src)
+{
+ attrs n;
+
+ attrs_list_clear (dstp);
+ for (; src; src = src->next)
+ {
+ n = pool_alloc (attrs_pool);
+ n->loc = src->loc;
+ n->decl = src->decl;
+ n->offset = src->offset;
+ n->next = *dstp;
+ *dstp = n;
+ }
+}
+
+/* Add all nodes from SRC which are not in *DSTP to *DSTP. */
+
+static void
+attrs_list_union (attrs *dstp, attrs src)
+{
+ for (; src; src = src->next)
+ {
+ if (!attrs_list_member (*dstp, src->decl, src->offset))
+ attrs_list_insert (dstp, src->decl, src->offset, src->loc);
+ }
+}
+
+/* Delete all variables from hash table VARS. */
+
+static void
+vars_clear (htab_t vars)
+{
+ htab_empty (vars);
+}
+
+/* Return a copy of a variable VAR and insert it to dataflow set SET. */
+
+static variable
+unshare_variable (dataflow_set *set, variable var)
+{
+ void **slot;
+ variable new_var;
+ int i;
+
+ new_var = pool_alloc (var_pool);
+ new_var->decl = var->decl;
+ new_var->refcount = 1;
+ var->refcount--;
+ new_var->n_var_parts = var->n_var_parts;
+
+ for (i = 0; i < var->n_var_parts; i++)
+ {
+ location_chain node;
+ location_chain *nextp;
+
+ new_var->var_part[i].offset = var->var_part[i].offset;
+ nextp = &new_var->var_part[i].loc_chain;
+ for (node = var->var_part[i].loc_chain; node; node = node->next)
+ {
+ location_chain new_lc;
+
+ new_lc = pool_alloc (loc_chain_pool);
+ new_lc->next = NULL;
+ new_lc->loc = node->loc;
+
+ *nextp = new_lc;
+ nextp = &new_lc->next;
+ }
+
+ /* We are at the basic block boundary when copying variable description
+ so set the CUR_LOC to be the first element of the chain. */
+ if (new_var->var_part[i].loc_chain)
+ new_var->var_part[i].cur_loc = new_var->var_part[i].loc_chain->loc;
+ else
+ new_var->var_part[i].cur_loc = NULL;
+ }
+
+ slot = htab_find_slot_with_hash (set->vars, new_var->decl,
+ VARIABLE_HASH_VAL (new_var->decl),
+ INSERT);
+ *slot = new_var;
+ return new_var;
+}
+
+/* Add a variable from *SLOT to hash table DATA and increase its reference
+ count. */
+
+static int
+vars_copy_1 (void **slot, void *data)
+{
+ htab_t dst = (htab_t) data;
+ variable src, *dstp;
+
+ src = *(variable *) slot;
+ src->refcount++;
+
+ dstp = (variable *) htab_find_slot_with_hash (dst, src->decl,
+ VARIABLE_HASH_VAL (src->decl),
+ INSERT);
+ *dstp = src;
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Copy all variables from hash table SRC to hash table DST. */
+
+static void
+vars_copy (htab_t dst, htab_t src)
+{
+ vars_clear (dst);
+ htab_traverse (src, vars_copy_1, dst);
+}
+
+/* Delete current content of register LOC in dataflow set SET
+ and set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
+
+static void
+var_reg_delete_and_set (dataflow_set *set, rtx loc)
+{
+ tree decl = REG_EXPR (loc);
+ HOST_WIDE_INT offset = REG_OFFSET (loc);
+ attrs node, next;
+ attrs *nextp;
+
+ nextp = &set->regs[REGNO (loc)];
+ for (node = *nextp; node; node = next)
+ {
+ next = node->next;
+ if (node->decl != decl || node->offset != offset)
+ {
+ delete_variable_part (set, node->loc, node->decl, node->offset);
+ pool_free (attrs_pool, node);
+ *nextp = next;
+ }
+ else
+ {
+ node->loc = loc;
+ nextp = &node->next;
+ }
+ }
+ if (set->regs[REGNO (loc)] == NULL)
+ attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
+ set_variable_part (set, loc, decl, offset);
+}
+
+/* Delete current content of register LOC in dataflow set SET. */
+
+static void
+var_reg_delete (dataflow_set *set, rtx loc)
+{
+ attrs *reg = &set->regs[REGNO (loc)];
+ attrs node, next;
+
+ for (node = *reg; node; node = next)
+ {
+ next = node->next;
+ delete_variable_part (set, node->loc, node->decl, node->offset);
+ pool_free (attrs_pool, node);
+ }
+ *reg = NULL;
+}
+
+/* Delete content of register with number REGNO in dataflow set SET. */
+
+static void
+var_regno_delete (dataflow_set *set, int regno)
+{
+ attrs *reg = &set->regs[regno];
+ attrs node, next;
+
+ for (node = *reg; node; node = next)
+ {
+ next = node->next;
+ delete_variable_part (set, node->loc, node->decl, node->offset);
+ pool_free (attrs_pool, node);
+ }
+ *reg = NULL;
+}
+
+/* Delete and set the location part of variable MEM_EXPR (LOC)
+ in dataflow set SET to LOC.
+ Adjust the address first if it is stack pointer based. */
+
+static void
+var_mem_delete_and_set (dataflow_set *set, rtx loc)
+{
+ tree decl = MEM_EXPR (loc);
+ HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+
+ set_variable_part (set, loc, decl, offset);
+}
+
+/* Delete the location part LOC from dataflow set SET.
+ Adjust the address first if it is stack pointer based. */
+
+static void
+var_mem_delete (dataflow_set *set, rtx loc)
+{
+ tree decl = MEM_EXPR (loc);
+ HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+
+ delete_variable_part (set, loc, decl, offset);
+}
+
+/* Initialize dataflow set SET to be empty.
+ VARS_SIZE is the initial size of hash table VARS. */
+
+static void
+dataflow_set_init (dataflow_set *set, int vars_size)
+{
+ init_attrs_list_set (set->regs);
+ set->vars = htab_create (vars_size, variable_htab_hash, variable_htab_eq,
+ variable_htab_free);
+ set->stack_adjust = 0;
+}
+
+/* Delete the contents of dataflow set SET. */
+
+static void
+dataflow_set_clear (dataflow_set *set)
+{
+ int i;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ attrs_list_clear (&set->regs[i]);
+
+ vars_clear (set->vars);
+}
+
+/* Copy the contents of dataflow set SRC to DST. */
+
+static void
+dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
+{
+ int i;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ attrs_list_copy (&dst->regs[i], src->regs[i]);
+
+ vars_copy (dst->vars, src->vars);
+ dst->stack_adjust = src->stack_adjust;
+}
+
+/* Information for merging lists of locations for a given offset of variable.
+ */
+struct variable_union_info
+{
+ /* Node of the location chain. */
+ location_chain lc;
+
+ /* The sum of positions in the input chains. */
+ int pos;
+
+ /* The position in the chains of SRC and DST dataflow sets. */
+ int pos_src;
+ int pos_dst;
+};
+
+/* Compare function for qsort, order the structures by POS element. */
+
+static int
+variable_union_info_cmp_pos (const void *n1, const void *n2)
+{
+ const struct variable_union_info *i1 = n1;
+ const struct variable_union_info *i2 = n2;
+
+ if (i1->pos != i2->pos)
+ return i1->pos - i2->pos;
+
+ return (i1->pos_dst - i2->pos_dst);
+}
+
+/* Compute union of location parts of variable *SLOT and the same variable
+ from hash table DATA. Compute "sorted" union of the location chains
+ for common offsets, i.e. the locations of a variable part are sorted by
+ a priority where the priority is the sum of the positions in the 2 chains
+ (if a location is only in one list the position in the second list is
+ defined to be larger than the length of the chains).
+ When we are updating the location parts the newest location is in the
+ beginning of the chain, so when we do the described "sorted" union
+ we keep the newest locations in the beginning. */
+
+static int
+variable_union (void **slot, void *data)
+{
+ variable src, dst, *dstp;
+ dataflow_set *set = (dataflow_set *) data;
+ int i, j, k;
+
+ src = *(variable *) slot;
+ dstp = (variable *) htab_find_slot_with_hash (set->vars, src->decl,
+ VARIABLE_HASH_VAL (src->decl),
+ INSERT);
+ if (!*dstp)
+ {
+ src->refcount++;
+
+ /* If CUR_LOC of some variable part is not the first element of
+ the location chain we are going to change it so we have to make
+ a copy of the variable. */
+ for (k = 0; k < src->n_var_parts; k++)
+ {
+ if (src->var_part[k].loc_chain)
+ {
+#ifdef ENABLE_CHECKING
+ if (src->var_part[k].cur_loc == NULL)
+ abort ();
+#endif
+ if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
+ break;
+ }
+#ifdef ENABLE_CHECKING
+ else
+ {
+ if (src->var_part[k].cur_loc != NULL)
+ abort ();
+ }
+#endif
+ }
+ if (k < src->n_var_parts)
+ unshare_variable (set, src);
+ else
+ *dstp = src;
+
+ /* Continue traversing the hash table. */
+ return 1;
+ }
+ else
+ dst = *dstp;
+
+#ifdef ENABLE_CHECKING
+ if (src->n_var_parts == 0)
+ abort ();
+#endif
+
+ /* Count the number of location parts, result is K. */
+ for (i = 0, j = 0, k = 0;
+ i < src->n_var_parts && j < dst->n_var_parts; k++)
+ {
+ if (src->var_part[i].offset == dst->var_part[j].offset)
+ {
+ i++;
+ j++;
+ }
+ else if (src->var_part[i].offset < dst->var_part[j].offset)
+ i++;
+ else
+ j++;
+ }
+ k += src->n_var_parts - i;
+ k += dst->n_var_parts - j;
+#ifdef ENABLE_CHECKING
+ /* We track only variables whose size is <= MAX_VAR_PARTS bytes
+ thus there are at most MAX_VAR_PARTS different offsets. */
+ if (k > MAX_VAR_PARTS)
+ abort ();
+#endif
+
+ if (dst->refcount > 1 && dst->n_var_parts != k)
+ dst = unshare_variable (set, dst);
+
+ i = src->n_var_parts - 1;
+ j = dst->n_var_parts - 1;
+ dst->n_var_parts = k;
+
+ for (k--; k >= 0; k--)
+ {
+ location_chain node, node2;
+
+ if (i >= 0 && j >= 0
+ && src->var_part[i].offset == dst->var_part[j].offset)
+ {
+ /* Compute the "sorted" union of the chains, i.e. the locations which
+ are in both chains go first, they are sorted by the sum of
+ positions in the chains. */
+ int dst_l, src_l;
+ int ii, jj, n;
+ struct variable_union_info *vui;
+
+ /* If DST is shared compare the location chains.
+ If they are different we will modify the chain in DST with
+ high probability so make a copy of DST. */
+ if (dst->refcount > 1)
+ {
+ for (node = src->var_part[i].loc_chain,
+ node2 = dst->var_part[j].loc_chain; node && node2;
+ node = node->next, node2 = node2->next)
+ {
+ if (!((REG_P (node2->loc)
+ && REG_P (node->loc)
+ && REGNO (node2->loc) == REGNO (node->loc))
+ || rtx_equal_p (node2->loc, node->loc)))
+ break;
+ }
+ if (node || node2)
+ dst = unshare_variable (set, dst);
+ }
+
+ src_l = 0;
+ for (node = src->var_part[i].loc_chain; node; node = node->next)
+ src_l++;
+ dst_l = 0;
+ for (node = dst->var_part[j].loc_chain; node; node = node->next)
+ dst_l++;
+ vui = xcalloc (src_l + dst_l, sizeof (struct variable_union_info));
+
+ /* Fill in the locations from DST. */
+ for (node = dst->var_part[j].loc_chain, jj = 0; node;
+ node = node->next, jj++)
+ {
+ vui[jj].lc = node;
+ vui[jj].pos_dst = jj;
+
+ /* Value larger than a sum of 2 valid positions. */
+ vui[jj].pos_src = src_l + dst_l;
+ }
+
+ /* Fill in the locations from SRC. */
+ n = dst_l;
+ for (node = src->var_part[i].loc_chain, ii = 0; node;
+ node = node->next, ii++)
+ {
+ /* Find location from NODE. */
+ for (jj = 0; jj < dst_l; jj++)
+ {
+ if ((REG_P (vui[jj].lc->loc)
+ && REG_P (node->loc)
+ && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
+ || rtx_equal_p (vui[jj].lc->loc, node->loc))
+ {
+ vui[jj].pos_src = ii;
+ break;
+ }
+ }
+ if (jj >= dst_l) /* The location has not been found. */
+ {
+ location_chain new_node;
+
+ /* Copy the location from SRC. */
+ new_node = pool_alloc (loc_chain_pool);
+ new_node->loc = node->loc;
+ vui[n].lc = new_node;
+ vui[n].pos_src = ii;
+ vui[n].pos_dst = src_l + dst_l;
+ n++;
+ }
+ }
+
+ for (ii = 0; ii < src_l + dst_l; ii++)
+ vui[ii].pos = vui[ii].pos_src + vui[ii].pos_dst;
+
+ qsort (vui, n, sizeof (struct variable_union_info),
+ variable_union_info_cmp_pos);
+
+ /* Reconnect the nodes in sorted order. */
+ for (ii = 1; ii < n; ii++)
+ vui[ii - 1].lc->next = vui[ii].lc;
+ vui[n - 1].lc->next = NULL;
+
+ dst->var_part[k].loc_chain = vui[0].lc;
+ dst->var_part[k].offset = dst->var_part[j].offset;
+
+ free (vui);
+ i--;
+ j--;
+ }
+ else if ((i >= 0 && j >= 0
+ && src->var_part[i].offset < dst->var_part[j].offset)
+ || i < 0)
+ {
+ dst->var_part[k] = dst->var_part[j];
+ j--;
+ }
+ else if ((i >= 0 && j >= 0
+ && src->var_part[i].offset > dst->var_part[j].offset)
+ || j < 0)
+ {
+ location_chain *nextp;
+
+ /* Copy the chain from SRC. */
+ nextp = &dst->var_part[k].loc_chain;
+ for (node = src->var_part[i].loc_chain; node; node = node->next)
+ {
+ location_chain new_lc;
+
+ new_lc = pool_alloc (loc_chain_pool);
+ new_lc->next = NULL;
+ new_lc->loc = node->loc;
+
+ *nextp = new_lc;
+ nextp = &new_lc->next;
+ }
+
+ dst->var_part[k].offset = src->var_part[i].offset;
+ i--;
+ }
+
+ /* We are at the basic block boundary when computing union
+ so set the CUR_LOC to be the first element of the chain. */
+ if (dst->var_part[k].loc_chain)
+ dst->var_part[k].cur_loc = dst->var_part[k].loc_chain->loc;
+ else
+ dst->var_part[k].cur_loc = NULL;
+ }
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Compute union of dataflow sets SRC and DST and store it to DST. */
+
+static void
+dataflow_set_union (dataflow_set *dst, dataflow_set *src)
+{
+ int i;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ attrs_list_union (&dst->regs[i], src->regs[i]);
+
+ htab_traverse (src->vars, variable_union, dst);
+}
+
+/* Flag whether two dataflow sets being compared contain different data. */
+static bool
+dataflow_set_different_value;
+
+static bool
+variable_part_different_p (variable_part *vp1, variable_part *vp2)
+{
+ location_chain lc1, lc2;
+
+ for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
+ {
+ for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
+ {
+ if (REG_P (lc1->loc) && REG_P (lc2->loc))
+ {
+ if (REGNO (lc1->loc) == REGNO (lc2->loc))
+ break;
+ }
+ if (rtx_equal_p (lc1->loc, lc2->loc))
+ break;
+ }
+ if (!lc2)
+ return true;
+ }
+ return false;
+}
+
+/* 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,
+ bool compare_current_location)
+{
+ int i;
+
+ if (var1 == var2)
+ return false;
+
+ if (var1->n_var_parts != var2->n_var_parts)
+ return true;
+
+ for (i = 0; i < var1->n_var_parts; i++)
+ {
+ if (var1->var_part[i].offset != var2->var_part[i].offset)
+ return true;
+ if (compare_current_location)
+ {
+ if (!((REG_P (var1->var_part[i].cur_loc)
+ && REG_P (var2->var_part[i].cur_loc)
+ && (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]))
+ return true;
+ }
+ return false;
+}
+
+/* Compare variable *SLOT with the same variable in hash table DATA
+ and set DATAFLOW_SET_DIFFERENT_VALUE if they are different. */
+
+static int
+dataflow_set_different_1 (void **slot, void *data)
+{
+ htab_t htab = (htab_t) data;
+ variable var1, var2;
+
+ var1 = *(variable *) slot;
+ var2 = htab_find_with_hash (htab, var1->decl,
+ VARIABLE_HASH_VAL (var1->decl));
+ if (!var2)
+ {
+ dataflow_set_different_value = true;
+
+ /* Stop traversing the hash table. */
+ return 0;
+ }
+
+ if (variable_different_p (var1, var2, false))
+ {
+ dataflow_set_different_value = true;
+
+ /* Stop traversing the hash table. */
+ return 0;
+ }
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Compare variable *SLOT with the same variable in hash table DATA
+ and set DATAFLOW_SET_DIFFERENT_VALUE if they are different. */
+
+static int
+dataflow_set_different_2 (void **slot, void *data)
+{
+ htab_t htab = (htab_t) data;
+ variable var1, var2;
+
+ var1 = *(variable *) slot;
+ var2 = htab_find_with_hash (htab, var1->decl,
+ VARIABLE_HASH_VAL (var1->decl));
+ if (!var2)
+ {
+ dataflow_set_different_value = true;
+
+ /* Stop traversing the hash table. */
+ return 0;
+ }
+
+#ifdef ENABLE_CHECKING
+ /* If both variables are defined they have been already checked for
+ equivalence. */
+ if (variable_different_p (var1, var2, false))
+ abort ();
+#endif
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Return true if dataflow sets OLD_SET and NEW_SET differ. */
+
+static bool
+dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
+{
+ dataflow_set_different_value = false;
+
+ htab_traverse (old_set->vars, dataflow_set_different_1, new_set->vars);
+ if (!dataflow_set_different_value)
+ {
+ /* We have compared the variables which are in both hash tables
+ so now only check whether there are some variables in NEW_SET->VARS
+ which are not in OLD_SET->VARS. */
+ htab_traverse (new_set->vars, dataflow_set_different_2, old_set->vars);
+ }
+ return dataflow_set_different_value;
+}
+
+/* Free the contents of dataflow set SET. */
+
+static void
+dataflow_set_destroy (dataflow_set *set)
+{
+ int i;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ attrs_list_clear (&set->regs[i]);
+
+ htab_delete (set->vars);
+ set->vars = NULL;
+}
+
+/* Return true if RTL X contains a SYMBOL_REF. */
+
+static bool
+contains_symbol_ref (rtx x)
+{
+ const char *fmt;
+ RTX_CODE code;
+ int i;
+
+ if (!x)
+ return false;
+
+ code = GET_CODE (x);
+ if (code == SYMBOL_REF)
+ return true;
+
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ if (contains_symbol_ref (XEXP (x, i)))
+ return true;
+ }
+ else if (fmt[i] == 'E')
+ {
+ int j;
+ for (j = 0; j < XVECLEN (x, i); j++)
+ if (contains_symbol_ref (XVECEXP (x, i, j)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Shall EXPR be tracked? */
+
+static bool
+track_expr_p (tree expr)
+{
+ rtx decl_rtl;
+
+ /* If EXPR is not a parameter or a variable do not track it. */
+ if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
+ return 0;
+
+ /* It also must have a name... */
+ if (!DECL_NAME (expr))
+ return 0;
+
+ /* ... and a RTL assigned to it. */
+ decl_rtl = DECL_RTL_IF_SET (expr);
+ if (!decl_rtl)
+ return 0;
+
+ /* Do not track EXPR if it should be ignored for debugging purposes. */
+ if (DECL_IGNORED_P (expr))
+ return 0;
+
+ /* Do not track global variables until we are able to emit correct location
+ list for them. */
+ if (TREE_STATIC (expr))
+ return 0;
+
+ /* When the EXPR is a DECL for alias of some variable (see example)
+ the TREE_STATIC flag is not used. Disable tracking all DECLs whose
+ DECL_RTL contains SYMBOL_REF.
+
+ Example:
+ extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
+ char **_dl_argv;
+ */
+ if (MEM_P (decl_rtl)
+ && contains_symbol_ref (XEXP (decl_rtl, 0)))
+ return 0;
+
+ /* If RTX is a memory it should not be very large (because it would be
+ an array or struct). */
+ if (MEM_P (decl_rtl))
+ {
+ /* Do not track structures and arrays. */
+ if (GET_MODE (decl_rtl) == BLKmode)
+ return 0;
+ if (MEM_SIZE (decl_rtl)
+ && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Count uses (register and memory references) LOC which will be tracked.
+ INSN is instruction which the LOC is part of. */
+
+static int
+count_uses (rtx *loc, void *insn)
+{
+ basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
+
+ if (REG_P (*loc))
+ {
+#ifdef ENABLE_CHECKING
+ if (REGNO (*loc) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+#endif
+ VTI (bb)->n_mos++;
+ }
+ else if (MEM_P (*loc)
+ && MEM_EXPR (*loc)
+ && track_expr_p (MEM_EXPR (*loc)))
+ {
+ VTI (bb)->n_mos++;
+ }
+
+ return 0;
+}
+
+/* Helper function for finding all uses of REG/MEM in X in insn INSN. */
+
+static void
+count_uses_1 (rtx *x, void *insn)
+{
+ for_each_rtx (x, count_uses, insn);
+}
+
+/* Count stores (register and memory references) LOC which will be tracked.
+ INSN is instruction which the LOC is part of. */
+
+static void
+count_stores (rtx loc, rtx expr ATTRIBUTE_UNUSED, void *insn)
+{
+ count_uses (&loc, insn);
+}
+
+/* Add uses (register and memory references) LOC which will be tracked
+ to VTI (bb)->mos. INSN is instruction which the LOC is part of. */
+
+static int
+add_uses (rtx *loc, void *insn)
+{
+ if (REG_P (*loc))
+ {
+ basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = ((REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc)))
+ ? MO_USE : MO_USE_NO_VAR);
+ mo->u.loc = *loc;
+ mo->insn = (rtx) insn;
+ }
+ else if (MEM_P (*loc)
+ && MEM_EXPR (*loc)
+ && track_expr_p (MEM_EXPR (*loc)))
+ {
+ basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = MO_USE;
+ mo->u.loc = *loc;
+ mo->insn = (rtx) insn;
+ }
+
+ return 0;
+}
+
+/* Helper function for finding all uses of REG/MEM in X in insn INSN. */
+
+static void
+add_uses_1 (rtx *x, void *insn)
+{
+ for_each_rtx (x, add_uses, insn);
+}
+
+/* Add stores (register and memory references) LOC which will be tracked
+ to VTI (bb)->mos. EXPR is the RTL expression containing the store.
+ INSN is instruction which the LOC is part of. */
+
+static void
+add_stores (rtx loc, rtx expr, void *insn)
+{
+ if (REG_P (loc))
+ {
+ basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = ((GET_CODE (expr) != CLOBBER && REG_EXPR (loc)
+ && track_expr_p (REG_EXPR (loc)))
+ ? MO_SET : MO_CLOBBER);
+ mo->u.loc = loc;
+ mo->insn = (rtx) insn;
+ }
+ else if (MEM_P (loc)
+ && MEM_EXPR (loc)
+ && track_expr_p (MEM_EXPR (loc)))
+ {
+ basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = GET_CODE (expr) == CLOBBER ? MO_CLOBBER : MO_SET;
+ mo->u.loc = loc;
+ mo->insn = (rtx) insn;
+ }
+}
+
+/* Compute the changes of variable locations in the basic block BB. */
+
+static bool
+compute_bb_dataflow (basic_block bb)
+{
+ int i, n, r;
+ bool changed;
+ dataflow_set old_out;
+ dataflow_set *in = &VTI (bb)->in;
+ dataflow_set *out = &VTI (bb)->out;
+
+ dataflow_set_init (&old_out, htab_elements (VTI (bb)->out.vars) + 3);
+ dataflow_set_copy (&old_out, out);
+ dataflow_set_copy (out, in);
+
+ n = VTI (bb)->n_mos;
+ for (i = 0; i < n; i++)
+ {
+ switch (VTI (bb)->mos[i].type)
+ {
+ case MO_CALL:
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (TEST_HARD_REG_BIT (call_used_reg_set, r))
+ var_regno_delete (out, r);
+ break;
+
+ case MO_USE:
+ case MO_SET:
+ {
+ rtx loc = VTI (bb)->mos[i].u.loc;
+
+ if (REG_P (loc))
+ var_reg_delete_and_set (out, loc);
+ else if (MEM_P (loc))
+ var_mem_delete_and_set (out, loc);
+ }
+ break;
+
+ case MO_USE_NO_VAR:
+ case MO_CLOBBER:
+ {
+ rtx loc = VTI (bb)->mos[i].u.loc;
+
+ if (REG_P (loc))
+ var_reg_delete (out, loc);
+ else if (MEM_P (loc))
+ var_mem_delete (out, loc);
+ }
+ break;
+
+ case MO_ADJUST:
+ {
+ rtx base;
+
+ out->stack_adjust += VTI (bb)->mos[i].u.adjust;
+ base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ out->stack_adjust));
+ set_frame_base_location (out, base);
+ }
+ break;
+ }
+ }
+
+ changed = dataflow_set_different (&old_out, out);
+ dataflow_set_destroy (&old_out);
+ return changed;
+}
+
+/* Find the locations of variables in the whole function. */
+
+static void
+vt_find_locations (void)
+{
+ fibheap_t worklist, pending, fibheap_swap;
+ sbitmap visited, in_worklist, in_pending, sbitmap_swap;
+ basic_block bb;
+ edge e;
+ int *bb_order;
+ int *rc_order;
+ int i;
+
+ /* Compute reverse completion order of depth first search of the CFG
+ so that the data-flow runs faster. */
+ rc_order = xmalloc (n_basic_blocks * sizeof (int));
+ bb_order = xmalloc (last_basic_block * sizeof (int));
+ flow_depth_first_order_compute (NULL, rc_order);
+ for (i = 0; i < n_basic_blocks; i++)
+ bb_order[rc_order[i]] = i;
+ free (rc_order);
+
+ worklist = fibheap_new ();
+ pending = fibheap_new ();
+ visited = sbitmap_alloc (last_basic_block);
+ in_worklist = sbitmap_alloc (last_basic_block);
+ in_pending = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (in_worklist);
+ sbitmap_zero (in_pending);
+
+ FOR_EACH_BB (bb)
+ {
+ fibheap_insert (pending, bb_order[bb->index], bb);
+ SET_BIT (in_pending, bb->index);
+ }
+
+ while (!fibheap_empty (pending))
+ {
+ fibheap_swap = pending;
+ pending = worklist;
+ worklist = fibheap_swap;
+ sbitmap_swap = in_pending;
+ in_pending = in_worklist;
+ in_worklist = sbitmap_swap;
+
+ sbitmap_zero (visited);
+
+ while (!fibheap_empty (worklist))
+ {
+ bb = fibheap_extract_min (worklist);
+ RESET_BIT (in_worklist, bb->index);
+ if (!TEST_BIT (visited, bb->index))
+ {
+ bool changed;
+
+ SET_BIT (visited, bb->index);
+
+ /* Calculate the IN set as union of predecessor OUT sets. */
+ dataflow_set_clear (&VTI (bb)->in);
+ for (e = bb->pred; e; e = e->pred_next)
+ {
+ dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
+ }
+
+ changed = compute_bb_dataflow (bb);
+ if (changed)
+ {
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ if (e->dest == bb)
+ continue;
+
+ if (TEST_BIT (visited, e->dest->index))
+ {
+ if (!TEST_BIT (in_pending, e->dest->index))
+ {
+ /* Send E->DEST to next round. */
+ SET_BIT (in_pending, e->dest->index);
+ fibheap_insert (pending,
+ bb_order[e->dest->index],
+ e->dest);
+ }
+ }
+ else if (!TEST_BIT (in_worklist, e->dest->index))
+ {
+ /* Add E->DEST to current round. */
+ SET_BIT (in_worklist, e->dest->index);
+ fibheap_insert (worklist, bb_order[e->dest->index],
+ e->dest);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ free (bb_order);
+ fibheap_delete (worklist);
+ fibheap_delete (pending);
+ sbitmap_free (visited);
+ sbitmap_free (in_worklist);
+ sbitmap_free (in_pending);
+}
+
+/* Print the content of the LIST to dump file. */
+
+static void
+dump_attrs_list (attrs list)
+{
+ for (; list; list = list->next)
+ {
+ print_mem_expr (dump_file, list->decl);
+ fprintf (dump_file, "+");
+ fprintf (dump_file, HOST_WIDE_INT_PRINT_DEC, list->offset);
+ }
+ fprintf (dump_file, "\n");
+}
+
+/* Print the information about variable *SLOT to dump file. */
+
+static int
+dump_variable (void **slot, void *data ATTRIBUTE_UNUSED)
+{
+ variable var = *(variable *) slot;
+ int i;
+ location_chain node;
+
+ fprintf (dump_file, " name: %s\n",
+ IDENTIFIER_POINTER (DECL_NAME (var->decl)));
+ for (i = 0; i < var->n_var_parts; i++)
+ {
+ fprintf (dump_file, " offset %ld\n",
+ (long) var->var_part[i].offset);
+ for (node = var->var_part[i].loc_chain; node; node = node->next)
+ {
+ fprintf (dump_file, " ");
+ print_rtl_single (dump_file, node->loc);
+ }
+ }
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Print the information about variables from hash table VARS to dump file. */
+
+static void
+dump_vars (htab_t vars)
+{
+ if (htab_elements (vars) > 0)
+ {
+ fprintf (dump_file, "Variables:\n");
+ htab_traverse (vars, dump_variable, NULL);
+ }
+}
+
+/* Print the dataflow set SET to dump file. */
+
+static void
+dump_dataflow_set (dataflow_set *set)
+{
+ int i;
+
+ fprintf (dump_file, "Stack adjustment: ");
+ fprintf (dump_file, HOST_WIDE_INT_PRINT_DEC, set->stack_adjust);
+ fprintf (dump_file, "\n");
+ for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (set->regs[i])
+ {
+ fprintf (dump_file, "Reg %d:", i);
+ dump_attrs_list (set->regs[i]);
+ }
+ }
+ dump_vars (set->vars);
+ fprintf (dump_file, "\n");
+}
+
+/* Print the IN and OUT sets for each basic block to dump file. */
+
+static void
+dump_dataflow_sets (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ fprintf (dump_file, "\nBasic block %d:\n", bb->index);
+ fprintf (dump_file, "IN:\n");
+ dump_dataflow_set (&VTI (bb)->in);
+ fprintf (dump_file, "OUT:\n");
+ dump_dataflow_set (&VTI (bb)->out);
+ }
+}
+
+/* Add variable VAR to the hash table of changed variables and
+ if it has no locations delete it from hash table HTAB. */
+
+static void
+variable_was_changed (variable var, htab_t htab)
+{
+ hashval_t hash = VARIABLE_HASH_VAL (var->decl);
+
+ if (emit_notes)
+ {
+ variable *slot;
+
+ slot = (variable *) htab_find_slot_with_hash (changed_variables,
+ var->decl, hash, INSERT);
+
+ if (htab && var->n_var_parts == 0)
+ {
+ variable empty_var;
+ void **old;
+
+ empty_var = pool_alloc (var_pool);
+ empty_var->decl = var->decl;
+ empty_var->refcount = 1;
+ empty_var->n_var_parts = 0;
+ *slot = empty_var;
+
+ old = htab_find_slot_with_hash (htab, var->decl, hash,
+ NO_INSERT);
+ if (old)
+ htab_clear_slot (htab, old);
+ }
+ else
+ {
+ *slot = var;
+ }
+ }
+ else
+ {
+#ifdef ENABLE_CHECKING
+ if (!htab)
+ abort ();
+#endif
+ if (var->n_var_parts == 0)
+ {
+ void **slot = htab_find_slot_with_hash (htab, var->decl, hash,
+ NO_INSERT);
+ if (slot)
+ htab_clear_slot (htab, slot);
+ }
+ }
+}
+
+/* Set the location of frame_base_decl to LOC in dataflow set SET. This
+ function expects that frame_base_decl has already one location for offset 0
+ in the variable table. */
+
+static void
+set_frame_base_location (dataflow_set *set, rtx loc)
+{
+ variable var;
+
+ var = htab_find_with_hash (set->vars, frame_base_decl,
+ VARIABLE_HASH_VAL (frame_base_decl));
+#ifdef ENABLE_CHECKING
+ if (!var)
+ abort ();
+ if (var->n_var_parts != 1)
+ abort ();
+ if (var->var_part[0].offset != 0)
+ abort ();
+ if (!var->var_part[0].loc_chain)
+ abort ();
+#endif
+
+ /* If frame_base_decl is shared unshare it first. */
+ if (var->refcount > 1)
+ var = unshare_variable (set, var);
+
+ var->var_part[0].loc_chain->loc = loc;
+ var->var_part[0].cur_loc = loc;
+ variable_was_changed (var, set->vars);
+}
+
+/* Set the part of variable's location in the dataflow set SET. The variable
+ part is specified by variable's declaration DECL and offset OFFSET and the
+ part's location by LOC. */
+
+static void
+set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
+{
+ int pos, low, high;
+ location_chain node, next;
+ location_chain *nextp;
+ variable var;
+ void **slot;
+
+ slot = htab_find_slot_with_hash (set->vars, decl,
+ VARIABLE_HASH_VAL (decl), INSERT);
+ if (!*slot)
+ {
+ /* Create new variable information. */
+ var = pool_alloc (var_pool);
+ var->decl = decl;
+ var->refcount = 1;
+ var->n_var_parts = 1;
+ var->var_part[0].offset = offset;
+ var->var_part[0].loc_chain = NULL;
+ var->var_part[0].cur_loc = NULL;
+ *slot = var;
+ pos = 0;
+ }
+ else
+ {
+ var = (variable) *slot;
+
+ /* Find the location part. */
+ low = 0;
+ high = var->n_var_parts;
+ while (low != high)
+ {
+ pos = (low + high) / 2;
+ if (var->var_part[pos].offset < offset)
+ low = pos + 1;
+ else
+ high = pos;
+ }
+ pos = low;
+
+ if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
+ {
+ node = var->var_part[pos].loc_chain;
+
+ if (node
+ && ((REG_P (node->loc) && REG_P (loc)
+ && REGNO (node->loc) == REGNO (loc))
+ || rtx_equal_p (node->loc, loc)))
+ {
+ /* LOC is in the beginning of the chain so we have nothing
+ to do. */
+ return;
+ }
+ else
+ {
+ /* We have to make a copy of a shared variable. */
+ if (var->refcount > 1)
+ var = unshare_variable (set, var);
+ }
+ }
+ else
+ {
+ /* We have not found the location part, new one will be created. */
+
+ /* We have to make a copy of the shared variable. */
+ if (var->refcount > 1)
+ var = unshare_variable (set, var);
+
+#ifdef ENABLE_CHECKING
+ /* We track only variables whose size is <= MAX_VAR_PARTS bytes
+ thus there are at most MAX_VAR_PARTS different offsets. */
+ if (var->n_var_parts >= MAX_VAR_PARTS)
+ abort ();
+#endif
+
+ /* We have to move the elements of array starting at index low to the
+ next position. */
+ for (high = var->n_var_parts; high > low; high--)
+ var->var_part[high] = var->var_part[high - 1];
+
+ var->n_var_parts++;
+ var->var_part[pos].offset = offset;
+ var->var_part[pos].loc_chain = NULL;
+ var->var_part[pos].cur_loc = NULL;
+ }
+ }
+
+ /* Delete the location from the list. */
+ nextp = &var->var_part[pos].loc_chain;
+ for (node = var->var_part[pos].loc_chain; node; node = next)
+ {
+ next = node->next;
+ if ((REG_P (node->loc) && REG_P (loc)
+ && REGNO (node->loc) == REGNO (loc))
+ || rtx_equal_p (node->loc, loc))
+ {
+ pool_free (loc_chain_pool, node);
+ *nextp = next;
+ break;
+ }
+ else
+ nextp = &node->next;
+ }
+
+ /* Add the location to the beginning. */
+ node = pool_alloc (loc_chain_pool);
+ node->loc = loc;
+ node->next = var->var_part[pos].loc_chain;
+ var->var_part[pos].loc_chain = node;
+
+ /* If no location was emitted do so. */
+ if (var->var_part[pos].cur_loc == NULL)
+ {
+ var->var_part[pos].cur_loc = loc;
+ variable_was_changed (var, set->vars);
+ }
+}
+
+/* Delete the part of variable's location from dataflow set SET. The variable
+ part is specified by variable's declaration DECL and offset OFFSET and the
+ part's location by LOC. */
+
+static void
+delete_variable_part (dataflow_set *set, rtx loc, tree decl,
+ HOST_WIDE_INT offset)
+{
+ int pos, low, high;
+ void **slot;
+
+ slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
+ NO_INSERT);
+ if (slot)
+ {
+ variable var = (variable) *slot;
+
+ /* Find the location part. */
+ low = 0;
+ high = var->n_var_parts;
+ while (low != high)
+ {
+ pos = (low + high) / 2;
+ if (var->var_part[pos].offset < offset)
+ low = pos + 1;
+ else
+ high = pos;
+ }
+ pos = low;
+
+ if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
+ {
+ location_chain node, next;
+ location_chain *nextp;
+ bool changed;
+
+ if (var->refcount > 1)
+ {
+ /* If the variable contains the location part we have to
+ make a copy of the variable. */
+ for (node = var->var_part[pos].loc_chain; node;
+ node = node->next)
+ {
+ if ((REG_P (node->loc) && REG_P (loc)
+ && REGNO (node->loc) == REGNO (loc))
+ || rtx_equal_p (node->loc, loc))
+ {
+ var = unshare_variable (set, var);
+ break;
+ }
+ }
+ }
+
+ /* Delete the location part. */
+ nextp = &var->var_part[pos].loc_chain;
+ for (node = *nextp; node; node = next)
+ {
+ next = node->next;
+ if ((REG_P (node->loc) && REG_P (loc)
+ && REGNO (node->loc) == REGNO (loc))
+ || rtx_equal_p (node->loc, loc))
+ {
+ pool_free (loc_chain_pool, node);
+ *nextp = next;
+ break;
+ }
+ else
+ nextp = &node->next;
+ }
+
+ /* If we have deleted the location which was last emitted
+ we have to emit new location so add the variable to set
+ of changed variables. */
+ if (var->var_part[pos].cur_loc
+ && ((REG_P (loc)
+ && REG_P (var->var_part[pos].cur_loc)
+ && REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
+ || rtx_equal_p (loc, var->var_part[pos].cur_loc)))
+ {
+ changed = true;
+ if (var->var_part[pos].loc_chain)
+ var->var_part[pos].cur_loc = var->var_part[pos].loc_chain->loc;
+ }
+ else
+ changed = false;
+
+ if (var->var_part[pos].loc_chain == NULL)
+ {
+ var->n_var_parts--;
+ while (pos < var->n_var_parts)
+ {
+ var->var_part[pos] = var->var_part[pos + 1];
+ pos++;
+ }
+ }
+ if (changed)
+ variable_was_changed (var, set->vars);
+ }
+ }
+}
+
+/* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP. DATA contains
+ additional parameters: WHERE specifies whether the note shall be emitted
+ before of after instruction INSN. */
+
+static int
+emit_note_insn_var_location (void **varp, void *data)
+{
+ variable var = *(variable *) varp;
+ rtx insn = ((emit_note_data *)data)->insn;
+ enum emit_note_where where = ((emit_note_data *)data)->where;
+ rtx note;
+ int i;
+ bool complete;
+ HOST_WIDE_INT last_limit;
+ tree type_size_unit;
+
+#ifdef ENABLE_CHECKING
+ if (!var->decl)
+ abort ();
+#endif
+
+ complete = true;
+ last_limit = 0;
+ for (i = 0; i < var->n_var_parts; i++)
+ {
+ if (last_limit < var->var_part[i].offset)
+ {
+ complete = false;
+ break;
+ }
+ last_limit
+ = (var->var_part[i].offset
+ + GET_MODE_SIZE (GET_MODE (var->var_part[i].loc_chain->loc)));
+ }
+ type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (var->decl));
+ if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
+ complete = false;
+
+ if (where == EMIT_NOTE_AFTER_INSN)
+ note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
+ else
+ note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
+
+ if (!complete)
+ {
+ NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
+ NULL_RTX);
+ }
+ else if (var->n_var_parts == 1)
+ {
+ rtx expr_list
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ var->var_part[0].loc_chain->loc,
+ GEN_INT (var->var_part[0].offset));
+
+ NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
+ expr_list);
+ }
+ else if (var->n_var_parts)
+ {
+ rtx argp[MAX_VAR_PARTS];
+ rtx parallel;
+
+ for (i = 0; i < var->n_var_parts; i++)
+ argp[i] = gen_rtx_EXPR_LIST (VOIDmode, var->var_part[i].loc_chain->loc,
+ GEN_INT (var->var_part[i].offset));
+ parallel = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec_v (var->n_var_parts, argp));
+ NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
+ parallel);
+ }
+
+ htab_clear_slot (changed_variables, varp);
+
+ /* When there are no location parts the variable has been already
+ removed from hash table and a new empty variable was created.
+ Free the empty variable. */
+ if (var->n_var_parts == 0)
+ {
+ pool_free (var_pool, var);
+ }
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
+ CHANGED_VARIABLES and delete this chain. WHERE specifies whether the notes
+ shall be emitted before of after instruction INSN. */
+
+static void
+emit_notes_for_changes (rtx insn, enum emit_note_where where)
+{
+ emit_note_data data;
+
+ data.insn = insn;
+ data.where = where;
+ htab_traverse (changed_variables, emit_note_insn_var_location, &data);
+}
+
+/* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
+ same variable in hash table DATA or is not there at all. */
+
+static int
+emit_notes_for_differences_1 (void **slot, void *data)
+{
+ htab_t new_vars = (htab_t) data;
+ variable old_var, new_var;
+
+ old_var = *(variable *) slot;
+ new_var = htab_find_with_hash (new_vars, old_var->decl,
+ VARIABLE_HASH_VAL (old_var->decl));
+
+ if (!new_var)
+ {
+ /* Variable has disappeared. */
+ variable empty_var;
+
+ empty_var = pool_alloc (var_pool);
+ empty_var->decl = old_var->decl;
+ empty_var->refcount = 1;
+ empty_var->n_var_parts = 0;
+ variable_was_changed (empty_var, NULL);
+ }
+ else if (variable_different_p (old_var, new_var, true))
+ {
+ variable_was_changed (new_var, NULL);
+ }
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
+ table DATA. */
+
+static int
+emit_notes_for_differences_2 (void **slot, void *data)
+{
+ htab_t old_vars = (htab_t) data;
+ variable old_var, new_var;
+
+ new_var = *(variable *) slot;
+ old_var = htab_find_with_hash (old_vars, new_var->decl,
+ VARIABLE_HASH_VAL (new_var->decl));
+ if (!old_var)
+ {
+ /* Variable has appeared. */
+ variable_was_changed (new_var, NULL);
+ }
+
+ /* Continue traversing the hash table. */
+ return 1;
+}
+
+/* Emit notes before INSN for differences between dataflow sets OLD_SET and
+ NEW_SET. */
+
+static void
+emit_notes_for_differences (rtx insn, dataflow_set *old_set,
+ dataflow_set *new_set)
+{
+ htab_traverse (old_set->vars, emit_notes_for_differences_1, new_set->vars);
+ htab_traverse (new_set->vars, emit_notes_for_differences_2, old_set->vars);
+ emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+}
+
+/* Emit the notes for changes of location parts in the basic block BB. */
+
+static void
+emit_notes_in_bb (basic_block bb)
+{
+ int i;
+ dataflow_set set;
+
+ dataflow_set_init (&set, htab_elements (VTI (bb)->in.vars) + 3);
+ dataflow_set_copy (&set, &VTI (bb)->in);
+
+ for (i = 0; i < VTI (bb)->n_mos; i++)
+ {
+ rtx insn = VTI (bb)->mos[i].insn;
+
+ switch (VTI (bb)->mos[i].type)
+ {
+ case MO_CALL:
+ {
+ int r;
+
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (TEST_HARD_REG_BIT (call_used_reg_set, r))
+ {
+ var_regno_delete (&set, r);
+ }
+ emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
+ }
+ break;
+
+ case MO_USE:
+ case MO_SET:
+ {
+ rtx loc = VTI (bb)->mos[i].u.loc;
+
+ if (REG_P (loc))
+ var_reg_delete_and_set (&set, loc);
+ else
+ var_mem_delete_and_set (&set, loc);
+
+ if (VTI (bb)->mos[i].type == MO_USE)
+ emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+ else
+ emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
+ }
+ break;
+
+ case MO_USE_NO_VAR:
+ case MO_CLOBBER:
+ {
+ rtx loc = VTI (bb)->mos[i].u.loc;
+
+ if (REG_P (loc))
+ var_reg_delete (&set, loc);
+ else
+ var_mem_delete (&set, loc);
+
+ if (VTI (bb)->mos[i].type == MO_USE_NO_VAR)
+ emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+ else
+ emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
+ }
+ break;
+
+ case MO_ADJUST:
+ {
+ rtx base;
+
+ set.stack_adjust += VTI (bb)->mos[i].u.adjust;
+ base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ set.stack_adjust));
+ set_frame_base_location (&set, base);
+ emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
+ }
+ break;
+ }
+ }
+ dataflow_set_destroy (&set);
+}
+
+/* Emit notes for the whole function. */
+
+static void
+vt_emit_notes (void)
+{
+ basic_block bb;
+ dataflow_set *last_out;
+ dataflow_set empty;
+
+#ifdef ENABLE_CHECKING
+ if (htab_elements (changed_variables))
+ abort ();
+#endif
+
+ /* Enable emitting notes by functions (mainly by set_variable_part and
+ delete_variable_part). */
+ emit_notes = true;
+
+ dataflow_set_init (&empty, 7);
+ last_out = &empty;
+
+ FOR_EACH_BB (bb)
+ {
+ /* Emit the notes for changes of variable locations between two
+ subsequent basic blocks. */
+ emit_notes_for_differences (BB_HEAD (bb), last_out, &VTI (bb)->in);
+
+ /* Emit the notes for the changes in the basic block itself. */
+ emit_notes_in_bb (bb);
+
+ last_out = &VTI (bb)->out;
+ }
+ dataflow_set_destroy (&empty);
+ emit_notes = false;
+}
+
+/* If there is a declaration and offset associated with register/memory RTL
+ assign declaration to *DECLP and offset to *OFFSETP, and return true. */
+
+static bool
+vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
+{
+ if (REG_P (rtl))
+ {
+ if (REG_ATTRS (rtl))
+ {
+ *declp = REG_EXPR (rtl);
+ *offsetp = REG_OFFSET (rtl);
+ return true;
+ }
+ }
+ else if (MEM_P (rtl))
+ {
+ if (MEM_ATTRS (rtl))
+ {
+ *declp = MEM_EXPR (rtl);
+ *offsetp = MEM_OFFSET (rtl) ? INTVAL (MEM_OFFSET (rtl)) : 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
+
+static void
+vt_add_function_parameters (void)
+{
+ tree parm;
+
+ for (parm = DECL_ARGUMENTS (current_function_decl);
+ parm; parm = TREE_CHAIN (parm))
+ {
+ rtx decl_rtl = DECL_RTL_IF_SET (parm);
+ rtx incoming = DECL_INCOMING_RTL (parm);
+ tree decl;
+ HOST_WIDE_INT offset;
+ dataflow_set *out;
+
+ if (TREE_CODE (parm) != PARM_DECL)
+ continue;
+
+ if (!DECL_NAME (parm))
+ continue;
+
+ if (!decl_rtl || !incoming)
+ continue;
+
+ if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
+ continue;
+
+ if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+ if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
+ continue;
+
+ if (!decl)
+ continue;
+
+#ifdef ENABLE_CHECKING
+ if (parm != decl)
+ abort ();
+#endif
+
+ incoming = eliminate_regs (incoming, 0, NULL_RTX);
+ out = &VTI (ENTRY_BLOCK_PTR)->out;
+
+ if (REG_P (incoming))
+ {
+#ifdef ENABLE_CHECKING
+ if (REGNO (incoming) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+#endif
+ attrs_list_insert (&out->regs[REGNO (incoming)],
+ parm, offset, incoming);
+ set_variable_part (out, incoming, parm, offset);
+ }
+ else if (MEM_P (incoming))
+ {
+ set_variable_part (out, incoming, parm, offset);
+ }
+ }
+}
+
+/* Allocate and initialize the data structures for variable tracking
+ and parse the RTL to get the micro operations. */
+
+static void
+vt_initialize (void)
+{
+ basic_block bb;
+
+ alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
+
+ FOR_EACH_BB (bb)
+ {
+ rtx insn;
+ HOST_WIDE_INT pre, post;
+
+ /* Count the number of micro operations. */
+ VTI (bb)->n_mos = 0;
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ {
+ if (!frame_pointer_needed)
+ {
+ insn_stack_adjust_offset_pre_post (insn, &pre, &post);
+ if (pre)
+ VTI (bb)->n_mos++;
+ if (post)
+ VTI (bb)->n_mos++;
+ }
+ note_uses (&PATTERN (insn), count_uses_1, insn);
+ note_stores (PATTERN (insn), count_stores, insn);
+ if (GET_CODE (insn) == CALL_INSN)
+ VTI (bb)->n_mos++;
+ }
+ }
+
+ /* Add the micro-operations to the array. */
+ VTI (bb)->mos = xmalloc (VTI (bb)->n_mos
+ * sizeof (struct micro_operation_def));
+ VTI (bb)->n_mos = 0;
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ {
+ int n1, n2;
+
+ if (!frame_pointer_needed)
+ {
+ insn_stack_adjust_offset_pre_post (insn, &pre, &post);
+ if (pre)
+ {
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = MO_ADJUST;
+ mo->u.adjust = pre;
+ mo->insn = insn;
+ }
+ }
+
+ n1 = VTI (bb)->n_mos;
+ note_uses (&PATTERN (insn), add_uses_1, insn);
+ n2 = VTI (bb)->n_mos - 1;
+
+ /* Order the MO_USEs to be before MO_USE_NO_VARs. */
+ while (n1 < n2)
+ {
+ while (n1 < n2 && VTI (bb)->mos[n1].type == MO_USE)
+ n1++;
+ while (n1 < n2 && VTI (bb)->mos[n2].type == MO_USE_NO_VAR)
+ n2--;
+ if (n1 < n2)
+ {
+ micro_operation sw;
+
+ sw = VTI (bb)->mos[n1];
+ VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
+ VTI (bb)->mos[n2] = sw;
+ }
+ }
+
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = MO_CALL;
+ mo->insn = insn;
+ }
+
+ n1 = VTI (bb)->n_mos;
+ note_stores (PATTERN (insn), add_stores, insn);
+ n2 = VTI (bb)->n_mos - 1;
+
+ /* Order the MO_SETs to be before MO_CLOBBERs. */
+ while (n1 < n2)
+ {
+ while (n1 < n2 && VTI (bb)->mos[n1].type == MO_SET)
+ n1++;
+ while (n1 < n2 && VTI (bb)->mos[n2].type == MO_CLOBBER)
+ n2--;
+ if (n1 < n2)
+ {
+ micro_operation sw;
+
+ sw = VTI (bb)->mos[n1];
+ VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
+ VTI (bb)->mos[n2] = sw;
+ }
+ }
+
+ if (!frame_pointer_needed && post)
+ {
+ micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+
+ mo->type = MO_ADJUST;
+ mo->u.adjust = post;
+ mo->insn = insn;
+ }
+ }
+ }
+ }
+
+ /* Init the IN and OUT sets. */
+ FOR_ALL_BB (bb)
+ {
+ VTI (bb)->visited = false;
+ dataflow_set_init (&VTI (bb)->in, 7);
+ dataflow_set_init (&VTI (bb)->out, 7);
+ }
+
+ attrs_pool = create_alloc_pool ("attrs_def pool",
+ sizeof (struct attrs_def), 1024);
+ var_pool = create_alloc_pool ("variable_def pool",
+ sizeof (struct variable_def), 64);
+ loc_chain_pool = create_alloc_pool ("location_chain_def pool",
+ sizeof (struct location_chain_def),
+ 1024);
+ changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
+ NULL);
+ vt_add_function_parameters ();
+
+ if (!frame_pointer_needed)
+ {
+ rtx base;
+
+ /* Create fake variable for tracking stack pointer changes. */
+ frame_base_decl = make_node (VAR_DECL);
+ DECL_NAME (frame_base_decl) = get_identifier ("___frame_base_decl");
+ TREE_TYPE (frame_base_decl) = char_type_node;
+ DECL_ARTIFICIAL (frame_base_decl) = 1;
+
+ /* Set its initial "location". */
+ frame_stack_adjust = -prologue_stack_adjust ();
+ base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ frame_stack_adjust));
+ set_variable_part (&VTI (ENTRY_BLOCK_PTR)->out, base, frame_base_decl, 0);
+ }
+ else
+ {
+ frame_base_decl = NULL;
+ }
+}
+
+/* Free the data structures needed for variable tracking. */
+
+static void
+vt_finalize (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ free (VTI (bb)->mos);
+ }
+
+ FOR_ALL_BB (bb)
+ {
+ dataflow_set_destroy (&VTI (bb)->in);
+ dataflow_set_destroy (&VTI (bb)->out);
+ }
+ free_aux_for_blocks ();
+ free_alloc_pool (attrs_pool);
+ free_alloc_pool (var_pool);
+ free_alloc_pool (loc_chain_pool);
+ htab_delete (changed_variables);
+}
+
+/* The entry point to variable tracking pass. */
+
+void
+variable_tracking_main (void)
+{
+ if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
+ return;
+
+ mark_dfs_back_edges ();
+ vt_initialize ();
+ if (!frame_pointer_needed)
+ {
+ if (!vt_stack_adjustments ())
+ {
+ vt_finalize ();
+ return;
+ }
+ }
+
+ vt_find_locations ();
+ vt_emit_notes ();
+
+ if (dump_file)
+ {
+ dump_dataflow_sets ();
+ dump_flow_info (dump_file);
+ }
+
+ vt_finalize ();
+}
diff --git a/gcc/vec.c b/gcc/vec.c
new file mode 100644
index 00000000000..01faf52bd78
--- /dev/null
+++ b/gcc/vec.c
@@ -0,0 +1,90 @@
+/* Vector API for GNU compiler.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Nathan Sidwell <nathan@codesourcery.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 "ggc.h"
+#include "vec.h"
+#include "errors.h"
+#include "coretypes.h"
+#include "tree.h"
+
+struct vec_prefix
+{
+ size_t num;
+ size_t alloc;
+ void *vec[1];
+};
+
+/* Ensure there are at least RESERVE free slots in VEC, if RESERVE !=
+ ~0u. If RESERVE == ~0u increase the current allocation
+ exponentially. VEC can be NULL, to create a new vector. */
+
+void *
+vec_p_reserve (void *vec, size_t reserve MEM_STAT_DECL)
+{
+ return vec_o_reserve (vec, reserve,
+ offsetof (struct vec_prefix, vec), sizeof (void *)
+ PASS_MEM_STAT);
+}
+
+/* Ensure there are at least RESERVE free slots in VEC, if RESERVE !=
+ ~0u. If RESERVE == ~0u, increase the current allocation
+ exponentially. VEC can be NULL, in which case a new vector is
+ created. The vector's trailing array is at VEC_OFFSET offset and
+ consistes of ELT_SIZE sized elements. */
+
+void *
+vec_o_reserve (void *vec, size_t reserve, size_t vec_offset, size_t elt_size
+ MEM_STAT_DECL)
+{
+ struct vec_prefix *pfx = vec;
+ size_t alloc;
+
+ if (reserve + 1)
+ alloc = (pfx ? pfx->num : 0) + reserve;
+ else
+ alloc = pfx ? pfx->alloc * 2 : 4;
+
+ if (!pfx || pfx->alloc < alloc)
+ {
+ vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size
+ PASS_MEM_STAT);
+ ((struct vec_prefix *)vec)->alloc = alloc;
+ if (!pfx)
+ ((struct vec_prefix *)vec)->num = 0;
+ }
+
+ return vec;
+}
+
+#if ENABLE_CHECKING
+/* Issue a vector domain error, and then fall over. */
+
+void
+vec_assert_fail (const char *op, const char *struct_name,
+ const char *file, size_t line, const char *function)
+{
+ internal_error ("vector %s %s domain error, in %s at %s:%u",
+ struct_name, op, function, function,
+ trim_filename (file), line);
+}
+#endif
diff --git a/gcc/vec.h b/gcc/vec.h
new file mode 100644
index 00000000000..be4aaad1977
--- /dev/null
+++ b/gcc/vec.h
@@ -0,0 +1,600 @@
+/* Vector API for GNU compiler.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Nathan Sidwell <nathan@codesourcery.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_VEC_H
+#define GCC_VEC_H
+
+/* The macros here implement a set of templated vector types and
+ associated interfaces. These templates are implemented with
+ macros, as we're not in C++ land. The interface functions are
+ typesafe and use static inline functions, sometimes backed by
+ out-of-line generic functions. The vectors are designed to
+ interoperate with the GTY machinery.
+
+ Because of the different behaviour of objects and of pointers to
+ objects, there are two flavours. One to deal with a vector of
+ pointers to objects, and one to deal with a vector of objects
+ themselves. Both of these pass pointers to objects around -- in
+ the former case the pointers are stored into the vector and in the
+ latter case the pointers are dereferenced and the objects copied
+ into the vector. Therefore, when using a vector of pointers, the
+ objects pointed to must be long lived, but when dealing with a
+ vector of objects, the source objects need not be.
+
+ The vectors are implemented using the trailing array idiom, thus
+ they are not resizeable without changing the address of the vector
+ object itself. This means you cannot have variables or fields of
+ vector type -- always use a pointer to a vector. The one exception
+ is the final field of a structure, which could be a vector type.
+ You will have to use the embedded_size & embedded_init calls to
+ create such objects, and they will probably not be resizeable (so
+ don't use the 'safe' allocation variants). The trailing array
+ idiom is used (rather than a pointer to an array of data), because,
+ if we allow NULL to also represent an empty vector, empty vectors
+ occupy minimal space in the structure containing them.
+
+ Each operation that increases the number of active elements is
+ available in 'quick' and 'safe' variants. The former presumes that
+ there is sufficient allocated space for the operation to succeed
+ (it aborts if there is not). The latter will reallocate the
+ vector, if needed. Reallocation causes an exponential increase in
+ vector size. If you know you will be adding N elements, it would
+ be more efficient to use the reserve operation before adding the
+ elements with the 'quick' operation.
+
+ You should prefer the push and pop operations, as they append and
+ remove from the end of the vector. If you need to remove several
+ items in one go, use the truncate operation. The insert and remove
+ operations allow you to change elements in the middle of the
+ vector. There are two remove operations, one which preserves the
+ element ordering 'ordered_remove', and one which does not
+ 'unordered_remove'. The latter function copies the end element
+ into the removed slot, rather than invoke a memmove operation.
+
+ Vector types are defined using a DEF_VEC_x(TYPEDEF) macro, and
+ variables of vector type are declared using a VEC(TYPEDEF)
+ macro. The 'x' letter indicates whether TYPEDEF is a pointer (P) or
+ object (O) type.
+
+ An example of their use would be,
+
+ DEF_VEC_P(tree); // define a vector of tree pointers. This must
+ // appear at file scope.
+
+ struct my_struct {
+ VEC(tree) *v; // A (pointer to) a vector of tree pointers.
+ };
+
+ struct my_struct *s;
+
+ if (VEC_length(tree,s->v)) { we have some contents }
+ VEC_safe_push(tree,s->v,decl); // append some decl onto the end
+ for (ix = 0; (t = VEC_iterate(tree,s->v,ix)); ix++)
+ { do something with t }
+
+*/
+
+/* Macros to invoke API calls. A single macro works for both pointer
+ and object vectors, but the argument and return types might well be
+ different. In each macro, TDEF is the typedef of the vector
+ elements. Some of these macros pass the vector, V, by reference
+ (by taking its address), this is noted in the descriptions. */
+
+/* Length of vector
+ size_t VEC_T_length(const VEC(T) *v);
+
+ Return the number of active elements in V. V can be NULL, in which
+ case zero is returned. */
+#define VEC_length(TDEF,V) (VEC_OP(TDEF,length)(V))
+
+/* Get the final element of the vector.
+ T VEC_T_last(VEC(T) *v); // Pointer
+ T *VEC_T_last(VEC(T) *v); // Object
+
+ Return the final element. If V is empty, abort. */
+#define VEC_last(TDEF,V) (VEC_OP(TDEF,last)(V))
+
+/* Index into vector
+ T VEC_T_index(VEC(T) *v, size_t ix); // Pointer
+ T *VEC_T_index(VEC(T) *v, size_t ix); // Object
+
+ Return the IX'th element. If IX is outside the domain of V,
+ abort. */
+#define VEC_index(TDEF,V,I) (VEC_OP(TDEF,index)(V,I))
+
+/* Iterate over vector
+ T VEC_T_index(VEC(T) *v, size_t ix); // Pointer
+ T *VEC_T_index(VEC(T) *v, size_t ix); // Object
+
+ Return the IX'th element or NULL. Use this to iterate over the
+ elements of a vector as follows,
+
+ for (ix = 0; (ptr = VEC_iterate(T,v,ix)); ix++)
+ continue; */
+#define VEC_iterate(TDEF,V,I) (VEC_OP(TDEF,iterate)(V,I))
+
+/* Allocate new vector.
+ VEC(T) *VEC_T_alloc(size_t reserve);
+
+ Allocate a new vector with space for RESERVE objects. */
+#define VEC_alloc(TDEF,A) (VEC_OP(TDEF,alloc)(A MEM_STAT_INFO))
+
+/* Use these to determine the required size and initialization of a
+ vector embedded within another structure (as the final member).
+
+ size_t VEC_T_embedded_size(size_t reserve);
+ void VEC_T_embedded_init(VEC(T) *v, size_t reserve);
+
+ These allow the caller to perform the memory allocation. */
+#define VEC_embedded_size(TDEF,A) (VEC_OP(TDEF,embedded_size)(A))
+#define VEC_embedded_init(TDEF,O,A) (VEC_OP(TDEF,embedded_init)(O,A))
+
+/* Reserve space.
+ void VEC_T_reserve(VEC(T) *&v, size_t reserve);
+
+ Ensure that V has at least RESERVE slots available. Note this can
+ cause V to be reallocated. */
+#define VEC_reserve(TDEF,V,R) (VEC_OP(TDEF,reserve)(&(V),R MEM_STAT_INFO))
+
+/* Push object with no reallocation
+ T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
+ T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
+
+ Push a new element onto the end, returns a pointer to the slot
+ filled in. For object vectors, the new value can be NULL, in which
+ case NO initialization is performed. Aborts if there is
+ insufficient space in the vector. */
+#define VEC_quick_push(TDEF,V,O) (VEC_OP(TDEF,quick_push)(V,O))
+
+/* Push object with reallocation
+ T *VEC_T_safe_push (VEC(T) *&v, T obj); // Pointer
+ T *VEC_T_safe_push (VEC(T) *&v, T *obj); // Object
+
+ Push a new element onto the end, returns a pointer to the slot
+ filled in. For object vectors, the new value can be NULL, in which
+ case NO initialization is performed. Reallocates V, if needed. */
+#define VEC_safe_push(TDEF,V,O) (VEC_OP(TDEF,safe_push)(&(V),O MEM_STAT_INFO))
+
+/* Pop element off end
+ T VEC_T_pop (VEC(T) *v); // Pointer
+ void VEC_T_pop (VEC(T) *v); // Object
+
+ Pop the last element off the end. Returns the element popped, for
+ pointer vectors. */
+#define VEC_pop(TDEF,V) (VEC_OP(TDEF,pop)(V))
+
+/* Truncate to specific length
+ void VEC_T_truncate (VEC(T) *v, size_t len);
+
+ Set the length as specified. This is an O(1) operation. */
+#define VEC_truncate(TDEF,V,I) (VEC_OP(TDEF,truncate)(V,I))
+
+/* Replace element
+ T VEC_T_replace (VEC(T) *v, size_t ix, T val); // Pointer
+ T *VEC_T_replace (VEC(T) *v, size_t ix, T *val); // Object
+
+ Replace the IXth element of V with a new value, VAL. For pointer
+ vectors returns the original value. For object vectors returns a
+ pointer to the new value. For object vectors the new value can be
+ NULL, in which case no overwriting of the slot is actually
+ performed. */
+#define VEC_replace(TDEF,V,I,O) (VEC_OP(TDEF,replace)(V,I,O))
+
+/* Insert object with no reallocation
+ T *VEC_T_quick_insert (VEC(T) *v, size_t ix, T val); // Pointer
+ T *VEC_T_quick_insert (VEC(T) *v, size_t ix, T *val); // Object
+
+ Insert an element, VAL, at the IXth position of V. Return a pointer
+ to the slot created. For vectors of object, the new value can be
+ NULL, in which case no initialization of the inserted slot takes
+ place. Aborts if there is insufficient space. */
+#define VEC_quick_insert(TDEF,V,I,O) (VEC_OP(TDEF,quick_insert)(V,I,O))
+
+/* Insert object with reallocation
+ T *VEC_T_safe_insert (VEC(T) *&v, size_t ix, T val); // Pointer
+ T *VEC_T_safe_insert (VEC(T) *&v, size_t ix, T *val); // Object
+
+ Insert an element, VAL, at the IXth position of V. Return a pointer
+ to the slot created. For vectors of object, the new value can be
+ NULL, in which case no initialization of the inserted slot takes
+ place. Reallocate V, if necessary. */
+#define VEC_safe_insert(TDEF,V,I,O) (VEC_OP(TDEF,safe_insert)(&(V),I,O MEM_STAT_INFO))
+
+/* Remove element retaining order
+ T VEC_T_ordered_remove (VEC(T) *v, size_t ix); // Pointer
+ void VEC_T_ordered_remove (VEC(T) *v, size_t ix); // Object
+
+ Remove an element from the IXth position of V. Ordering of
+ remaining elements is preserverd. For pointer vectors returns the
+ removed object. This is an O(N) operation due to a memmove. */
+#define VEC_ordered_remove(TDEF,V,I) (VEC_OP(TDEF,ordered_remove)(V,I))
+
+/* Remove element destroying order
+ T VEC_T_unordered_remove (VEC(T) *v, size_t ix); // Pointer
+ void VEC_T_unordered_remove (VEC(T) *v, size_t ix); // Object
+
+ Remove an element from the IXth position of V. Ordering of
+ remaining elements is destroyed. For pointer vectors returns the
+ removed object. This is an O(1) operation. */
+#define VEC_unordered_remove(TDEF,V,I) (VEC_OP(TDEF,unordered_remove)(V,I))
+
+#if !IN_GENGTYPE
+/* Reallocate an array of elements with prefix. */
+extern void *vec_p_reserve (void *, size_t MEM_STAT_DECL);
+extern void *vec_o_reserve (void *, size_t, size_t, size_t MEM_STAT_DECL);
+
+#if ENABLE_CHECKING
+extern void vec_assert_fail (const char *, const char *,
+ const char *, size_t, const char *)
+ ATTRIBUTE_NORETURN;
+#define VEC_ASSERT_FAIL(OP,VEC) \
+ vec_assert_fail (OP,#VEC,__FILE__,__LINE__,__FUNCTION__)
+
+#define VEC_ASSERT(EXPR,OP,TDEF) \
+ (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(TDEF)), 0))
+#else
+#define VEC_ASSERT(EXPR,OP,TYPE) (void)(EXPR)
+#endif
+
+#define VEC(TDEF) VEC_##TDEF
+#define VEC_OP(TDEF,OP) VEC_OP_(VEC(TDEF),OP)
+#define VEC_OP_(VEC,OP) VEC_OP__(VEC,OP)
+#define VEC_OP__(VEC,OP) VEC ## _ ## OP
+#else /* IN_GENGTYPE */
+#define VEC(TDEF) VEC_ TDEF
+#define VEC_STRINGIFY(X) VEC_STRINGIFY_(X)
+#define VEC_STRINGIFY_(X) #X
+#undef GTY
+#endif /* IN_GENGTYPE */
+
+#define VEC_TDEF(TDEF) \
+typedef struct VEC (TDEF) GTY(()) \
+{ \
+ size_t num; \
+ size_t alloc; \
+ TDEF GTY ((length ("%h.num"))) vec[1]; \
+} VEC (TDEF)
+
+/* Vector of pointer to object. */
+#if IN_GENGTYPE
+{"DEF_VEC_P", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
+#else
+
+#define DEF_VEC_P(TDEF) \
+VEC_TDEF (TDEF); \
+ \
+static inline size_t VEC_OP (TDEF,length) \
+ (const VEC (TDEF) *vec_) \
+{ \
+ return vec_ ? vec_->num : 0; \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,last) \
+ (const VEC (TDEF) *vec_) \
+{ \
+ VEC_ASSERT (vec_ && vec_->num, "last", TDEF); \
+ \
+ return vec_->vec[vec_->num - 1]; \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,index) \
+ (const VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ VEC_ASSERT (vec_ && ix_ < vec_->num, "index", TDEF); \
+ \
+ return vec_->vec[ix_]; \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,iterate) \
+ (const VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ return vec_ && ix_ < vec_->num ? vec_->vec[ix_] : NULL; \
+} \
+ \
+static inline VEC (TDEF) *VEC_OP (TDEF,alloc MEM_STAT_DECL) \
+ (size_t alloc_) \
+{ \
+ return vec_p_reserve (NULL, alloc_ - !alloc_ PASS_MEM_STAT); \
+} \
+ \
+static inline size_t VEC_OP (TDEF,embedded_size) \
+ (size_t alloc_) \
+{ \
+ return offsetof (VEC(TDEF),vec) + alloc_ * sizeof(TDEF); \
+} \
+ \
+static inline void VEC_OP (TDEF,embedded_init) \
+ (VEC (TDEF) *vec_, size_t alloc_) \
+{ \
+ vec_->num = 0; \
+ vec_->alloc = alloc_; \
+} \
+ \
+static inline void VEC_OP (TDEF,reserve) \
+ (VEC (TDEF) **vec_, size_t alloc_ MEM_STAT_DECL) \
+{ \
+ *vec_ = vec_p_reserve (*vec_, alloc_ PASS_MEM_STAT); \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,quick_push) \
+ (VEC (TDEF) *vec_, TDEF obj_) \
+{ \
+ TDEF *slot_; \
+ \
+ VEC_ASSERT (vec_->num < vec_->alloc, "push", TDEF); \
+ slot_ = &vec_->vec[vec_->num++]; \
+ *slot_ = obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,safe_push) \
+ (VEC (TDEF) **vec_, TDEF obj_ MEM_STAT_DECL) \
+{ \
+ if (!*vec_ || (*vec_)->num == (*vec_)->alloc) \
+ VEC_OP (TDEF,reserve) (vec_, ~(size_t)0 PASS_MEM_STAT); \
+ \
+ return VEC_OP (TDEF,quick_push) (*vec_, obj_); \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,pop) \
+ (VEC (TDEF) *vec_) \
+{ \
+ TDEF obj_; \
+ \
+ VEC_ASSERT (vec_->num, "pop", TDEF); \
+ obj_ = vec_->vec[--vec_->num]; \
+ \
+ return obj_; \
+} \
+ \
+static inline void VEC_OP (TDEF,truncate) \
+ (VEC (TDEF) *vec_, size_t size_) \
+{ \
+ VEC_ASSERT (vec_->num >= size_, "truncate", TDEF); \
+ vec_->num = size_; \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,replace) \
+ (VEC (TDEF) *vec_, size_t ix_, TDEF obj_) \
+{ \
+ TDEF old_obj_; \
+ \
+ VEC_ASSERT (ix_ < vec_->num, "replace", TDEF); \
+ old_obj_ = vec_->vec[ix_]; \
+ vec_->vec[ix_] = obj_; \
+ \
+ return old_obj_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,quick_insert) \
+ (VEC (TDEF) *vec_, size_t ix_, TDEF obj_) \
+{ \
+ TDEF *slot_; \
+ \
+ VEC_ASSERT (vec_->num < vec_->alloc, "insert", TDEF); \
+ VEC_ASSERT (ix_ <= vec_->num, "insert", TDEF); \
+ slot_ = &vec_->vec[ix_]; \
+ memmove (slot_ + 1, slot_, vec_->num++ - ix_); \
+ *slot_ = obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,safe_insert) \
+ (VEC (TDEF) **vec_, size_t ix_, TDEF obj_ MEM_STAT_DECL) \
+{ \
+ if (!*vec_ || (*vec_)->num == (*vec_)->alloc) \
+ VEC_OP (TDEF,reserve) (vec_, ~(size_t)0 PASS_MEM_STAT); \
+ \
+ return VEC_OP (TDEF,quick_insert) (*vec_, ix_, obj_); \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,ordered_remove) \
+ (VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ TDEF *slot_; \
+ TDEF obj_; \
+ \
+ VEC_ASSERT (ix_ < vec_->num, "remove", TDEF); \
+ slot_ = &vec_->vec[ix_]; \
+ obj_ = *slot_; \
+ memmove (slot_, slot_ + 1, --vec_->num - ix_); \
+ \
+ return obj_; \
+} \
+ \
+static inline TDEF VEC_OP (TDEF,unordered_remove) \
+ (VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ TDEF *slot_; \
+ TDEF obj_; \
+ \
+ VEC_ASSERT (ix_ < vec_->num, "remove", TDEF); \
+ slot_ = &vec_->vec[ix_]; \
+ obj_ = *slot_; \
+ *slot_ = vec_->vec[--vec_->num]; \
+ \
+ return obj_; \
+} \
+ \
+struct vec_swallow_trailing_semi
+#endif
+
+/* Vector of object. */
+#if IN_GENGTYPE
+{"DEF_VEC_O", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
+#else
+
+#define DEF_VEC_O(TDEF) \
+VEC_TDEF (TDEF); \
+ \
+static inline size_t VEC_OP (TDEF,length) \
+ (const VEC (TDEF) *vec_) \
+{ \
+ return vec_ ? vec_->num : 0; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,last) \
+ (VEC (TDEF) *vec_) \
+{ \
+ VEC_ASSERT (vec_ && vec_->num, "last", TDEF); \
+ \
+ return &vec_->vec[vec_->num - 1]; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,index) \
+ (VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ VEC_ASSERT (vec_ && ix_ < vec_->num, "index", TDEF); \
+ \
+ return &vec_->vec[ix_]; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,iterate) \
+ (VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ return vec_ && ix_ < vec_->num ? &vec_->vec[ix_] : NULL; \
+} \
+ \
+static inline VEC (TDEF) *VEC_OP (TDEF,alloc) \
+ (size_t alloc_ MEM_STAT_DECL) \
+{ \
+ return vec_o_reserve (NULL, alloc_ - !alloc_, \
+ offsetof (VEC(TDEF),vec), sizeof (TDEF) \
+ PASS_MEM_STAT); \
+} \
+ \
+static inline size_t VEC_OP (TDEF,embedded_size) \
+ (size_t alloc_) \
+{ \
+ return offsetof (VEC(TDEF),vec) + alloc_ * sizeof(TDEF); \
+} \
+ \
+static inline void VEC_OP (TDEF,embedded_init) \
+ (VEC (TDEF) *vec_, size_t alloc_) \
+{ \
+ vec_->num = 0; \
+ vec_->alloc = alloc_; \
+} \
+ \
+static inline void VEC_OP (TDEF,reserve) \
+ (VEC (TDEF) **vec_, size_t alloc_ MEM_STAT_DECL) \
+{ \
+ *vec_ = vec_o_reserve (*vec_, alloc_, \
+ offsetof (VEC(TDEF),vec), sizeof (TDEF) \
+ PASS_MEM_STAT); \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,quick_push) \
+ (VEC (TDEF) *vec_, const TDEF *obj_) \
+{ \
+ TDEF *slot_; \
+ \
+ VEC_ASSERT (vec_->num < vec_->alloc, "push", TDEF); \
+ slot_ = &vec_->vec[vec_->num++]; \
+ if (obj_) \
+ *slot_ = *obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,safe_push) \
+ (VEC (TDEF) **vec_, const TDEF *obj_ MEM_STAT_DECL) \
+{ \
+ if (!*vec_ || (*vec_)->num == (*vec_)->alloc) \
+ VEC_OP (TDEF,reserve) (vec_, ~(size_t)0 PASS_MEM_STAT); \
+ \
+ return VEC_OP (TDEF,quick_push) (*vec_, obj_); \
+} \
+ \
+static inline void VEC_OP (TDEF,pop) \
+ (VEC (TDEF) *vec_) \
+{ \
+ VEC_ASSERT (vec_->num, "pop", TDEF); \
+ --vec_->num; \
+} \
+ \
+static inline void VEC_OP (TDEF,truncate) \
+ (VEC (TDEF) *vec_, size_t size_) \
+{ \
+ VEC_ASSERT (vec_->num >= size_, "truncate", TDEF); \
+ vec_->num = size_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,replace) \
+ (VEC (TDEF) *vec_, size_t ix_, const TDEF *obj_) \
+{ \
+ TDEF *slot_; \
+ \
+ VEC_ASSERT (ix_ < vec_->num, "replace", TDEF); \
+ slot_ = &vec_->vec[ix_]; \
+ if (obj_) \
+ *slot_ = *obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,quick_insert) \
+ (VEC (TDEF) *vec_, size_t ix_, const TDEF *obj_) \
+{ \
+ TDEF *slot_; \
+ \
+ VEC_ASSERT (vec_->num < vec_->alloc, "insert", TDEF); \
+ VEC_ASSERT (ix_ <= vec_->num, "insert", TDEF); \
+ slot_ = &vec_->vec[ix_]; \
+ memmove (slot_ + 1, slot_, vec_->num++ - ix_); \
+ if (obj_) \
+ *slot_ = *obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline TDEF *VEC_OP (TDEF,safe_insert) \
+ (VEC (TDEF) **vec_, size_t ix_, const TDEF *obj_ MEM_STAT_DECL) \
+{ \
+ if (!*vec_ || (*vec_)->num == (*vec_)->alloc) \
+ VEC_OP (TDEF,reserve) (vec_, ~(size_t)0 PASS_MEM_STAT); \
+ \
+ return VEC_OP (TDEF,quick_insert) (*vec_, ix_, obj_); \
+} \
+ \
+static inline void VEC_OP (TDEF,ordered_remove) \
+ (VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ TDEF *slot_; \
+ \
+ VEC_ASSERT (ix_ < vec_->num, "remove", TDEF); \
+ slot_ = &vec_->vec[ix_]; \
+ memmove (slot_, slot_ + 1, --vec_->num - ix_); \
+} \
+ \
+static inline void VEC_OP (TDEF,unordered_remove) \
+ (VEC (TDEF) *vec_, size_t ix_) \
+{ \
+ VEC_ASSERT (ix_ < vec_->num, "remove", TDEF); \
+ vec_->vec[ix_] = vec_->vec[--vec_->num]; \
+} \
+ \
+struct vec_swallow_trailing_semi
+#endif
+
+#endif /* GCC_VEC_H */
diff --git a/gcc/xcoff.h b/gcc/xcoff.h
new file mode 100644
index 00000000000..2d003fed3bb
--- /dev/null
+++ b/gcc/xcoff.h
@@ -0,0 +1,17 @@
+/* Storage classes in XCOFF object file format designed for DBX's use.
+ This info is from the `Files Reference' manual for IBM's AIX version 3
+ for the RS6000. */
+
+#define C_GSYM 0x80
+#define C_LSYM 0x81
+#define C_PSYM 0x82
+#define C_RSYM 0x83
+#define C_RPSYM 0x84
+#define C_STSYM 0x85
+
+#define C_BCOMM 0x87
+#define C_ECOML 0x88
+#define C_ECOMM 0x89
+#define C_DECL 0x8c
+#define C_ENTRY 0x8d
+#define C_FUN 0x8e
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index a7fe99ad1cc..d4c19813d11 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,14 +1,3 @@
-2003-10-26 Mark Wielaard <mark@klomp.org>
-
- Reported by Helmer Kraemer <hkraemer@freenet.de>
- * java/util/jar/JarInputStream.java (readManifest): Don't call
- closeEntry().
-
- * java/util/zip/DeflaterOutputStream.java (inbufWrite): New method.
- (finish): Use inbufWrite().
- (write(int)): Likewise.
- (write(byte[],int,int)): Likewise.
-
2003-10-26 Bryce McKinlay <bryce@mckinlay.net.nz>
* java/lang/reflect/AccessibleObject.java (secureSetAccessible):
diff --git a/libjava/java/util/jar/JarInputStream.java b/libjava/java/util/jar/JarInputStream.java
index daf935fa70a..9c295f372e6 100644
--- a/libjava/java/util/jar/JarInputStream.java
+++ b/libjava/java/util/jar/JarInputStream.java
@@ -116,6 +116,7 @@ public class JarInputStream extends ZipInputStream
}
firstEntry = (JarEntry) super.getNextEntry();
}
+ closeEntry();
if (verify)
{
diff --git a/libjava/java/util/zip/DeflaterOutputStream.java b/libjava/java/util/zip/DeflaterOutputStream.java
index 6a4fa95886b..ff66b080f9e 100644
--- a/libjava/java/util/zip/DeflaterOutputStream.java
+++ b/libjava/java/util/zip/DeflaterOutputStream.java
@@ -127,7 +127,12 @@ public class DeflaterOutputStream extends FilterOutputStream
*/
public void finish () throws IOException
{
- inbufWrite();
+ if (inbufLength > 0)
+ {
+ def.setInput (inbuf, 0, inbufLength);
+ deflate ();
+ inbufLength = 0;
+ }
def.finish();
while (! def.finished ())
{
@@ -140,27 +145,28 @@ public class DeflaterOutputStream extends FilterOutputStream
public void write (int bval) throws IOException
{
if (inbuf == null)
- inbuf = new byte[128];
+ {
+ inbuf = new byte[128];
+ }
else if (inbufLength == inbuf.length)
- inbufWrite ();
+ {
+ def.setInput (inbuf, 0, inbufLength);
+ deflate ();
+ inbufLength = 0;
+ }
inbuf[inbufLength++] = (byte) bval;
}
public void write (byte[] buf, int off, int len) throws IOException
{
- inbufWrite ();
- def.setInput (buf, off, len);
- deflate ();
- }
-
- private void inbufWrite () throws IOException
- {
if (inbufLength > 0)
{
- int size = inbufLength;
+ def.setInput (inbuf, 0, inbufLength);
+ deflate ();
inbufLength = 0;
- write (inbuf, 0, size);
}
+ def.setInput (buf, off, len);
+ deflate ();
}
// Used, if needed, for write(int).